From 4c40c764c37374084fedfad6db2845d9c463e7cf Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Mon, 18 Sep 2017 13:09:29 +0100 Subject: [PATCH 001/230] Cleaned up NodeInfo API (#1535) --- .../corda/client/jfx/NodeMonitorModelTest.kt | 7 ++--- .../corda/client/rpc/CordaRPCClientTest.kt | 6 ++-- .../core/flows/BroadcastTransactionFlow.kt | 2 +- .../corda/core/flows/SwapIdentitiesFlow.kt | 4 +-- .../kotlin/net/corda/core/node/NodeInfo.kt | 22 +++++++------- .../net/corda/core/flows/FlowsInJavaTest.java | 6 ++-- .../kotlin/net/corda/docs/CustomVaultQuery.kt | 3 +- .../corda/docs/FxTransactionBuildTutorial.kt | 14 ++++----- .../docs/WorkflowTransactionBuildTutorial.kt | 6 ++-- .../node/services/BFTNotaryServiceTests.kt | 2 +- .../net/corda/node/internal/AbstractNode.kt | 2 +- .../network/PersistentNetworkMapCache.kt | 2 +- .../services/events/ScheduledFlowTests.kt | 6 ++-- .../network/PersistentNetworkMapCacheTest.kt | 29 +++++++++---------- .../net/corda/explorer/views/Network.kt | 18 ++++++++---- 15 files changed, 65 insertions(+), 64 deletions(-) diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt index 1b5c44f241..99554d5e1f 100644 --- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt +++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt @@ -132,9 +132,8 @@ class NodeMonitorModelTest : DriverBasedTest() { @Test fun `cash issue and move`() { - val anonymous = false val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow() - val (_, paymentIdentity) = rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow() + rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow() var issueSmId: StateMachineRunId? = null var moveSmId: StateMachineRunId? = null @@ -152,7 +151,7 @@ class NodeMonitorModelTest : DriverBasedTest() { require(remove.id == issueSmId) }, // MOVE - N.B. There are other framework flows that happen in parallel for the remote resolve transactions flow - expect(match = { it is StateMachineUpdate.Added && it.stateMachineInfo.flowLogicClassName == CashPaymentFlow::class.java.name }) { add: StateMachineUpdate.Added -> + expect(match = { it.stateMachineInfo.flowLogicClassName == CashPaymentFlow::class.java.name }) { add: StateMachineUpdate.Added -> moveSmId = add.id val initiator = add.stateMachineInfo.initiator require(initiator is FlowInitiator.RPC && initiator.username == "user1") @@ -167,7 +166,7 @@ class NodeMonitorModelTest : DriverBasedTest() { // MOVE expect { add: StateMachineUpdate.Added -> val initiator = add.stateMachineInfo.initiator - require(initiator is FlowInitiator.Peer && initiator.party.name == aliceNode.chooseIdentity().name) + require(initiator is FlowInitiator.Peer && aliceNode.isLegalIdentity(initiator.party)) } ) } diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt index 71dccec05f..b73622da24 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt @@ -2,7 +2,10 @@ package net.corda.client.rpc import net.corda.core.crypto.random63BitValue import net.corda.core.flows.FlowInitiator -import net.corda.core.messaging.* +import net.corda.core.messaging.FlowProgressHandle +import net.corda.core.messaging.StateMachineUpdate +import net.corda.core.messaging.startFlow +import net.corda.core.messaging.startTrackedFlow import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow @@ -105,7 +108,6 @@ class CordaRPCClientTest : NodeBasedTest() { login(rpcUser.username, rpcUser.password) connection!!.proxy.startFlow(::CashPaymentFlow, 100.DOLLARS, node.info.chooseIdentity()).use { assertFalse(it is FlowProgressHandle<*>) - assertTrue(it is FlowHandle<*>) } } diff --git a/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt index 33a57c47da..4aada740a4 100644 --- a/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt @@ -20,7 +20,7 @@ class BroadcastTransactionFlow(val notarisedTransaction: SignedTransaction, @Suspendable override fun call() { // TODO: Messaging layer should handle this broadcast for us - participants.filter { it !in serviceHub.myInfo.legalIdentities }.forEach { participant -> + participants.filter { !serviceHub.myInfo.isLegalIdentity(it) }.forEach { participant -> // SendTransactionFlow allows otherParty to access our data to resolve the transaction. subFlow(SendTransactionFlow(participant, notarisedTransaction)) } diff --git a/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt b/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt index c56f52dea2..83e20cd5ae 100644 --- a/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt @@ -2,8 +2,8 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.identity.AnonymousParty -import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.services.IdentityService import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.unwrap @@ -40,7 +40,7 @@ class SwapIdentitiesFlow(val otherSide: Party, // Special case that if we're both parties, a single identity is generated val identities = LinkedHashMap() - if (otherSide in serviceHub.myInfo.legalIdentities) { + if (serviceHub.myInfo.isLegalIdentity(otherSide)) { identities.put(otherSide, legalIdentityAnonymous.party.anonymise()) } else { val anonymousOtherSide = sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> diff --git a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt index de905a6796..2c2f1db71f 100644 --- a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt @@ -18,10 +18,9 @@ data class ServiceEntry(val info: ServiceInfo, val identity: PartyAndCertificate * Info about a network node that acts on behalf of some form of contract party. */ // TODO We currently don't support multi-IP/multi-identity nodes, we only left slots in the data structures. -// Note that order of `legalIdentitiesAndCerts` is now important. We still treat the first identity as a special one. -// It will change after introducing proper multi-identity management. @CordaSerializable data class NodeInfo(val addresses: List, + /** Non-empty list of all the identities, plus certificates, that belong to this node. */ val legalIdentitiesAndCerts: List, val platformVersion: Int, val advertisedServices: List = emptyList(), @@ -33,17 +32,16 @@ data class NodeInfo(val addresses: List, // TODO This part will be removed with services removal. val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity.party + + @Transient private var _legalIdentities: List? = null + val legalIdentities: List get() { + return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } + } + + /** Returns true iff [party] is one of the identities of this node. */ + fun isLegalIdentity(party: Party): Boolean = party in legalIdentities + fun serviceIdentities(type: ServiceType): List { return advertisedServices.mapNotNull { if (it.info.type.isSubTypeOf(type)) it.identity.party else null } } - - /** - * Uses node's owner X500 name to infer the node's location. Used in Explorer in map view. - */ - fun getWorldMapLocation(): WorldMapLocation? { - val nodeOwnerLocation = legalIdentitiesAndCerts.first().name.locality - return nodeOwnerLocation.let { CityDatabase[it] } - } - val legalIdentities: List - get() = legalIdentitiesAndCerts.map { it.party } } diff --git a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java index aabaea10fa..406cbc30ec 100644 --- a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java +++ b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable; import com.google.common.primitives.Primitives; import net.corda.core.identity.Party; import net.corda.node.internal.StartedNode; -import net.corda.testing.CoreTestUtils; import net.corda.testing.node.MockNetwork; import org.junit.After; import org.junit.Before; @@ -13,6 +12,7 @@ import org.junit.Test; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; +import static net.corda.testing.CoreTestUtils.chooseIdentity; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import static org.junit.Assert.fail; @@ -40,7 +40,7 @@ public class FlowsInJavaTest { @Test public void suspendableActionInsideUnwrap() throws Exception { node2.getInternals().registerInitiatedFlow(SendHelloAndThenReceive.class); - Future result = node1.getServices().startFlow(new SendInUnwrapFlow(CoreTestUtils.chooseIdentity(node2.getInfo()))).getResultFuture(); + Future result = node1.getServices().startFlow(new SendInUnwrapFlow(chooseIdentity(node2.getInfo()))).getResultFuture(); mockNet.runNetwork(); assertThat(result.get()).isEqualTo("Hello"); } @@ -55,7 +55,7 @@ public class FlowsInJavaTest { } private void primitiveReceiveTypeTest(Class receiveType) throws InterruptedException { - PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(CoreTestUtils.chooseIdentity(node2.getInfo()), receiveType); + PrimitiveReceiveFlow flow = new PrimitiveReceiveFlow(chooseIdentity(node2.getInfo()), receiveType); Future result = node1.getServices().startFlow(flow).getResultFuture(); mockNet.runNetwork(); try { diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt index 10a8e7108a..9f886590ff 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt @@ -20,7 +20,6 @@ import net.corda.finance.flows.AbstractCashFlow import net.corda.finance.flows.CashException import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow -import net.corda.testing.chooseIdentity import java.util.* // DOCSTART CustomVaultQuery @@ -140,7 +139,7 @@ object TopupIssuerFlow { val issueTx = subFlow(issueCashFlow) // NOTE: issueCashFlow performs a Broadcast (which stores a local copy of the txn to the ledger) // short-circuit when issuing to self - if (issueTo == serviceHub.myInfo.chooseIdentity()) + if (serviceHub.myInfo.isLegalIdentity(issueTo)) return issueTx // now invoke Cash subflow to Move issued assetType to issue requester progressTracker.currentStep = TRANSFERRING diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt index 11f187482b..08e6defaf9 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt @@ -47,7 +47,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub, val fullCriteria = fungibleCriteria.and(vaultCriteria).and(cashCriteria) - val eligibleStates = serviceHub.vaultService.tryLockFungibleStatesForSpending(lockId, fullCriteria, amountRequired.withoutIssuer(), Cash.State::class.java) + val eligibleStates = serviceHub.vaultService.tryLockFungibleStatesForSpending(lockId, fullCriteria, amountRequired.withoutIssuer(), Cash.State::class.java) check(eligibleStates.isNotEmpty()) { "Insufficient funds" } val amount = eligibleStates.fold(0L) { tot, x -> tot + x.state.data.amount.quantity } @@ -97,11 +97,11 @@ class ForeignExchangeFlow(val tradeId: String, // Select correct sides of the Fx exchange to query for. // Specifically we own the assets we wish to sell. // Also prepare the other side query - val (localRequest, remoteRequest) = if (baseCurrencySeller == serviceHub.myInfo.chooseIdentity()) { + val (localRequest, remoteRequest) = if (serviceHub.myInfo.isLegalIdentity(baseCurrencySeller)) { val local = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer) val remote = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller) Pair(local, remote) - } else if (baseCurrencyBuyer == serviceHub.myInfo.chooseIdentity()) { + } else if (serviceHub.myInfo.isLegalIdentity(baseCurrencyBuyer)) { val local = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller) val remote = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer) Pair(local, remote) @@ -133,8 +133,8 @@ class ForeignExchangeFlow(val tradeId: String, >= remoteRequestWithNotary.amount.quantity) { "the provided inputs don't provide sufficient funds" } - require(it.filter { it.owner == serviceHub.myInfo.chooseIdentity() }. - map { it.amount.quantity }.sum() == remoteRequestWithNotary.amount.quantity) { + val sum = it.filter { it.owner.let { it is Party && serviceHub.myInfo.isLegalIdentity(it) } }.map { it.amount.quantity }.sum() + require(sum == remoteRequestWithNotary.amount.quantity) { "the provided outputs don't provide the request quantity" } it // return validated response @@ -195,7 +195,7 @@ class ForeignExchangeFlow(val tradeId: String, } @InitiatedBy(ForeignExchangeFlow::class) -class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic() { +class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic() { @Suspendable override fun call() { // Initial receive from remote party @@ -206,7 +206,7 @@ class ForeignExchangeRemoteFlow(val source: Party) : FlowLogic() { // the lifecycle of the Fx trades which would be included in the transaction // Check request is for us - require(serviceHub.myInfo.chooseIdentity() == it.owner) { + require(serviceHub.myInfo.isLegalIdentity(it.owner)) { "Request does not include the correct counterparty" } require(source == it.counterparty) { diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index 61a7d94dca..1eaee1a9da 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -116,7 +116,7 @@ class SubmitTradeApprovalFlow(val tradeId: String, // Notarise and distribute. subFlow(FinalityFlow(signedTx, setOf(serviceHub.myInfo.chooseIdentity(), counterparty))) // Return the initial state - return signedTx.tx.outRef(0) + return signedTx.tx.outRef(0) } } @@ -149,7 +149,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow "Input trade not modifiable ${latestRecord.state.data.state}" } // Check we are the correct Party to run the protocol. Note they will counter check this too. - require(latestRecord.state.data.counterparty == serviceHub.myInfo.chooseIdentity()) { + require(serviceHub.myInfo.isLegalIdentity(latestRecord.state.data.counterparty)) { "The counterparty must give the verdict" } @@ -225,7 +225,7 @@ class RecordCompletionFlow(val source: Party) : FlowLogic() { // Check the context dependent parts of the transaction as the // Contract verify method must not use serviceHub queries. val state = ltx.outRef(0) - require(state.state.data.source == serviceHub.myInfo.chooseIdentity()) { + require(serviceHub.myInfo.isLegalIdentity(state.state.data.source)) { "Proposal not one of our original proposals" } require(state.state.data.counterparty == source) { diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index 60facf156f..b391f34c7b 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -99,7 +99,7 @@ class BFTNotaryServiceTests { val notary = bftNotaryCluster(clusterSize) node.run { val issueTx = signInitialTransaction(notary) { - addOutputState(DummyContract.SingleOwnerState(owner = (info.chooseIdentity())), DUMMY_PROGRAM_ID) + addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID) } database.transaction { services.recordTransactions(issueTx) diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 73cc864bf7..cf949b89e0 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -579,7 +579,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val caCertificates: Array = listOf(legalIdentity.certificate, clientCa?.certificate?.cert) .filterNotNull() .toTypedArray() - val service = PersistentIdentityService(info.legalIdentitiesAndCerts.toSet(), trustRoot = trustRoot, caCertificates = *caCertificates) + val service = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates) services.networkMapCache.partyNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } } services.networkMapCache.changed.subscribe { mapChange -> // TODO how should we handle network map removal diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index 4c2cf09a6e..ef49d2e80c 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -76,7 +76,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) override fun getPartyInfo(party: Party): PartyInfo? { val nodes = serviceHub.database.transaction { queryByIdentityKey(party.owningKey) } - if (nodes.size == 1 && party in nodes[0].legalIdentities) { + if (nodes.size == 1 && nodes[0].isLegalIdentity(party)) { return PartyInfo.SingleNode(party, nodes[0].addresses) } for (node in nodes) { diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index dd172e462a..02a2550b86 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -21,8 +21,8 @@ import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.chooseIdentity +import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.dummyCommand import net.corda.testing.node.MockNetwork import org.junit.After @@ -81,7 +81,7 @@ class ScheduledFlowTests { val state = serviceHub.toStateAndRef(stateRef) val scheduledState = state.state.data // Only run flow over states originating on this node - if (scheduledState.source != serviceHub.myInfo.chooseIdentity()) { + if (!serviceHub.myInfo.isLegalIdentity(scheduledState.source)) { return } require(!scheduledState.processed) { "State should not have been previously processed" } @@ -144,7 +144,7 @@ class ScheduledFlowTests { fun `run a whole batch of scheduled flows`() { val N = 100 val futures = mutableListOf>() - for (i in 0..N - 1) { + for (i in 0 until N) { futures.add(nodeA.services.startFlow(InsertInitialStateFlow(nodeB.info.chooseIdentity())).resultFuture) futures.add(nodeB.services.startFlow(InsertInitialStateFlow(nodeA.info.chooseIdentity())).resultFuture) } diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt index 50e75b8207..5f156ce601 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt @@ -10,17 +10,14 @@ import net.corda.core.node.NodeInfo import net.corda.core.utilities.* import net.corda.node.internal.Node import net.corda.node.internal.StartedNode -import net.corda.testing.ALICE -import net.corda.testing.BOB -import net.corda.testing.CHARLIE -import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.chooseIdentity +import net.corda.testing.* import net.corda.testing.node.NodeBasedTest import org.assertj.core.api.Assertions.assertThat import org.junit.Before import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertFails +import kotlin.test.assertTrue class PersistentNetworkMapCacheTest : NodeBasedTest() { val partiesList = listOf(DUMMY_NOTARY, ALICE, BOB) @@ -64,7 +61,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { fun `restart node with DB map cache and no network map`() { val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0] val partyNodes = alice.services.networkMapCache.partyNodes - assert(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type }) + assertTrue(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type }) assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService) assertEquals(infos.size, partyNodes.size) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) @@ -74,8 +71,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { fun `start 2 nodes without pointing at NetworkMapService and communicate with each other`() { val parties = partiesList.subList(1, partiesList.size) val nodes = startNodesWithPort(parties, noNetworkMap = true) - assert(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) - assert(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) + assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) + assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) nodes.forEach { val partyNodes = it.services.networkMapCache.partyNodes assertEquals(infos.size, partyNodes.size) @@ -88,8 +85,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { fun `start 2 nodes pointing at NetworkMapService but don't start network map node`() { val parties = partiesList.subList(1, partiesList.size) val nodes = startNodesWithPort(parties, noNetworkMap = false) - assert(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) - assert(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) + assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) + assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) nodes.forEach { val partyNodes = it.services.networkMapCache.partyNodes assertEquals(infos.size, partyNodes.size) @@ -116,20 +113,20 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { // Start 2 nodes pointing at network map, but don't start network map service. val otherNodes = startNodesWithPort(parties, noNetworkMap = false) otherNodes.forEach { node -> - assert(infos.any { it.legalIdentitiesAndCerts.toSet() == node.info.legalIdentitiesAndCerts.toSet() }) + assertTrue(infos.any { it.legalIdentitiesAndCerts.toSet() == node.info.legalIdentitiesAndCerts.toSet() }) } // Start node that is not in databases of other nodes. Point to NMS. Which has't started yet. val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0] otherNodes.forEach { - assert(charlie.info.chooseIdentity() !in it.services.networkMapCache.partyNodes.flatMap { it.legalIdentities }) + assertThat(it.services.networkMapCache.partyNodes).doesNotContain(charlie.info) } // Start Network Map and see that charlie node appears in caches. val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0] nms.internals.startupComplete.get() - assert(nms.inNodeNetworkMapService != NullNetworkMapService) - assert(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() }) + assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService) + assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() }) otherNodes.forEach { - assert(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() }) + assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() }) } charlie.internals.nodeReadyFuture.get() // Finish registration. checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS. @@ -137,7 +134,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { val cacheB = otherNodes[1].services.networkMapCache.partyNodes val cacheC = charlie.services.networkMapCache.partyNodes assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap - assert(charlie.info.chooseIdentity() in cacheB.map { it.chooseIdentity() }) // Other nodes also fetched data from Network Map with node C. + assertThat(cacheB).contains(charlie.info) assertEquals(cacheA.toSet(), cacheB.toSet()) assertEquals(cacheA.toSet(), cacheC.toSet()) } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index 110b3ad739..cada329cc1 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -28,8 +28,10 @@ import net.corda.client.jfx.model.* import net.corda.client.jfx.utils.* import net.corda.core.contracts.ContractState import net.corda.core.identity.Party +import net.corda.core.node.CityDatabase import net.corda.core.node.NodeInfo import net.corda.core.node.ScreenCoordinate +import net.corda.core.node.WorldMapLocation import net.corda.core.utilities.toBase58String import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CordaView @@ -39,10 +41,10 @@ class Network : CordaView() { override val root by fxml() override val icon = FontAwesomeIcon.GLOBE // Inject data. - val myIdentity by observableValue(NetworkIdentityModel::myIdentity) - val notaries by observableList(NetworkIdentityModel::notaries) - val peers by observableList(NetworkIdentityModel::parties) - val transactions by observableList(TransactionDataModel::partiallyResolvedTransactions) + private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) + private val notaries by observableList(NetworkIdentityModel::notaries) + private val peers by observableList(NetworkIdentityModel::parties) + private val transactions by observableList(TransactionDataModel::partiallyResolvedTransactions) var centralPeer: String? = null private var centralLabel: ObservableValue @@ -215,8 +217,8 @@ class Network : CordaView() { private fun List.getParties() = map { it.participants.map { it.owningKey.toKnownParty() } }.flatten() private fun fireBulletBetweenNodes(senderParty: Party, destParty: Party, startType: String, endType: String) { - val senderNode = allComponents.firstOrNull { senderParty in it.nodeInfo.legalIdentities } ?: return - val destNode = allComponents.firstOrNull { destParty in it.nodeInfo.legalIdentities } ?: return + val senderNode = allComponents.firstOrNull { it.nodeInfo.isLegalIdentity(senderParty) } ?: return + val destNode = allComponents.firstOrNull { it.nodeInfo.isLegalIdentity(destParty) } ?: return val sender = senderNode.label.boundsInParentProperty().map { Point2D(it.width / 2 + it.minX, it.height / 4 - 2.5 + it.minY) } val receiver = destNode.label.boundsInParentProperty().map { Point2D(it.width / 2 + it.minX, it.height / 4 - 2.5 + it.minY) } val bullet = Circle(3.0) @@ -254,4 +256,8 @@ class Network : CordaView() { mapPane.children.add(1, line) mapPane.children.add(bullet) } + + private fun NodeInfo.getWorldMapLocation(): WorldMapLocation? { + return CityDatabase[legalIdentitiesAndCerts[0].name.locality] + } } From 8f860688077d536a0700f4c127661f3788eb66ee Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Mon, 18 Sep 2017 14:19:20 +0100 Subject: [PATCH 002/230] Move SwapIdentitiesFlow to confidential-identities module (#1531) * Move SwapIdentitiesFlow to confidential-identities module * Clean up confidential-identities build.gradle * Change description to include Experimental * Move confidential-identities to a dependency of node rather than node-api --- build.gradle | 5 +- confidential-identities/build.gradle | 64 +++++++++++++++++++ .../corda/confidential}/SwapIdentitiesFlow.kt | 5 +- .../confidential/SwapIdentitiesHandler.kt | 27 ++++++++ .../confidential}/SwapIdentitiesFlowTests.kt | 2 +- finance/build.gradle | 1 + .../corda/finance/flows/CashPaymentFlow.kt | 2 +- .../corda/finance/flows/TwoPartyDealFlow.kt | 6 +- node/build.gradle | 1 + .../net/corda/node/internal/AbstractNode.kt | 3 +- .../corda/node/services/CoreFlowHandlers.kt | 27 ++------ settings.gradle | 3 +- 12 files changed, 117 insertions(+), 29 deletions(-) create mode 100644 confidential-identities/build.gradle rename {core/src/main/kotlin/net/corda/core/flows => confidential-identities/src/main/kotlin/net/corda/confidential}/SwapIdentitiesFlow.kt (94%) create mode 100644 confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt rename {core/src/test/kotlin/net/corda/core/flows => confidential-identities/src/test/kotlin/net/corda/confidential}/SwapIdentitiesFlowTests.kt (98%) diff --git a/build.gradle b/build.gradle index f16c378b85..ba1bf0abf7 100644 --- a/build.gradle +++ b/build.gradle @@ -184,6 +184,7 @@ dependencies { cordaRuntime project(':client:mock') cordaRuntime project(':client:rpc') cordaRuntime project(':core') + cordaRuntime project(':confidential-identities') cordaRuntime project(':finance') cordaRuntime project(':webserver') testCompile project(':test-utils') @@ -251,7 +252,7 @@ bintrayConfig { projectUrl = 'https://github.com/corda/corda' gpgSign = true gpgPassphrase = System.getenv('CORDA_BINTRAY_GPG_PASSPHRASE') - publications = ['corda-jfx', 'corda-mock', 'corda-rpc', 'corda-core', 'corda', 'corda-finance', 'corda-node', 'corda-node-api', 'corda-test-common', 'corda-test-utils', 'corda-jackson', 'corda-verifier', 'corda-webserver-impl', 'corda-webserver', 'corda-node-driver'] + publications = ['corda-jfx', 'corda-mock', 'corda-rpc', 'corda-core', 'corda', 'corda-finance', 'corda-node', 'corda-node-api', 'corda-test-common', 'corda-test-utils', 'corda-jackson', 'corda-verifier', 'corda-webserver-impl', 'corda-webserver', 'corda-node-driver', 'corda-confidential-identities'] license { name = 'Apache-2.0' url = 'https://www.apache.org/licenses/LICENSE-2.0' @@ -286,7 +287,7 @@ artifactory { password = System.getenv('CORDA_ARTIFACTORY_PASSWORD') } defaults { - publications('corda-jfx', 'corda-mock', 'corda-rpc', 'corda-core', 'corda', 'cordform-common', 'corda-finance', 'corda-node', 'corda-node-api', 'corda-test-common', 'corda-test-utils', 'corda-jackson', 'corda-verifier', 'corda-webserver-impl', 'corda-webserver', 'corda-node-driver') + publications('corda-jfx', 'corda-mock', 'corda-rpc', 'corda-core', 'corda', 'cordform-common', 'corda-finance', 'corda-node', 'corda-node-api', 'corda-test-common', 'corda-test-utils', 'corda-jackson', 'corda-verifier', 'corda-webserver-impl', 'corda-webserver', 'corda-node-driver', 'corda-confidential-identities') } } } diff --git a/confidential-identities/build.gradle b/confidential-identities/build.gradle new file mode 100644 index 0000000000..fcad3bbf8c --- /dev/null +++ b/confidential-identities/build.gradle @@ -0,0 +1,64 @@ +// Experimental Confidential Identities support for 1.0 +// This contains the prototype SwapIdentitiesFlow and SwapIdentitiesHandler, which can be used +// for exchanging confidential identities as part of a flow, until a permanent solution is prepared. +// Expect this module to be removed and merged into core in a later release. +apply plugin: 'kotlin' +apply plugin: CanonicalizerPlugin +apply plugin: 'net.corda.plugins.publish-utils' +apply plugin: 'net.corda.plugins.quasar-utils' +apply plugin: 'net.corda.plugins.cordformation' +apply plugin: 'com.jfrog.artifactory' + +description 'Corda Experimental Confidential Identities' + +buildscript { + repositories { + mavenCentral() + } +} + +dependencies { + // Note the :confidential-identities module is a CorDapp in its own right + // and CorDapps using :confidential-identities features should use 'cordapp' not 'compile' linkage. + cordaCompile project(':core') + + testCompile "junit:junit:$junit_version" + + // Guava: Google test library (collections test suite) + testCompile "com.google.guava:guava-testlib:$guava_version" + + // Bring in the MockNode infrastructure for writing protocol unit tests. + testCompile project(":node") + testCompile project(":node-driver") + + compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" + compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" + testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" + + // Quasar, for suspendable fibres. + compileOnly "co.paralleluniverse:quasar-core:$quasar_version:jdk8" + + // AssertJ: for fluent assertions for testing + testCompile "org.assertj:assertj-core:${assertj_version}" +} + +configurations { + testArtifacts.extendsFrom testRuntime +} + +task testJar(type: Jar) { + classifier "tests" + from sourceSets.test.output +} + +artifacts { + testArtifacts testJar +} + +jar { + baseName 'corda-confidential-identities' +} + +publish { + name jar.baseName +} diff --git a/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt similarity index 94% rename from core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt rename to confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt index 83e20cd5ae..d11bd556a5 100644 --- a/core/src/main/kotlin/net/corda/core/flows/SwapIdentitiesFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt @@ -1,6 +1,9 @@ -package net.corda.core.flows +package net.corda.confidential import co.paralleluniverse.fibers.Suspendable +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.InitiatingFlow +import net.corda.core.flows.StartableByRPC import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt new file mode 100644 index 0000000000..d2b226ec1d --- /dev/null +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt @@ -0,0 +1,27 @@ +package net.corda.confidential; + +import co.paralleluniverse.fibers.Suspendable; +import net.corda.core.flows.FlowLogic +import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate +import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.unwrap + +class SwapIdentitiesHandler(val otherSide: Party, val revocationEnabled: Boolean) : FlowLogic() { + constructor(otherSide: Party) : this(otherSide, false) + companion object { + object SENDING_KEY : ProgressTracker.Step("Sending key") + } + + override val progressTracker: ProgressTracker = ProgressTracker(SENDING_KEY) + + @Suspendable + override fun call(): Unit { + val revocationEnabled = false + progressTracker.currentStep = SENDING_KEY + val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, revocationEnabled) + sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> + SwapIdentitiesFlow.validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) + } + } +} \ No newline at end of file diff --git a/core/src/test/kotlin/net/corda/core/flows/SwapIdentitiesFlowTests.kt b/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt similarity index 98% rename from core/src/test/kotlin/net/corda/core/flows/SwapIdentitiesFlowTests.kt rename to confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt index d0eebd1c65..f974216870 100644 --- a/core/src/test/kotlin/net/corda/core/flows/SwapIdentitiesFlowTests.kt +++ b/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt @@ -1,4 +1,4 @@ -package net.corda.core.flows +package net.corda.confidential import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty diff --git a/finance/build.gradle b/finance/build.gradle index e67a674738..7ded74b45d 100644 --- a/finance/build.gradle +++ b/finance/build.gradle @@ -14,6 +14,7 @@ dependencies { // Note the :finance module is a CorDapp in its own right // and CorDapps using :finance features should use 'cordapp' not 'compile' linkage. cordaCompile project(':core') + cordaCompile project(':confidential-identities') testCompile project(':test-utils') testCompile project(path: ':core', configuration: 'testArtifacts') diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt index 8ace7c1503..38623c23d2 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt @@ -1,10 +1,10 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable +import net.corda.confidential.SwapIdentitiesFlow import net.corda.core.contracts.Amount import net.corda.core.contracts.InsufficientBalanceException import net.corda.core.flows.StartableByRPC -import net.corda.core.flows.SwapIdentitiesFlow import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.serialization.CordaSerializable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index e73c8f2d70..63a05214e0 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -1,10 +1,14 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable +import net.corda.confidential.SwapIdentitiesFlow import net.corda.core.contracts.requireThat import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature -import net.corda.core.flows.* +import net.corda.core.flows.CollectSignaturesFlow +import net.corda.core.flows.FinalityFlow +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.SignTransactionFlow import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party diff --git a/node/build.gradle b/node/build.gradle index 4afebf95e2..a784504792 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -77,6 +77,7 @@ processSmokeTestResources { dependencies { compile project(':node-api') + compile project(":confidential-identities") compile project(':client:rpc') compile "net.corda.plugins:cordform-common:$gradle_plugins_version" diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index cf949b89e0..e0f6eb679a 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -4,6 +4,8 @@ import com.codahale.metrics.MetricRegistry import com.google.common.collect.Lists import com.google.common.collect.MutableClassToInstanceMap import com.google.common.util.concurrent.MoreExecutors +import net.corda.confidential.SwapIdentitiesFlow +import net.corda.confidential.SwapIdentitiesHandler import net.corda.core.concurrent.CordaFuture import net.corda.core.crypto.* import net.corda.core.flows.* @@ -35,7 +37,6 @@ import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappProvider import net.corda.node.services.NotaryChangeHandler import net.corda.node.services.NotifyTransactionHandler -import net.corda.node.services.SwapIdentitiesHandler import net.corda.node.services.api.* import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.configureWithDevSSLCertificate diff --git a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt index 77282ee996..622d994c7c 100644 --- a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt +++ b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt @@ -1,9 +1,13 @@ package net.corda.node.services import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.* -import net.corda.core.identity.PartyAndCertificate +import net.corda.confidential.SwapIdentitiesFlow +import net.corda.core.flows.AbstractStateReplacementFlow +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.ReceiveTransactionFlow +import net.corda.core.flows.StateReplacementException import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.unwrap @@ -44,22 +48,3 @@ class NotaryChangeHandler(otherSide: Party) : AbstractStateReplacementFlow.Accep } } } - -class SwapIdentitiesHandler(val otherSide: Party, val revocationEnabled: Boolean) : FlowLogic() { - constructor(otherSide: Party) : this(otherSide, false) - companion object { - object SENDING_KEY : ProgressTracker.Step("Sending key") - } - - override val progressTracker: ProgressTracker = ProgressTracker(SENDING_KEY) - - @Suspendable - override fun call(): Unit { - val revocationEnabled = false - progressTracker.currentStep = SENDING_KEY - val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, revocationEnabled) - sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> - SwapIdentitiesFlow.validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) - } - } -} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 4d2f595935..a3b8270486 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,6 +1,7 @@ // The project is named 'corda-project' and not 'corda' because if this is named the same as the // output JAR from the capsule then the buildCordaJAR task goes into an infinite loop. rootProject.name = 'corda-project' +include 'confidential-identities' include 'finance' include 'finance:isolated' include 'core' @@ -38,4 +39,4 @@ include 'samples:irs-demo' include 'samples:network-visualiser' include 'samples:simm-valuation-demo' include 'samples:notary-demo' -include 'samples:bank-of-corda-demo' \ No newline at end of file +include 'samples:bank-of-corda-demo' From 8e0b8477af97f4a34f6589303a6b66dce10279f8 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Mon, 18 Sep 2017 15:28:23 +0100 Subject: [PATCH 003/230] Changed FlowLogic.ourIdentity to return Party and added FlowLogic.ourIdentityAndCert which returns PartyAndCertificate. (#1537) Updated code base to make use of these instead of chooseIdentity(). Also improved the serialisation of fiber checkpoints so that it doesn't store the entire cert parth of this identity. --- .idea/compiler.xml | 2 ++ .../corda/confidential/SwapIdentitiesFlow.kt | 8 ++--- .../confidential/SwapIdentitiesHandler.kt | 4 +-- .../net/corda/core/flows/FinalityFlow.kt | 8 ++--- .../kotlin/net/corda/core/flows/FlowLogic.kt | 21 ++++++++++-- .../corda/core/flows/ManualFinalityFlow.kt | 2 +- .../corda/core/internal/FlowStateMachine.kt | 2 +- .../kotlin/net/corda/core/node/NodeInfo.kt | 2 +- .../core/flows/CollectSignaturesFlowTests.kt | 18 ++++------- .../docs/WorkflowTransactionBuildTutorial.kt | 32 ++++++++----------- .../net/corda/finance/flows/CashExitFlow.kt | 13 ++++---- .../net/corda/finance/flows/CashIssueFlow.kt | 14 ++++---- .../corda/finance/flows/TwoPartyDealFlow.kt | 19 +++++------ .../corda/finance/flows/TwoPartyTradeFlow.kt | 25 +++++++-------- .../statemachine/LargeTransactionsTest.kt | 10 +++--- .../test/node/NodeStatePersistenceTests.kt | 2 +- .../net/corda/node/internal/AbstractNode.kt | 5 ++- .../corda/node/internal/CordaRPCOpsImpl.kt | 5 ++- .../corda/node/services/CoreFlowHandlers.kt | 6 +--- .../node/services/api/ServiceHubInternal.kt | 6 ++-- .../statemachine/FlowStateMachineImpl.kt | 10 ++++-- .../services/statemachine/SessionMessage.kt | 5 +-- .../statemachine/StateMachineManager.kt | 24 +++++++++----- .../node/messaging/TwoPartyTradeFlowTests.kt | 20 ++++++------ .../services/events/ScheduledFlowTests.kt | 12 +++---- .../corda/attachmentdemo/AttachmentDemo.kt | 3 +- .../net/corda/irs/flows/AutoOfferFlow.kt | 2 +- .../notarydemo/flows/DummyIssueAndMove.kt | 7 ++-- .../net/corda/vega/flows/IRSTradeFlow.kt | 5 ++- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 15 +++++---- .../net/corda/vega/flows/SimmRevaluation.kt | 6 ++-- .../flow/CommercialPaperIssueFlow.kt | 10 +++--- .../net/corda/traderdemo/flow/SellerFlow.kt | 6 ++-- .../node/testing/MockServiceHubInternal.kt | 8 ++--- .../kotlin/net/corda/testing/CoreTestUtils.kt | 6 ++-- 35 files changed, 178 insertions(+), 165 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index c5c0a6ef37..f455e61871 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -12,6 +12,8 @@ + + diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt index d11bd556a5..58ab4ea99e 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt @@ -18,8 +18,8 @@ import net.corda.core.utilities.unwrap */ @StartableByRPC @InitiatingFlow -class SwapIdentitiesFlow(val otherSide: Party, - val revocationEnabled: Boolean, +class SwapIdentitiesFlow(private val otherSide: Party, + private val revocationEnabled: Boolean, override val progressTracker: ProgressTracker) : FlowLogic>() { constructor(otherSide: Party) : this(otherSide, false, tracker()) @@ -39,7 +39,7 @@ class SwapIdentitiesFlow(val otherSide: Party, @Suspendable override fun call(): LinkedHashMap { progressTracker.currentStep = AWAITING_KEY - val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, revocationEnabled) + val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, revocationEnabled) // Special case that if we're both parties, a single identity is generated val identities = LinkedHashMap() @@ -49,7 +49,7 @@ class SwapIdentitiesFlow(val otherSide: Party, val anonymousOtherSide = sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) } - identities.put(ourIdentity.party, legalIdentityAnonymous.party.anonymise()) + identities.put(ourIdentity, legalIdentityAnonymous.party.anonymise()) identities.put(otherSide, anonymousOtherSide.party.anonymise()) } return identities diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt index d2b226ec1d..89a36deeb0 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt @@ -16,10 +16,10 @@ class SwapIdentitiesHandler(val otherSide: Party, val revocationEnabled: Boolean override val progressTracker: ProgressTracker = ProgressTracker(SENDING_KEY) @Suspendable - override fun call(): Unit { + override fun call() { val revocationEnabled = false progressTracker.currentStep = SENDING_KEY - val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, revocationEnabled) + val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, revocationEnabled) sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> SwapIdentitiesFlow.validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) } diff --git a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt index 181c2d8db6..847475ae75 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt @@ -62,13 +62,13 @@ open class FinalityFlow(val transactions: Iterable, // Lookup the resolved transactions and use them to map each signed transaction to the list of participants. // Then send to the notary if needed, record locally and distribute. progressTracker.currentStep = NOTARISING - val notarisedTxns: List>> = resolveDependenciesOf(transactions) + val notarisedTxns: List>> = resolveDependenciesOf(transactions) .map { (stx, ltx) -> Pair(notariseAndRecord(stx), lookupParties(ltx)) } // Each transaction has its own set of recipients, but extra recipients get them all. progressTracker.currentStep = BROADCASTING for ((stx, parties) in notarisedTxns) { - val participants = (parties + extraRecipients).filter { it != ourIdentity.party }.toSet() + val participants = (parties + extraRecipients).filter { !serviceHub.myInfo.isLegalIdentity(it) }.toSet() if (participants.isNotEmpty()) { broadcastTransaction(stx, participants.toNonEmptySet()) } @@ -117,12 +117,12 @@ open class FinalityFlow(val transactions: Iterable, * * The default implementation throws an exception if an unknown party is encountered. */ - open protected fun lookupParties(ltx: LedgerTransaction): List { + open protected fun lookupParties(ltx: LedgerTransaction): Set { // Calculate who is meant to see the results based on the participants involved. return extractParticipants(ltx).map { serviceHub.identityService.partyFromAnonymous(it) ?: throw IllegalArgumentException("Could not resolve well known identity of participant $it") - } + }.toSet() } /** diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt b/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt index c36cec8069..91269be2d3 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt @@ -7,6 +7,7 @@ import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.abbreviate import net.corda.core.messaging.DataFeed +import net.corda.core.node.NodeInfo import net.corda.core.node.ServiceHub import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction @@ -58,10 +59,24 @@ abstract class FlowLogic { fun initiateFlow(party: Party): FlowSession = stateMachine.initiateFlow(party, flowUsedForSessions) /** - * Specifies our identity in the flow. With node's multiple identities we can choose which one to use for communication. - * Defaults to the first one from [NodeInfo.legalIdentitiesAndCerts]. + * Specifies the identity, with certificate, to use for this flow. This will be one of the multiple identities that + * belong to this node. + * @see NodeInfo.legalIdentitiesAndCerts + * + * Note: The current implementation returns the single identity of the node. This will change once multiple identities + * is implemented. */ - val ourIdentity: PartyAndCertificate get() = stateMachine.ourIdentity + val ourIdentityAndCert: PartyAndCertificate get() = stateMachine.ourIdentityAndCert + + /** + * Specifies the identity to use for this flow. This will be one of the multiple identities that belong to this node. + * This is the same as calling `ourIdentityAndCert.party`. + * @see NodeInfo.legalIdentities + * + * Note: The current implementation returns the single identity of the node. This will change once multiple identities + * is implemented. + */ + val ourIdentity: Party get() = ourIdentityAndCert.party /** * Returns a [FlowInfo] object describing the flow [otherParty] is using. With [FlowInfo.flowVersion] it diff --git a/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt index 5fe7aa2745..16c792266c 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt @@ -16,5 +16,5 @@ class ManualFinalityFlow(transactions: Iterable, recipients: Set, progressTracker: ProgressTracker) : FinalityFlow(transactions, recipients, progressTracker) { constructor(transaction: SignedTransaction, extraParticipants: Set) : this(listOf(transaction), extraParticipants, tracker()) - override fun lookupParties(ltx: LedgerTransaction): List = emptyList() + override fun lookupParties(ltx: LedgerTransaction): Set = emptySet() } diff --git a/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt b/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt index 10faf65cce..dc09d6da3f 100644 --- a/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt +++ b/core/src/main/kotlin/net/corda/core/internal/FlowStateMachine.kt @@ -50,5 +50,5 @@ interface FlowStateMachine { val id: StateMachineRunId val resultFuture: CordaFuture val flowInitiator: FlowInitiator - val ourIdentity: PartyAndCertificate + val ourIdentityAndCert: PartyAndCertificate } diff --git a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt index 2c2f1db71f..5f5ba9eda0 100644 --- a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt @@ -38,7 +38,7 @@ data class NodeInfo(val addresses: List, return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } } - /** Returns true iff [party] is one of the identities of this node. */ + /** Returns true if [party] is one of the identities of this node, else false. */ fun isLegalIdentity(party: Party): Boolean = party in legalIdentities fun serviceIdentities(type: ServiceType): List { diff --git a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt index bb64c68cc7..9de4df3c82 100644 --- a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt @@ -12,10 +12,10 @@ import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap import net.corda.node.internal.StartedNode import net.corda.testing.MINI_CORP_KEY -import net.corda.testing.contracts.DUMMY_PROGRAM_ID -import net.corda.testing.contracts.DummyContract import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentityAndCert +import net.corda.testing.contracts.DUMMY_PROGRAM_ID +import net.corda.testing.contracts.DummyContract import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockServices import org.junit.After @@ -77,9 +77,7 @@ class CollectSignaturesFlowTests { } val stx = subFlow(flow) - val ftx = waitForLedgerCommit(stx.id) - - return ftx + return waitForLedgerCommit(stx.id) } } @@ -91,14 +89,12 @@ class CollectSignaturesFlowTests { val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity val myInputKeys = state.participants.map { it.owningKey } - val myKeys = myInputKeys + (identities[serviceHub.myInfo.chooseIdentity()] ?: serviceHub.myInfo.chooseIdentity()).owningKey + val myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey val command = Command(DummyContract.Commands.Create(), myInputKeys) val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) val ptx = serviceHub.signInitialTransaction(builder) val stx = subFlow(CollectSignaturesFlow(ptx, myKeys)) - val ftx = subFlow(FinalityFlow(stx)).single() - - return ftx + return subFlow(FinalityFlow(stx)).single() } } } @@ -117,9 +113,7 @@ class CollectSignaturesFlowTests { val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) val ptx = serviceHub.signInitialTransaction(builder) val stx = subFlow(CollectSignaturesFlow(ptx, myInputKeys)) - val ftx = subFlow(FinalityFlow(stx)).single() - - return ftx + return subFlow(FinalityFlow(stx)).single() } } diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index 1eaee1a9da..5f34291ead 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -48,8 +48,7 @@ data class TradeApprovalContract(val blank: Unit? = null) : Contract { val counterparty: Party, val state: WorkflowState = WorkflowState.NEW, override val linearId: UniqueIdentifier = UniqueIdentifier(tradeId)) : LinearState { - val parties: List get() = listOf(source, counterparty) - override val participants: List get() = parties + override val participants: List get() = listOf(source, counterparty) } /** @@ -96,29 +95,26 @@ data class TradeApprovalContract(val blank: Unit? = null) : Contract { * The protocol then sends a copy to the other node. We don't require the other party to sign * as their approval/rejection is to follow. */ -class SubmitTradeApprovalFlow(val tradeId: String, - val counterparty: Party) : FlowLogic>() { +class SubmitTradeApprovalFlow(private val tradeId: String, + private val counterparty: Party) : FlowLogic>() { @Suspendable override fun call(): StateAndRef { // Manufacture an initial state - val tradeProposal = TradeApprovalContract.State( - tradeId, - serviceHub.myInfo.chooseIdentity(), - counterparty) + val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty) // identify a notary. This might also be done external to the flow val notary = serviceHub.networkMapCache.getAnyNotary() // Create the TransactionBuilder and populate with the new state. - val tx = TransactionBuilder(notary) - .withItems(StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID), Command(TradeApprovalContract.Commands.Issue(), listOf(tradeProposal.source.owningKey))) + val tx = TransactionBuilder(notary).withItems( + StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID), + Command(TradeApprovalContract.Commands.Issue(), listOf(tradeProposal.source.owningKey))) tx.setTimeWindow(serviceHub.clock.instant(), 60.seconds) // We can automatically sign as there is no untrusted data. val signedTx = serviceHub.signInitialTransaction(tx) // Notarise and distribute. - subFlow(FinalityFlow(signedTx, setOf(serviceHub.myInfo.chooseIdentity(), counterparty))) + subFlow(FinalityFlow(signedTx, setOf(ourIdentity, counterparty))) // Return the initial state return signedTx.tx.outRef(0) } - } /** @@ -126,7 +122,7 @@ class SubmitTradeApprovalFlow(val tradeId: String, * end up with a fully signed copy of the state either as APPROVED, or REJECTED */ @InitiatingFlow -class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : FlowLogic>() { +class SubmitCompletionFlow(private val ref: StateRef, private val verdict: WorkflowState) : FlowLogic>() { init { require(verdict in setOf(WorkflowState.APPROVED, WorkflowState.REJECTED)) { "Verdict must be a final state" @@ -171,7 +167,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow latestRecord, StateAndContract(newState, TRADE_APPROVAL_PROGRAM_ID), Command(TradeApprovalContract.Commands.Completed(), - listOf(serviceHub.myInfo.chooseIdentity().owningKey, latestRecord.state.data.source.owningKey))) + listOf(ourIdentity.owningKey, latestRecord.state.data.source.owningKey))) tx.setTimeWindow(serviceHub.clock.instant(), 60.seconds) // We can sign this transaction immediately as we have already checked all the fields and the decision // is ultimately a manual one from the caller. @@ -197,7 +193,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow subFlow(FinalityFlow(allPartySignedTx, setOf(latestRecord.state.data.source, latestRecord.state.data.counterparty))) // DOCEND 4 // Return back the details of the completed state/transaction. - return allPartySignedTx.tx.outRef(0) + return allPartySignedTx.tx.outRef(0) } } @@ -207,14 +203,14 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow * transaction to the ledger. */ @InitiatedBy(SubmitCompletionFlow::class) -class RecordCompletionFlow(val source: Party) : FlowLogic() { +class RecordCompletionFlow(private val source: Party) : FlowLogic() { @Suspendable - override fun call(): Unit { + override fun call() { // DOCSTART 3 // First we receive the verdict transaction signed by their single key val completeTx = receive(source).unwrap { // Check the transaction is signed apart from our own key and the notary - it.verifySignaturesExcept(serviceHub.myInfo.chooseIdentity().owningKey, it.tx.notary!!.owningKey) + it.verifySignaturesExcept(ourIdentity.owningKey, it.tx.notary!!.owningKey) // Check the transaction data is correctly formed val ltx = it.toLedgerTransaction(serviceHub, false) ltx.verify() diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt index 87245eb783..4ba83b2645 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt @@ -26,7 +26,9 @@ import java.util.* * issuer. */ @StartableByRPC -class CashExitFlow(val amount: Amount, val issuerRef: OpaqueBytes, progressTracker: ProgressTracker) : AbstractCashFlow(progressTracker) { +class CashExitFlow(private val amount: Amount, + private val issuerRef: OpaqueBytes, + progressTracker: ProgressTracker) : AbstractCashFlow(progressTracker) { constructor(amount: Amount, issueRef: OpaqueBytes) : this(amount, issueRef, tracker()) constructor(request: ExitRequest) : this(request.amount, request.issueRef, tracker()) @@ -43,8 +45,9 @@ class CashExitFlow(val amount: Amount, val issuerRef: OpaqueBytes, pro override fun call(): AbstractCashFlow.Result { progressTracker.currentStep = GENERATING_TX val builder = TransactionBuilder(notary = null as Party?) - val issuer = ourIdentity.party.ref(issuerRef) - val exitStates = CashSelection.getInstance({serviceHub.jdbcSession().metaData}).unconsumedCashStatesForSpending(serviceHub, amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference)) + val issuer = ourIdentity.ref(issuerRef) + val exitStates = CashSelection.getInstance { serviceHub.jdbcSession().metaData } + .unconsumedCashStatesForSpending(serviceHub, amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference)) val signers = try { Cash().generateExit( builder, @@ -61,9 +64,7 @@ class CashExitFlow(val amount: Amount, val issuerRef: OpaqueBytes, pro // TODO: Is it safe to drop participants we don't know how to contact? Does not knowing how to contact them // count as a reason to fail? val participants: Set = inputStates - .filterIsInstance() - .map { serviceHub.identityService.partyFromAnonymous(it.owner) } - .filterNotNull() + .mapNotNull { serviceHub.identityService.partyFromAnonymous(it.state.data.owner) } .toSet() // Sign transaction progressTracker.currentStep = SIGNING_TX diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt index f9ef4119d3..2072a0f214 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt @@ -25,9 +25,9 @@ import java.util.* * @param notary the notary to set on the output states. */ @StartableByRPC -class CashIssueFlow(val amount: Amount, - val issuerBankPartyRef: OpaqueBytes, - val notary: Party, +class CashIssueFlow(private val amount: Amount, + private val issuerBankPartyRef: OpaqueBytes, + private val notary: Party, progressTracker: ProgressTracker) : AbstractCashFlow(progressTracker) { constructor(amount: Amount, issuerBankPartyRef: OpaqueBytes, @@ -38,13 +38,13 @@ class CashIssueFlow(val amount: Amount, override fun call(): AbstractCashFlow.Result { progressTracker.currentStep = GENERATING_TX val builder = TransactionBuilder(notary) - val issuer = ourIdentity.party.ref(issuerBankPartyRef) - val signers = Cash().generateIssue(builder, amount.issuedBy(issuer), ourIdentity.party, notary) + val issuer = ourIdentity.ref(issuerBankPartyRef) + val signers = Cash().generateIssue(builder, amount.issuedBy(issuer), ourIdentity, notary) progressTracker.currentStep = SIGNING_TX val tx = serviceHub.signInitialTransaction(builder, signers) progressTracker.currentStep = FINALISING_TX - subFlow(FinalityFlow(tx)) - return Result(tx, ourIdentity.party) + val notarised = subFlow(FinalityFlow(tx)).single() + return Result(notarised, ourIdentity) } @CordaSerializable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index 63a05214e0..956b1b250e 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -9,7 +9,6 @@ import net.corda.core.flows.CollectSignaturesFlow import net.corda.core.flows.FinalityFlow import net.corda.core.flows.FlowLogic import net.corda.core.flows.SignTransactionFlow -import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.node.NodeInfo @@ -58,8 +57,8 @@ object TwoPartyDealFlow { @Suspendable override fun call(): SignedTransaction { progressTracker.currentStep = GENERATING_ID val txIdentities = subFlow(SwapIdentitiesFlow(otherParty)) - val anonymousMe = txIdentities.get(ourIdentity.party) ?: ourIdentity.party.anonymise() - val anonymousCounterparty = txIdentities.get(otherParty) ?: otherParty.anonymise() + val anonymousMe = txIdentities[ourIdentity] ?: ourIdentity.anonymise() + val anonymousCounterparty = txIdentities[otherParty] ?: otherParty.anonymise() progressTracker.currentStep = SENDING_PROPOSAL // Make the first message we'll send to kick off the flow. val hello = Handshake(payload, anonymousMe, anonymousCounterparty) @@ -122,7 +121,7 @@ object TwoPartyDealFlow { logger.trace { "Got signatures from other party, verifying ... " } progressTracker.currentStep = RECORDING - val ftx = subFlow(FinalityFlow(stx, setOf(otherParty, ourIdentity.party))).single() + val ftx = subFlow(FinalityFlow(stx, setOf(otherParty, ourIdentity))).single() logger.trace { "Recorded transaction." } @@ -154,13 +153,15 @@ object TwoPartyDealFlow { val wellKnownOtherParty = serviceHub.identityService.partyFromAnonymous(it.primaryIdentity) val wellKnownMe = serviceHub.identityService.partyFromAnonymous(it.secondaryIdentity) require(wellKnownOtherParty == otherParty) - require(wellKnownMe == ourIdentity.party) + require(wellKnownMe == ourIdentity) validateHandshake(it) } } - @Suspendable protected abstract fun validateHandshake(handshake: Handshake): Handshake - @Suspendable protected abstract fun assembleSharedTX(handshake: Handshake): Triple, List> + @Suspendable + protected abstract fun validateHandshake(handshake: Handshake): Handshake + @Suspendable + protected abstract fun assembleSharedTX(handshake: Handshake): Triple, List> } @CordaSerializable @@ -173,7 +174,7 @@ object TwoPartyDealFlow { override val payload: AutoOffer, override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { override val notaryNode: NodeInfo get() = - serviceHub.networkMapCache.notaryNodes.filter { it.notaryIdentity == payload.notary }.single() + serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == payload.notary } @Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat { // Add some constraints here. @@ -201,7 +202,7 @@ object TwoPartyDealFlow { // We set the transaction's time-window: it may be that none of the contracts need this! // But it can't hurt to have one. ptx.setTimeWindow(serviceHub.clock.instant(), 30.seconds) - return Triple(ptx, arrayListOf(deal.participants.single { it == ourIdentity.party as AbstractParty }.owningKey), emptyList()) + return Triple(ptx, arrayListOf(deal.participants.single { it is Party && serviceHub.myInfo.isLegalIdentity(it) }.owningKey), emptyList()) } } } diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index 367dc8fc82..032f23d301 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -1,10 +1,6 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable -import net.corda.core.contracts.Amount -import net.corda.core.contracts.OwnableState -import net.corda.core.contracts.StateAndRef -import net.corda.core.contracts.withoutIssuer import net.corda.core.contracts.* import net.corda.core.flows.* import net.corda.core.identity.Party @@ -103,7 +99,9 @@ object TwoPartyTradeFlow { val states: Iterable = (stx.tx.inputs.map { serviceHub.loadState(it).data } + stx.tx.outputs.map { it.data }) states.forEach { state -> state.participants.forEach { anon -> - require(serviceHub.identityService.partyFromAnonymous(anon) != null) { "Transaction state ${state} involves unknown participant ${anon}" } + require(serviceHub.identityService.partyFromAnonymous(anon) != null) { + "Transaction state $state involves unknown participant $anon" + } } } @@ -129,12 +127,13 @@ object TwoPartyTradeFlow { // express flow state machines on top of the messaging layer. } - open class Buyer(val otherParty: Party, - val notary: Party, - val acceptablePrice: Amount, - val typeToBuy: Class, - val anonymous: Boolean) : FlowLogic() { - constructor(otherParty: Party, notary: Party, acceptablePrice: Amount, typeToBuy: Class): this(otherParty, notary, acceptablePrice, typeToBuy, true) + open class Buyer(private val otherParty: Party, + private val notary: Party, + private val acceptablePrice: Amount, + private val typeToBuy: Class, + private val anonymous: Boolean) : FlowLogic() { + constructor(otherParty: Party, notary: Party, acceptablePrice: Amount, typeToBuy: Class) : + this(otherParty, notary, acceptablePrice, typeToBuy, true) // DOCSTART 2 object RECEIVING : ProgressTracker.Step("Waiting for seller trading info") @@ -161,9 +160,9 @@ object TwoPartyTradeFlow { // Create the identity we'll be paying to, and send the counterparty proof we own the identity val buyerAnonymousIdentity = if (anonymous) - serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, false) + serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) else - ourIdentity + ourIdentityAndCert // Put together a proposed transaction that performs the trade, and sign it. progressTracker.currentStep = SIGNING val (ptx, cashSigningPubKeys) = assembleSharedTX(assetForSale, tradeRequest, buyerAnonymousIdentity) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index 6ccd63fbd8..b3358408bd 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -11,7 +11,6 @@ import net.corda.testing.BOB import net.corda.testing.DUMMY_NOTARY import net.corda.testing.aliceBobAndNotary import net.corda.testing.contracts.DUMMY_PROGRAM_ID -import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DummyState import net.corda.testing.driver.driver import net.corda.testing.dummyCommand @@ -24,17 +23,20 @@ import kotlin.test.assertEquals */ class LargeTransactionsTest { @StartableByRPC @InitiatingFlow - class SendLargeTransactionFlow(val hash1: SecureHash, val hash2: SecureHash, val hash3: SecureHash, val hash4: SecureHash) : FlowLogic() { + class SendLargeTransactionFlow(private val hash1: SecureHash, + private val hash2: SecureHash, + private val hash3: SecureHash, + private val hash4: SecureHash) : FlowLogic() { @Suspendable override fun call() { val tx = TransactionBuilder(notary = DUMMY_NOTARY) .addOutputState(DummyState(), DUMMY_PROGRAM_ID) - .addCommand(dummyCommand(serviceHub.myInfo.chooseIdentity().owningKey)) + .addCommand(dummyCommand(ourIdentity.owningKey)) .addAttachment(hash1) .addAttachment(hash2) .addAttachment(hash3) .addAttachment(hash4) - val stx = serviceHub.signInitialTransaction(tx, serviceHub.myInfo.chooseIdentity().owningKey) + val stx = serviceHub.signInitialTransaction(tx, ourIdentity.owningKey) // Send to the other side and wait for it to trigger resolution from us. val bob = serviceHub.identityService.partyFromX500Name(BOB.name)!! subFlow(SendTransactionFlow(bob, stx)) diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index 176386fd9f..5185a3bf4f 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -140,7 +140,7 @@ class SendMessageFlow(private val message: Message) : FlowLogic startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, me: PartyAndCertificate?): FlowStateMachineImpl { - check(me == null || me in myInfo.legalIdentitiesAndCerts) { "Attempt to start a flow with legal identity not belonging to this node." } - return serverThread.fetchFrom { smm.add(logic, flowInitiator, me) } + override fun startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, ourIdentity: Party?): FlowStateMachineImpl { + return serverThread.fetchFrom { smm.add(logic, flowInitiator, ourIdentity) } } override fun getFlowFactory(initiatingFlowClass: Class>): InitiatedFlowFactory<*>? { diff --git a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt index 9a4206826a..a3058d9e03 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt @@ -10,7 +10,6 @@ import net.corda.core.flows.StartableByRPC import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.* import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache @@ -143,11 +142,11 @@ class CordaRPCOpsImpl( private fun startFlow(logicType: Class>, args: Array): FlowStateMachineImpl { require(logicType.isAnnotationPresent(StartableByRPC::class.java)) { "${logicType.name} was not designed for RPC" } - val me = services.myInfo.legalIdentitiesAndCerts.first() // TODO RPC flows should have mapping user -> identity that should be resolved automatically on starting flow. val rpcContext = getRpcContext() rpcContext.requirePermission(startFlowPermission(logicType)) val currentUser = FlowInitiator.RPC(rpcContext.currentUser.username) - return services.invokeFlowAsync(logicType, currentUser, me, *args) + // TODO RPC flows should have mapping user -> identity that should be resolved automatically on starting flow. + return services.invokeFlowAsync(logicType, currentUser, *args) } override fun attachmentExists(id: SecureHash): Boolean { diff --git a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt index 622d994c7c..454a9aaddc 100644 --- a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt +++ b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt @@ -1,16 +1,12 @@ package net.corda.node.services import co.paralleluniverse.fibers.Suspendable -import net.corda.confidential.SwapIdentitiesFlow import net.corda.core.flows.AbstractStateReplacementFlow import net.corda.core.flows.FlowLogic import net.corda.core.flows.ReceiveTransactionFlow import net.corda.core.flows.StateReplacementException import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.ProgressTracker -import net.corda.core.utilities.unwrap // TODO: We should have a whitelist of contracts we're willing to accept at all, and reject if the transaction // includes us in any outside that list. Potentially just if it includes any outside that list at all. @@ -32,7 +28,7 @@ class NotaryChangeHandler(otherSide: Party) : AbstractStateReplacementFlow.Accep * and is also in a geographically convenient location we can just automatically approve the change. * TODO: In more difficult cases this should call for human attention to manually verify and approve the proposal */ - override fun verifyProposal(stx: SignedTransaction, proposal: AbstractStateReplacementFlow.Proposal): Unit { + override fun verifyProposal(stx: SignedTransaction, proposal: AbstractStateReplacementFlow.Proposal) { val state = proposal.stateRef val proposedTx = stx.resolveNotaryChangeTransaction(serviceHub) val newNotary = proposal.modification diff --git a/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt b/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt index f3ceca8c26..1e2625ffb4 100644 --- a/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt +++ b/node/src/main/kotlin/net/corda/node/services/api/ServiceHubInternal.kt @@ -6,7 +6,6 @@ import net.corda.core.flows.FlowInitiator import net.corda.core.flows.FlowLogic import net.corda.core.flows.StateMachineRunId import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.VisibleForTesting import net.corda.core.messaging.DataFeed @@ -118,7 +117,7 @@ interface ServiceHubInternal : ServiceHub { * Starts an already constructed flow. Note that you must be on the server thread to call this method. * @param flowInitiator indicates who started the flow, see: [FlowInitiator]. */ - fun startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, me: PartyAndCertificate? = null): FlowStateMachineImpl + fun startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, ourIdentity: Party? = null): FlowStateMachineImpl /** * Will check [logicType] and [args] against a whitelist and if acceptable then construct and initiate the flow. @@ -131,12 +130,11 @@ interface ServiceHubInternal : ServiceHub { fun invokeFlowAsync( logicType: Class>, flowInitiator: FlowInitiator, - me: PartyAndCertificate? = null, vararg args: Any?): FlowStateMachineImpl { val logicRef = FlowLogicRefFactoryImpl.createForRPC(logicType, *args) @Suppress("UNCHECKED_CAST") val logic = FlowLogicRefFactoryImpl.toFlowLogic(logicRef) as FlowLogic - return startFlow(logic, flowInitiator, me) + return startFlow(logic, flowInitiator, ourIdentity = null) } fun getFlowFactory(initiatingFlowClass: Class>): InitiatedFlowFactory<*>? diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index e5065337d8..0a1299b591 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -12,9 +12,12 @@ import net.corda.core.crypto.random63BitValue import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate -import net.corda.core.internal.* +import net.corda.core.internal.FlowStateMachine +import net.corda.core.internal.abbreviate import net.corda.core.internal.concurrent.OpenFuture import net.corda.core.internal.concurrent.openFuture +import net.corda.core.internal.isRegularFile +import net.corda.core.internal.staticField import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.* import net.corda.node.services.api.FlowAppAuditEvent @@ -37,7 +40,9 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, val logic: FlowLogic, scheduler: FiberScheduler, override val flowInitiator: FlowInitiator, - override val ourIdentity: PartyAndCertificate) : Fiber(id.toString(), scheduler), FlowStateMachine { + // Store the Party rather than the full cert path with PartyAndCertificate + val ourIdentity: Party) : Fiber(id.toString(), scheduler), FlowStateMachine { + companion object { // Used to work around a small limitation in Quasar. private val QUASAR_UNBLOCKER = Fiber::class.staticField("SERIALIZER_BLOCKER").value @@ -67,6 +72,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, // These fields shouldn't be serialised, so they are marked @Transient. @Transient override lateinit var serviceHub: ServiceHubInternal + @Transient override lateinit var ourIdentityAndCert: PartyAndCertificate @Transient internal lateinit var database: CordaPersistence @Transient internal lateinit var actionOnSuspend: (FlowIORequest) -> Unit @Transient internal lateinit var actionOnEnd: (Try, Boolean) -> Unit diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/SessionMessage.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/SessionMessage.kt index 0708da39a2..fc103e6dca 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/SessionMessage.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/SessionMessage.kt @@ -3,7 +3,6 @@ package net.corda.node.services.statemachine import net.corda.core.flows.FlowException import net.corda.core.flows.UnexpectedFlowEndException import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.castIfPossible import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.UntrustworthyData @@ -26,9 +25,7 @@ data class SessionInit(val initiatorSessionId: Long, val initiatingFlowClass: String, val flowVersion: Int, val appName: String, - val firstPayload: Any?, - // Left as a placeholder for support of multiple identities on a node. For now we choose the first one as a special one. - val otherIdentity: PartyAndCertificate? = null) : SessionMessage + val firstPayload: Any?) : SessionMessage data class SessionConfirm(override val initiatorSessionId: Long, val initiatedSessionId: Long, diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt index d0f899626a..dc2a8342cb 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/StateMachineManager.kt @@ -14,7 +14,6 @@ import net.corda.core.crypto.SecureHash import net.corda.core.crypto.random63BitValue import net.corda.core.flows.* import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.ThreadBox import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.castIfPossible @@ -371,8 +370,9 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, session.receivedMessages += ReceivedSessionMessage(sender, SessionData(session.ourSessionId, sessionInit.firstPayload)) } openSessions[session.ourSessionId] = session - val meIdentity = sessionInit.otherIdentity ?: serviceHub.myInfo.legalIdentitiesAndCerts.first() - val fiber = createFiber(flow, FlowInitiator.Peer(sender), meIdentity) + // TODO Perhaps the session-init will specificy which of our multiple identies to use, which we would have to + // double-check is actually ours. However, what if we want to control how our identities gets used? + val fiber = createFiber(flow, FlowInitiator.Peer(sender)) flowSession.sessionFlow = flow flowSession.stateMachine = fiber fiber.openSessions[Pair(flow, sender)] = session @@ -427,15 +427,23 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, } } - private fun createFiber(logic: FlowLogic, flowInitiator: FlowInitiator, me: PartyAndCertificate): FlowStateMachineImpl { - val id = StateMachineRunId.createRandom() - return FlowStateMachineImpl(id, logic, scheduler, flowInitiator, me).apply { initFiber(this) } + private fun createFiber(logic: FlowLogic, flowInitiator: FlowInitiator, ourIdentity: Party? = null): FlowStateMachineImpl { + val fsm = FlowStateMachineImpl( + StateMachineRunId.createRandom(), + logic, + scheduler, + flowInitiator, + ourIdentity ?: serviceHub.myInfo.legalIdentities[0]) + initFiber(fsm) + return fsm } private fun initFiber(fiber: FlowStateMachineImpl<*>) { verifyFlowLogicIsSuspendable(fiber.logic) fiber.database = database fiber.serviceHub = serviceHub + fiber.ourIdentityAndCert = serviceHub.myInfo.legalIdentitiesAndCerts.find { it.party == fiber.ourIdentity } + ?: throw IllegalStateException("Identity specified by ${fiber.id} (${fiber.ourIdentity}) is not one of ours!") fiber.actionOnSuspend = { ioRequest -> updateCheckpoint(fiber) // We commit on the fibers transaction that was copied across ThreadLocals during suspend @@ -514,11 +522,11 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, * * Note that you must be on the [executor] thread. */ - fun add(logic: FlowLogic, flowInitiator: FlowInitiator, me: PartyAndCertificate?): FlowStateMachineImpl { + fun add(logic: FlowLogic, flowInitiator: FlowInitiator, ourIdentity: Party? = null): FlowStateMachineImpl { // TODO: Check that logic has @Suspendable on its call method. executor.checkOnThread() val fiber = database.transaction { - val fiber = createFiber(logic, flowInitiator, me ?: serviceHub.myInfo.legalIdentitiesAndCerts.first()) + val fiber = createFiber(logic, flowInitiator, ourIdentity) updateCheckpoint(fiber) fiber } diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 3af174c0d7..c47cb53174 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -545,17 +545,17 @@ class TwoPartyTradeFlowTests { } @InitiatingFlow - class SellerInitiator(val buyer: Party, - val notary: NodeInfo, - val assetToSell: StateAndRef, - val price: Amount, - val anonymous: Boolean) : FlowLogic() { + class SellerInitiator(private val buyer: Party, + private val notary: NodeInfo, + private val assetToSell: StateAndRef, + private val price: Amount, + private val anonymous: Boolean) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - val myParty = if (anonymous) { - serviceHub.keyManagementService.freshKeyAndCert(serviceHub.myInfo.chooseIdentityAndCert(), false) + val myPartyAndCert = if (anonymous) { + serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) } else { - serviceHub.myInfo.chooseIdentityAndCert() + ourIdentityAndCert } send(buyer, TestTx(notary.notaryIdentity, price, anonymous)) return subFlow(Seller( @@ -563,12 +563,12 @@ class TwoPartyTradeFlowTests { notary, assetToSell, price, - myParty)) + myPartyAndCert)) } } @InitiatedBy(SellerInitiator::class) - class BuyerAcceptor(val seller: Party) : FlowLogic() { + class BuyerAcceptor(private val seller: Party) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { val (notary, price, anonymous) = receive(seller).unwrap { diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 02a2550b86..da50a4c710 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -37,6 +37,7 @@ class ScheduledFlowTests { val PAGE_SIZE = 20 val SORTING = Sort(listOf(Sort.SortColumn(SortAttribute.Standard(Sort.CommonStateAttribute.STATE_REF_TXN_ID), Sort.Direction.DESC))) } + lateinit var mockNet: MockNetwork lateinit var notaryNode: StartedNode lateinit var nodeA: StartedNode @@ -59,23 +60,22 @@ class ScheduledFlowTests { override val participants: List = listOf(source, destination) } - class InsertInitialStateFlow(val destination: Party) : FlowLogic() { + class InsertInitialStateFlow(private val destination: Party) : FlowLogic() { @Suspendable override fun call() { - val scheduledState = ScheduledState(serviceHub.clock.instant(), - serviceHub.myInfo.chooseIdentity(), destination) + val scheduledState = ScheduledState(serviceHub.clock.instant(), ourIdentity, destination) val notary = serviceHub.networkMapCache.getAnyNotary() val builder = TransactionBuilder(notary) .addOutputState(scheduledState, DUMMY_PROGRAM_ID) .addCommand(dummyCommand(ourIdentity.owningKey)) val tx = serviceHub.signInitialTransaction(builder) - subFlow(FinalityFlow(tx, setOf(serviceHub.myInfo.chooseIdentity()))) + subFlow(FinalityFlow(tx, setOf(ourIdentity))) } } @SchedulableFlow - class ScheduledFlow(val stateRef: StateRef) : FlowLogic() { + class ScheduledFlow(private val stateRef: StateRef) : FlowLogic() { @Suspendable override fun call() { val state = serviceHub.toStateAndRef(stateRef) @@ -90,7 +90,7 @@ class ScheduledFlowTests { val builder = TransactionBuilder(notary) .addInputState(state) .addOutputState(newStateOutput, DUMMY_PROGRAM_ID) - .addCommand(dummyCommand(serviceHub.myInfo.chooseIdentity().owningKey)) + .addCommand(dummyCommand(ourIdentity.owningKey)) val tx = serviceHub.signInitialTransaction(builder) subFlow(FinalityFlow(tx, setOf(scheduledState.source, scheduledState.destination))) } diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt index 488fdf3e69..76dbece304 100644 --- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt +++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt @@ -25,7 +25,6 @@ import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.getOrThrow import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.chooseIdentity import net.corda.testing.driver.poll import java.io.InputStream import java.net.HttpURLConnection @@ -118,7 +117,7 @@ class AttachmentDemoFlow(val otherSide: Party, val notary: Party, val hash: Secu // Create a trivial transaction with an output that describes the attachment, and the attachment itself val ptx = TransactionBuilder(notary) .addOutputState(AttachmentContract.State(hash), ATTACHMENT_PROGRAM_ID) - .addCommand(AttachmentContract.Command, serviceHub.myInfo.chooseIdentity().owningKey) + .addCommand(AttachmentContract.Command, ourIdentity.owningKey) .addAttachment(hash) progressTracker.currentStep = SIGNING diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt index df53d44c77..aa4ab59ce4 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt @@ -62,7 +62,7 @@ object AutoOfferFlow { } private fun notUs(parties: List): List { - return parties.filter { ourIdentity.party != it } + return parties.filter { ourIdentity != it } } } diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt index e5ffc20c99..5d4820f0b5 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt @@ -11,7 +11,6 @@ import net.corda.core.identity.Party import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder -import net.corda.testing.chooseIdentity @StartableByRPC class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: Party, private val discriminator: Int) : FlowLogic() { @@ -27,10 +26,10 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: @Suspendable override fun call(): SignedTransaction { // Self issue an asset - val state = State(listOf(serviceHub.myInfo.chooseIdentity()), discriminator) + val state = State(listOf(ourIdentity), discriminator) val issueTx = serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { addOutputState(state, DO_NOTHING_PROGRAM_ID) - addCommand(DummyCommand(),listOf(serviceHub.myInfo.chooseIdentity().owningKey)) + addCommand(DummyCommand(),listOf(ourIdentity.owningKey)) }) serviceHub.recordTransactions(issueTx) // Move ownership of the asset to the counterparty @@ -38,7 +37,7 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: return serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { addInputState(issueTx.tx.outRef(0)) addOutputState(state.copy(participants = listOf(counterpartyNode)), DO_NOTHING_PROGRAM_ID) - addCommand(DummyCommand(),listOf(serviceHub.myInfo.chooseIdentity().owningKey)) + addCommand(DummyCommand(),listOf(ourIdentity.owningKey)) }) } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt index 5a510ee5e9..0a63c159f5 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt @@ -11,7 +11,6 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.unwrap import net.corda.finance.flows.TwoPartyDealFlow import net.corda.vega.contracts.IRSState -import net.corda.vega.contracts.OGTrade import net.corda.vega.contracts.SwapData object IRSTradeFlow { @@ -27,9 +26,9 @@ object IRSTradeFlow { val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity val (buyer, seller) = if (swap.buyer.second == ourIdentity.owningKey) { - Pair(ourIdentity.party, otherParty) + Pair(ourIdentity, otherParty) } else { - Pair(otherParty, ourIdentity.party) + Pair(otherParty, ourIdentity) } val offer = IRSState(swap, buyer, seller) diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index d0e0ef9cbe..8ad4e384a1 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -21,7 +21,10 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.unwrap import net.corda.finance.flows.TwoPartyDealFlow import net.corda.vega.analytics.* -import net.corda.vega.contracts.* +import net.corda.vega.contracts.IRSState +import net.corda.vega.contracts.PortfolioState +import net.corda.vega.contracts.PortfolioValuation +import net.corda.vega.contracts.RevisionedState import net.corda.vega.portfolio.Portfolio import net.corda.vega.portfolio.toPortfolio import java.time.LocalDate @@ -48,16 +51,16 @@ object SimmFlow { */ @InitiatingFlow @StartableByRPC - class Requester(val otherParty: Party, - val valuationDate: LocalDate, - val existing: StateAndRef?) + class Requester(private val otherParty: Party, + private val valuationDate: LocalDate, + private val existing: StateAndRef?) : FlowLogic>() { constructor(otherParty: Party, valuationDate: LocalDate) : this(otherParty, valuationDate, null) lateinit var notary: Party @Suspendable override fun call(): RevisionedState { - logger.debug("Calling from: ${ourIdentity.party}. Sending to: $otherParty") + logger.debug("Calling from: $ourIdentity. Sending to: $otherParty") require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity @@ -80,7 +83,7 @@ object SimmFlow { @Suspendable private fun agreePortfolio(portfolio: Portfolio) { logger.info("Agreeing portfolio") - val parties = Pair(ourIdentity.party, otherParty) + val parties = Pair(ourIdentity, otherParty) val portfolioState = PortfolioState(portfolio.refs, parties, valuationDate) send(otherParty, OfferMessage(notary, portfolioState, existing?.ref, valuationDate)) diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt index 95600b853e..72fa97480a 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt @@ -17,12 +17,12 @@ import java.time.LocalDate object SimmRevaluation { @StartableByRPC @SchedulableFlow - class Initiator(val curStateRef: StateRef, val valuationDate: LocalDate) : FlowLogic() { + class Initiator(private val curStateRef: StateRef, private val valuationDate: LocalDate) : FlowLogic() { @Suspendable - override fun call(): Unit { + override fun call() { val stateAndRef = serviceHub.vaultQueryService.queryBy(VaultQueryCriteria(stateRefs = listOf(curStateRef))).states.single() val curState = stateAndRef.state.data - if (ourIdentity.party == curState.participants[0]) { + if (ourIdentity == curState.participants[0]) { val otherParty = serviceHub.identityService.partyFromAnonymous(curState.participants[1]) require(otherParty != null) { "Other party must be known by this node" } subFlow(SimmFlow.Requester(otherParty!!, valuationDate, stateAndRef)) diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt index bdef4a03e8..f89aafd091 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt @@ -22,10 +22,10 @@ import java.util.* * Flow for the Bank of Corda node to issue some commercial paper to the seller's node, to sell to the buyer. */ @StartableByRPC -class CommercialPaperIssueFlow(val amount: Amount, - val issueRef: OpaqueBytes, - val recipient: Party, - val notary: Party, +class CommercialPaperIssueFlow(private val amount: Amount, + private val issueRef: OpaqueBytes, + private val recipient: Party, + private val notary: Party, override val progressTracker: ProgressTracker) : FlowLogic() { constructor(amount: Amount, issueRef: OpaqueBytes, recipient: Party, notary: Party) : this(amount, issueRef, recipient, notary, tracker()) @@ -40,7 +40,7 @@ class CommercialPaperIssueFlow(val amount: Amount, progressTracker.currentStep = ISSUING val issuance: SignedTransaction = run { - val tx = CommercialPaper().generateIssue(ourIdentity.party.ref(issueRef), amount `issued by` ourIdentity.party.ref(issueRef), + val tx = CommercialPaper().generateIssue(ourIdentity.ref(issueRef), amount `issued by` ourIdentity.ref(issueRef), Instant.now() + 10.days, notary) // TODO: Consider moving these two steps below into generateIssue. diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt index f70e3bca45..c7eeccb797 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt @@ -16,8 +16,8 @@ import java.util.* @InitiatingFlow @StartableByRPC -class SellerFlow(val otherParty: Party, - val amount: Amount, +class SellerFlow(private val otherParty: Party, + private val amount: Amount, override val progressTracker: ProgressTracker) : FlowLogic() { constructor(otherParty: Party, amount: Amount) : this(otherParty, amount, tracker()) @@ -41,7 +41,7 @@ class SellerFlow(val otherParty: Party, progressTracker.currentStep = SELF_ISSUING val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] - val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentity, false) + val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first() progressTracker.currentStep = TRADING diff --git a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt index 1b2f5ddb34..31e5ce8440 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt @@ -3,11 +3,10 @@ package net.corda.node.testing import com.codahale.metrics.MetricRegistry import net.corda.core.flows.FlowInitiator import net.corda.core.flows.FlowLogic -import net.corda.core.identity.PartyAndCertificate +import net.corda.core.identity.Party import net.corda.core.node.NodeInfo import net.corda.core.node.services.* import net.corda.core.serialization.SerializeAsToken -import net.corda.core.utilities.NonEmptySet import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.serialization.NodeClock import net.corda.node.services.api.* @@ -79,9 +78,8 @@ open class MockServiceHubInternal( override fun cordaService(type: Class): T = throw UnsupportedOperationException() - override fun startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, me: PartyAndCertificate?): FlowStateMachineImpl { - check(me == null || me in myInfo.legalIdentitiesAndCerts) { "Attempt to start a flow with legal identity not belonging to this node." } - return smm.executor.fetchFrom { smm.add(logic, flowInitiator, me) } + override fun startFlow(logic: FlowLogic, flowInitiator: FlowInitiator, ourIdentity: Party?): FlowStateMachineImpl { + return smm.executor.fetchFrom { smm.add(logic, flowInitiator, ourIdentity) } } override fun getFlowFactory(initiatingFlowClass: Class>): InitiatedFlowFactory<*>? = null diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index 30db24bbde..bd1c25673e 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -12,7 +12,9 @@ import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.cert import net.corda.core.node.NodeInfo import net.corda.core.node.services.IdentityService -import net.corda.core.utilities.* +import net.corda.core.utilities.NetworkHostAndPort +import net.corda.core.utilities.OpaqueBytes +import net.corda.core.utilities.loggerFor import net.corda.finance.contracts.asset.DUMMY_CASH_ISSUER import net.corda.node.services.config.configureDevKeyAndTrustStores import net.corda.node.services.identity.InMemoryIdentityService @@ -159,4 +161,4 @@ inline fun amqpSpecific(reason: String, function: () -> Unit) * TODO: Should be removed after multiple identities are introduced. */ fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first() -fun NodeInfo.chooseIdentity(): Party = legalIdentitiesAndCerts.first().party +fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party From c3764ff944f97c679c2b9eb855eefdd7a52e738c Mon Sep 17 00:00:00 2001 From: Alberto Arri <30873160+al-r3@users.noreply.github.com> Date: Tue, 19 Sep 2017 12:57:44 +0100 Subject: [PATCH 004/230] Fix US country code (#1549) --- .../src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index 45892c32cc..c9097fa7fb 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -79,7 +79,7 @@ class ExplorerSimulation(val options: OptionSet) { advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("cash"))), customOverrides = mapOf("nearestCity" to "Madrid")) val ukBankName = CordaX500Name(organisation = "UK Bank Plc", locality = "London", country = "GB") - val usaBankName = CordaX500Name(organisation = "USA Bank Corp", locality = "New York", country = "USA") + val usaBankName = CordaX500Name(organisation = "USA Bank Corp", locality = "New York", country = "US") val issuerGBP = startNode(providedName = ukBankName, rpcUsers = arrayListOf(manager), advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.GBP"))), customOverrides = mapOf("nearestCity" to "London")) From b332b9682989a37a1edcb06180d216a2732ea95b Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Tue, 19 Sep 2017 14:51:03 +0100 Subject: [PATCH 005/230] Remove Kotlin classes from confidential-identities. (#1553) --- confidential-identities/build.gradle | 32 +++---------------- .../confidential/SwapIdentitiesHandler.kt | 4 +-- 2 files changed, 7 insertions(+), 29 deletions(-) diff --git a/confidential-identities/build.gradle b/confidential-identities/build.gradle index fcad3bbf8c..04212b3df1 100644 --- a/confidential-identities/build.gradle +++ b/confidential-identities/build.gradle @@ -11,17 +11,15 @@ apply plugin: 'com.jfrog.artifactory' description 'Corda Experimental Confidential Identities' -buildscript { - repositories { - mavenCentral() - } -} - dependencies { // Note the :confidential-identities module is a CorDapp in its own right // and CorDapps using :confidential-identities features should use 'cordapp' not 'compile' linkage. cordaCompile project(':core') + // Quasar, for suspendable fibres. + compileOnly "co.paralleluniverse:quasar-core:$quasar_version:jdk8" + + testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" testCompile "junit:junit:$junit_version" // Guava: Google test library (collections test suite) @@ -31,28 +29,8 @@ dependencies { testCompile project(":node") testCompile project(":node-driver") - compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:$kotlin_version" - compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" - testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" - - // Quasar, for suspendable fibres. - compileOnly "co.paralleluniverse:quasar-core:$quasar_version:jdk8" - // AssertJ: for fluent assertions for testing - testCompile "org.assertj:assertj-core:${assertj_version}" -} - -configurations { - testArtifacts.extendsFrom testRuntime -} - -task testJar(type: Jar) { - classifier "tests" - from sourceSets.test.output -} - -artifacts { - testArtifacts testJar + testCompile "org.assertj:assertj-core:$assertj_version" } jar { diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt index 89a36deeb0..67d9e0b7b6 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt @@ -1,6 +1,6 @@ -package net.corda.confidential; +package net.corda.confidential -import co.paralleluniverse.fibers.Suspendable; +import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate From 0e3005518ee8d5994661b4377ebfc17ffc36f523 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Tue, 19 Sep 2017 15:05:54 +0100 Subject: [PATCH 006/230] Exclude kotlin-reflect artifact from any CorDapp. (#1555) --- constants.properties | 2 +- .../src/main/groovy/net/corda/plugins/Cordformation.groovy | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/constants.properties b/constants.properties index 0c4e4ef5b1..0df5b1245b 100644 --- a/constants.properties +++ b/constants.properties @@ -1,4 +1,4 @@ -gradlePluginsVersion=0.16.4 +gradlePluginsVersion=0.16.5 kotlinVersion=1.1.4 guavaVersion=21.0 bouncycastleVersion=1.57 diff --git a/gradle-plugins/cordformation/src/main/groovy/net/corda/plugins/Cordformation.groovy b/gradle-plugins/cordformation/src/main/groovy/net/corda/plugins/Cordformation.groovy index 60ca278dee..2fe24a7933 100644 --- a/gradle-plugins/cordformation/src/main/groovy/net/corda/plugins/Cordformation.groovy +++ b/gradle-plugins/cordformation/src/main/groovy/net/corda/plugins/Cordformation.groovy @@ -60,6 +60,7 @@ class Cordformation implements Plugin { def excludes = [ [group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib'], [group: 'org.jetbrains.kotlin', name: 'kotlin-stdlib-jre8'], + [group: 'org.jetbrains.kotlin', name: 'kotlin-reflect'], [group: 'co.paralleluniverse', name: 'quasar-core'] ] From 544fd943f4ed2a57a24dc239141d058a2188c29d Mon Sep 17 00:00:00 2001 From: Alberto Arri <30873160+al-r3@users.noreply.github.com> Date: Tue, 19 Sep 2017 17:30:23 +0100 Subject: [PATCH 007/230] Set title for node explorer windows (#1551) --- .../src/main/kotlin/net/corda/explorer/views/GuiUtilities.kt | 2 ++ .../src/main/kotlin/net/corda/explorer/views/LoginView.kt | 2 +- .../src/main/kotlin/net/corda/explorer/views/MainView.kt | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/GuiUtilities.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/GuiUtilities.kt index a30aa68baa..e61163b24b 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/GuiUtilities.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/GuiUtilities.kt @@ -19,6 +19,8 @@ import net.corda.finance.contracts.asset.Cash import tornadofx.* import java.security.PublicKey +const val WINDOW_TITLE = "Corda Node Explorer" + /** * Helper method to reduce boiler plate code */ diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/LoginView.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/LoginView.kt index ec0752d6c2..302f0253dd 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/LoginView.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/LoginView.kt @@ -10,7 +10,7 @@ import org.controlsfx.dialog.ExceptionDialog import tornadofx.* import kotlin.system.exitProcess -class LoginView : View() { +class LoginView : View(WINDOW_TITLE) { override val root by fxml() private val hostTextField by fxid() diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt index 69a661c7c3..2369a5dfc5 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/MainView.kt @@ -30,7 +30,7 @@ import tornadofx.* /** * The root view embeds the [Shell] and provides support for the status bar, and modal dialogs. */ -class MainView : View() { +class MainView : View(WINDOW_TITLE) { override val root by fxml() // Inject components. From 92e22ab5f878aa75277b19c98259fb077d803566 Mon Sep 17 00:00:00 2001 From: Maksymilian Pawlak <120831+m4ksio@users.noreply.github.com> Date: Tue, 19 Sep 2017 17:33:00 +0100 Subject: [PATCH 008/230] Test identities names cleanup (#1552) --- samples/bank-of-corda-demo/build.gradle | 4 ++-- .../src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt | 2 +- .../src/main/kotlin/net/corda/testing/CoreTestUtils.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index 45ec1aaeff..edebb866ba 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -59,7 +59,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { cordapps = ["net.corda:finance:$corda_release_version"] } node { - name "O=BankOfCorda,L=New York,C=US" + name "O=BankOfCorda,L=London,C=GB" advertisedServices = ["corda.issuer.USD"] p2pPort 10005 rpcPort 10006 @@ -74,7 +74,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { ] } node { - name "O=BigCorporation,L=London,C=GB" + name "O=BigCorporation,L=New York,C=US" advertisedServices = [] p2pPort 10008 rpcPort 10009 diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt index 8d94948992..4554b7d7c9 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt @@ -28,7 +28,7 @@ fun main(args: Array) { val BANK_USERNAME = "bankUser" val BIGCORP_USERNAME = "bigCorpUser" -val BIGCORP_LEGAL_NAME = CordaX500Name(organisation = "BigCorporation", locality = "London", country = "GB") +val BIGCORP_LEGAL_NAME = CordaX500Name(organisation = "BigCorporation", locality = "New York", country = "US") private class BankOfCordaDriver { enum class Role { diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index bd1c25673e..25059c5d8e 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -76,7 +76,7 @@ val BOC_PARTY_REF = BOC.ref(OpaqueBytes.of(1)).reference val BIG_CORP_KEY: KeyPair by lazy { generateKeyPair() } val BIG_CORP_PUBKEY: PublicKey get() = BIG_CORP_KEY.public -val BIG_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CordaX500Name(organisation = "BigCorporation", locality = "London", country = "GB"), BIG_CORP_PUBKEY) +val BIG_CORP_IDENTITY: PartyAndCertificate get() = getTestPartyAndCertificate(CordaX500Name(organisation = "BigCorporation", locality = "New York", country = "US"), BIG_CORP_PUBKEY) val BIG_CORP: Party get() = BIG_CORP_IDENTITY.party val BIG_CORP_PARTY_REF = BIG_CORP.ref(OpaqueBytes.of(1)).reference From 838e7531648c2b3d86e24894c684c0657f544fc2 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Tue, 19 Sep 2017 17:36:26 +0100 Subject: [PATCH 009/230] Moved PhysicalLocationStructures into finance (#1557) --- docs/source/changelog.rst | 2 ++ .../net/corda/finance/utils}/PhysicalLocationStructures.kt | 2 +- .../src/main/resources/net/corda/finance/utils}/cities.txt | 0 .../kotlin/net/corda/finance/utils}/CityDatabaseTest.kt | 2 +- .../src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt | 2 +- .../main/kotlin/net/corda/netmap/simulation/Simulation.kt | 4 ++-- .../src/main/kotlin/net/corda/testing/node/MockNode.kt | 2 +- .../src/main/kotlin/net/corda/demobench/model/NodeData.kt | 2 +- .../main/kotlin/net/corda/demobench/views/NodeTabView.kt | 4 ++-- .../src/main/kotlin/net/corda/explorer/views/Network.kt | 6 +++--- 10 files changed, 14 insertions(+), 12 deletions(-) rename {core/src/main/kotlin/net/corda/core/node => finance/src/main/kotlin/net/corda/finance/utils}/PhysicalLocationStructures.kt (99%) rename {core/src/main/resources/net/corda/core/node => finance/src/main/resources/net/corda/finance/utils}/cities.txt (100%) rename {core/src/test/kotlin/net/corda/core/node => finance/src/test/kotlin/net/corda/finance/utils}/CityDatabaseTest.kt (91%) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index bc370af2b6..dab2a42814 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -152,6 +152,8 @@ UNRELEASED * ``X509CertificateHolder`` has been removed from the public API, replaced by ``java.security.X509Certificate``. +* Moved ``CityDatabase`` out of ``core`` and into ``finance`` + Milestone 14 ------------ diff --git a/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt b/finance/src/main/kotlin/net/corda/finance/utils/PhysicalLocationStructures.kt similarity index 99% rename from core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt rename to finance/src/main/kotlin/net/corda/finance/utils/PhysicalLocationStructures.kt index 754fbbc44e..5277921bd1 100644 --- a/core/src/main/kotlin/net/corda/core/node/PhysicalLocationStructures.kt +++ b/finance/src/main/kotlin/net/corda/finance/utils/PhysicalLocationStructures.kt @@ -1,4 +1,4 @@ -package net.corda.core.node +package net.corda.finance.utils import net.corda.core.serialization.CordaSerializable import java.util.* diff --git a/core/src/main/resources/net/corda/core/node/cities.txt b/finance/src/main/resources/net/corda/finance/utils/cities.txt similarity index 100% rename from core/src/main/resources/net/corda/core/node/cities.txt rename to finance/src/main/resources/net/corda/finance/utils/cities.txt diff --git a/core/src/test/kotlin/net/corda/core/node/CityDatabaseTest.kt b/finance/src/test/kotlin/net/corda/finance/utils/CityDatabaseTest.kt similarity index 91% rename from core/src/test/kotlin/net/corda/core/node/CityDatabaseTest.kt rename to finance/src/test/kotlin/net/corda/finance/utils/CityDatabaseTest.kt index a9d3bcda6a..e0e5036146 100644 --- a/core/src/test/kotlin/net/corda/core/node/CityDatabaseTest.kt +++ b/finance/src/test/kotlin/net/corda/finance/utils/CityDatabaseTest.kt @@ -1,4 +1,4 @@ -package net.corda.core.node +package net.corda.finance.utils import org.junit.Assert.assertEquals import org.junit.Test diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt index ec3aea5111..f9751e8d6c 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/VisualiserViewModel.kt @@ -8,8 +8,8 @@ import javafx.scene.shape.Circle import javafx.scene.shape.Line import javafx.util.Duration import net.corda.core.identity.CordaX500Name -import net.corda.core.node.ScreenCoordinate import net.corda.core.utilities.ProgressTracker +import net.corda.finance.utils.ScreenCoordinate import net.corda.netmap.simulation.IRSSimulation import net.corda.testing.chooseIdentity import net.corda.testing.node.MockNetwork diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index 89509aefa0..a466501651 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -2,10 +2,10 @@ package net.corda.netmap.simulation import net.corda.core.flows.FlowLogic import net.corda.core.identity.CordaX500Name +import net.corda.finance.utils.CityDatabase +import net.corda.finance.utils.WorldMapLocation import net.corda.core.internal.uncheckedCast import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.CityDatabase -import net.corda.core.node.WorldMapLocation import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.ServiceType import net.corda.core.utilities.ProgressTracker diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index 75b6b27a4d..0e79451095 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -17,11 +17,11 @@ import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.ServiceEntry -import net.corda.core.node.WorldMapLocation import net.corda.core.node.services.* import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.loggerFor +import net.corda.finance.utils.WorldMapLocation import net.corda.node.internal.AbstractNode import net.corda.node.internal.StartedNode import net.corda.node.services.config.NodeConfiguration diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt index e4f234fa10..90147c5b43 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt @@ -4,7 +4,7 @@ import javafx.beans.property.SimpleIntegerProperty import javafx.beans.property.SimpleListProperty import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleStringProperty -import net.corda.core.node.CityDatabase +import net.corda.finance.utils.CityDatabase import tornadofx.* object SuggestedDetails { diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt index 16fe779134..8f3ec2d19d 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt @@ -15,8 +15,8 @@ import javafx.scene.layout.Priority import javafx.stage.FileChooser import javafx.util.StringConverter import net.corda.core.internal.* -import net.corda.core.node.CityDatabase -import net.corda.core.node.WorldMapLocation +import net.corda.finance.utils.CityDatabase +import net.corda.finance.utils.WorldMapLocation import net.corda.demobench.model.* import net.corda.demobench.ui.CloseableTab import org.controlsfx.control.CheckListView diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index cada329cc1..c3bff3753e 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -28,13 +28,13 @@ import net.corda.client.jfx.model.* import net.corda.client.jfx.utils.* import net.corda.core.contracts.ContractState import net.corda.core.identity.Party -import net.corda.core.node.CityDatabase import net.corda.core.node.NodeInfo -import net.corda.core.node.ScreenCoordinate -import net.corda.core.node.WorldMapLocation import net.corda.core.utilities.toBase58String import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CordaView +import net.corda.finance.utils.CityDatabase +import net.corda.finance.utils.ScreenCoordinate +import net.corda.finance.utils.WorldMapLocation import tornadofx.* class Network : CordaView() { From 1d6bd85f8a7bc1de81bc6d208cc5a755cdc169f2 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Tue, 19 Sep 2017 17:36:53 +0100 Subject: [PATCH 010/230] Clean up to NotaryFlow API (#1554) --- .../kotlin/net/corda/core/flows/NotaryFlow.kt | 31 ++++++++++--------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt index 74d6b2562c..27d05add24 100644 --- a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt @@ -15,11 +15,12 @@ import net.corda.core.node.services.UniquenessProvider import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker +import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.unwrap import java.security.SignatureException import java.util.function.Predicate -object NotaryFlow { +class NotaryFlow { /** * A flow to be used by a party for obtaining signature(s) from a [NotaryService] ascertaining the transaction * time-window is correct and none of its inputs have been used in another completed transaction. @@ -42,14 +43,12 @@ object NotaryFlow { fun tracker() = ProgressTracker(REQUESTING, VALIDATING) } - lateinit var notaryParty: Party - @Suspendable @Throws(NotaryException::class) override fun call(): List { progressTracker.currentStep = REQUESTING - notaryParty = stx.notary ?: throw IllegalStateException("Transaction does not specify a Notary") + val notaryParty = stx.notary ?: throw IllegalStateException("Transaction does not specify a Notary") check(stx.inputs.all { stateRef -> serviceHub.loadState(stateRef).notary == notaryParty }) { "Input states must have the same Notary" } @@ -84,17 +83,28 @@ object NotaryFlow { } return response.unwrap { signatures -> - signatures.forEach { validateSignature(it, stx.id) } + signatures.forEach { validateSignature(it, stx.id, notaryParty) } signatures } } - private fun validateSignature(sig: TransactionSignature, txId: SecureHash) { + private fun validateSignature(sig: TransactionSignature, txId: SecureHash, notaryParty: Party) { check(sig.by in notaryParty.owningKey.keys) { "Invalid signer for the notary result" } sig.verify(txId) } } + /** + * The [SendTransactionWithRetry] flow is equivalent to [SendTransactionFlow] but using [sendAndReceiveWithRetry] + * instead of [sendAndReceive], [SendTransactionWithRetry] is intended to be use by the notary client only. + */ + private class SendTransactionWithRetry(otherSide: Party, stx: SignedTransaction) : SendTransactionFlow(otherSide, stx) { + @Suspendable + override fun sendPayloadAndReceiveDataRequest(otherSide: Party, payload: Any): UntrustworthyData { + return sendAndReceiveWithRetry(otherSide, payload) + } + } + /** * A flow run by a notary service that handles notarisation requests. * @@ -151,12 +161,3 @@ sealed class NotaryError { override fun toString() = cause.toString() } } - -/** - * The [SendTransactionWithRetry] flow is equivalent to [SendTransactionFlow] but using [sendAndReceiveWithRetry] - * instead of [sendAndReceive], [SendTransactionWithRetry] is intended to be use by the notary client only. - */ -private class SendTransactionWithRetry(otherSide: Party, stx: SignedTransaction) : SendTransactionFlow(otherSide, stx) { - @Suspendable - override fun sendPayloadAndReceiveDataRequest(otherSide: Party, payload: Any) = sendAndReceiveWithRetry(otherSide, payload) -} \ No newline at end of file From 49a70cdbd6947a3ea126cbc556aa1a82dfea5524 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Tue, 19 Sep 2017 17:50:04 +0100 Subject: [PATCH 011/230] CORDA-579: Add EdDSA engine that understands X.509 keys (#1540) * Add EdDSA engine that understands X.509 keys * Add test for Certificate serialization * Address PR comments from Kostas --- .../kotlin/net/corda/core/crypto/Crypto.kt | 9 ++-- .../net/i2p/crypto/eddsa/X509EdDSAEngine.kt | 48 +++++++++++++++++++ .../core/identity/PartyAndCertificateTest.kt | 27 +++++++++++ 3 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt diff --git a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt index 3f1f4fa08e..ab6ea15722 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt @@ -1,10 +1,7 @@ package net.corda.core.crypto import net.corda.core.serialization.serialize -import net.i2p.crypto.eddsa.EdDSAEngine -import net.i2p.crypto.eddsa.EdDSAPrivateKey -import net.i2p.crypto.eddsa.EdDSAPublicKey -import net.i2p.crypto.eddsa.EdDSASecurityProvider +import net.i2p.crypto.eddsa.* import net.i2p.crypto.eddsa.math.GroupElement import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec import net.i2p.crypto.eddsa.spec.EdDSANamedCurveTable @@ -41,6 +38,8 @@ import org.bouncycastle.pqc.jcajce.provider.sphincs.BCSphincs256PublicKey import org.bouncycastle.pqc.jcajce.spec.SPHINCS256KeyGenParameterSpec import java.math.BigInteger import java.security.* +import java.security.KeyFactory +import java.security.KeyPairGenerator import java.security.spec.InvalidKeySpecException import java.security.spec.PKCS8EncodedKeySpec import java.security.spec.X509EncodedKeySpec @@ -200,6 +199,8 @@ object Crypto { private fun getBouncyCastleProvider() = BouncyCastleProvider().apply { putAll(EdDSASecurityProvider()) + // Override the normal EdDSA engine with one which can handle X509 keys. + put("Signature.${EdDSAEngine.SIGNATURE_ALGORITHM}", X509EdDSAEngine::class.qualifiedName) addKeyInfoConverter(EDDSA_ED25519_SHA512.signatureOID.algorithm, KeyInfoConverter(EDDSA_ED25519_SHA512)) } diff --git a/core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt b/core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt new file mode 100644 index 0000000000..9ce017a484 --- /dev/null +++ b/core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt @@ -0,0 +1,48 @@ +package net.i2p.crypto.eddsa + +import java.security.* +import java.security.spec.AlgorithmParameterSpec +import java.security.spec.X509EncodedKeySpec + +/** + * Wrapper around [EdDSAEngine] which can intelligently rewrite X509Keys to a [EdDSAPublicKey]. This is a temporary + * solution until this is integrated upstream and/or a custom certificate factory implemented to force the correct + * key type. Only intercepts public keys passed into [engineInitVerify], as there is no equivalent issue with private + * keys. + */ +class X509EdDSAEngine : Signature { + private val engine: EdDSAEngine + + constructor() : super(EdDSAEngine.SIGNATURE_ALGORITHM) { + engine = EdDSAEngine() + } + constructor(digest: MessageDigest) : super(EdDSAEngine.SIGNATURE_ALGORITHM) { + engine = EdDSAEngine(digest) + } + + override fun engineInitSign(privateKey: PrivateKey) = engine.engineInitSign(privateKey) + override fun engineInitVerify(publicKey: PublicKey) { + val parsedKey = if (publicKey is sun.security.x509.X509Key) { + EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded)) + } else { + publicKey + } + engine.engineInitVerify(parsedKey) + } + + override fun engineVerify(sigBytes: ByteArray): Boolean = engine.engineVerify(sigBytes) + override fun engineSign(): ByteArray = engine.engineSign() + override fun engineUpdate(b: Byte) = engine.engineUpdate(b) + override fun engineUpdate(b: ByteArray, off: Int, len: Int) = engine.engineUpdate(b, off, len) + override fun engineGetParameters(): AlgorithmParameters { + val method = engine.javaClass.getMethod("engineGetParameters") + return method.invoke(engine) as AlgorithmParameters + } + override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params) + override fun engineGetParameter(param: String): Any = engine.engineGetParameter(param) + override fun engineSetParameter(param: String, value: Any?) = engine.engineSetParameter(param, value) + override fun engineInitSign(privateKey: PrivateKey, random: SecureRandom) { + val method = engine.javaClass.getMethod("engineInitSign", PrivateKey::class.java, SecureRandom::class.java) + method.invoke(engine, privateKey, random) + } +} diff --git a/core/src/test/kotlin/net/corda/core/identity/PartyAndCertificateTest.kt b/core/src/test/kotlin/net/corda/core/identity/PartyAndCertificateTest.kt index 0b2c8ef51c..a9198b26e7 100644 --- a/core/src/test/kotlin/net/corda/core/identity/PartyAndCertificateTest.kt +++ b/core/src/test/kotlin/net/corda/core/identity/PartyAndCertificateTest.kt @@ -1,13 +1,18 @@ package net.corda.core.identity import net.corda.core.crypto.entropyToKeyPair +import net.corda.core.internal.read import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize +import net.corda.node.utilities.KEYSTORE_TYPE +import net.corda.node.utilities.save import net.corda.testing.getTestPartyAndCertificate import net.corda.testing.withTestSerialization import org.assertj.core.api.Assertions.assertThat import org.junit.Test +import java.io.File import java.math.BigInteger +import java.security.KeyStore class PartyAndCertificateTest { @Test @@ -22,4 +27,26 @@ class PartyAndCertificateTest { assertThat(copy.certificate).isEqualTo(original.certificate) } } + + @Test + fun `jdk serialization`() { + withTestSerialization { + val identity = getTestPartyAndCertificate(Party( + CordaX500Name(organisation = "Test Corp", locality = "Madrid", country = "ES"), + entropyToKeyPair(BigInteger.valueOf(83)).public)) + val original = identity.certificate + val storePassword = "test" + val keyStoreFilePath = File.createTempFile("serialization_test", "jks").toPath() + var keyStore = KeyStore.getInstance(KEYSTORE_TYPE) + keyStore.load(null, storePassword.toCharArray()) + keyStore.setCertificateEntry(identity.name.toString(), original) + keyStore.save(keyStoreFilePath, storePassword) + + // Load the key store back in again + keyStore = KeyStore.getInstance(KEYSTORE_TYPE) + keyStoreFilePath.read { keyStore.load(it, storePassword.toCharArray()) } + val copy = keyStore.getCertificate(identity.name.toString()) + assertThat(copy).isEqualTo(original) // .isNotSameAs(original) + } + } } From 477ea3a5e1482ddcfbbcc8fc917a9056ca42d265 Mon Sep 17 00:00:00 2001 From: Rick Parker Date: Tue, 19 Sep 2017 18:29:34 +0100 Subject: [PATCH 012/230] Fix serialization of ServiceHub (#1559) --- .../main/kotlin/net/corda/node/internal/AbstractNode.kt | 5 ++++- .../node/services/upgrade/ContractUpgradeServiceImpl.kt | 8 ++++++-- .../net/corda/node/messaging/TwoPartyTradeFlowTests.kt | 3 ++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index d6f43541fa..665194e27e 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -387,7 +387,10 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, info = makeInfo(legalIdentity) val tokenizableServices = mutableListOf(attachments, network, services.vaultService, services.vaultQueryService, - services.keyManagementService, services.identityService, platformClock, services.schedulerService) + services.keyManagementService, services.identityService, platformClock, services.schedulerService, + services.auditService, services.monitoringService, services.networkMapCache, services.schemaService, + services.transactionVerifierService, services.validatedTransactions, services.contractUpgradeService, + services, this) makeAdvertisedServices(tokenizableServices) return tokenizableServices } diff --git a/node/src/main/kotlin/net/corda/node/services/upgrade/ContractUpgradeServiceImpl.kt b/node/src/main/kotlin/net/corda/node/services/upgrade/ContractUpgradeServiceImpl.kt index 61501fac22..506160a6e9 100644 --- a/node/src/main/kotlin/net/corda/node/services/upgrade/ContractUpgradeServiceImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/upgrade/ContractUpgradeServiceImpl.kt @@ -3,11 +3,15 @@ package net.corda.node.services.upgrade import net.corda.core.contracts.StateRef import net.corda.core.contracts.UpgradedContract import net.corda.core.node.services.ContractUpgradeService +import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.PersistentMap -import javax.persistence.* +import javax.persistence.Column +import javax.persistence.Entity +import javax.persistence.Id +import javax.persistence.Table -class ContractUpgradeServiceImpl : ContractUpgradeService { +class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsToken() { @Entity @Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades") diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index c47cb53174..69f687d066 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -22,6 +22,7 @@ import net.corda.core.node.NodeInfo import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.serialization.CordaSerializable +import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.toFuture import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder @@ -734,7 +735,7 @@ class TwoPartyTradeFlowTests { } - class RecordingTransactionStorage(val database: CordaPersistence, val delegate: WritableTransactionStorage) : WritableTransactionStorage { + class RecordingTransactionStorage(val database: CordaPersistence, val delegate: WritableTransactionStorage) : WritableTransactionStorage, SingletonSerializeAsToken() { override fun track(): DataFeed, SignedTransaction> { return database.transaction { delegate.track() From 6887947a4d87228bf06bedea0a6688966de81ad0 Mon Sep 17 00:00:00 2001 From: Konstantinos Chalkias Date: Wed, 20 Sep 2017 13:11:58 +0100 Subject: [PATCH 013/230] CORDA-521: Backwards compatible Transactions using sub-Merkle trees (#1481) * tx backwards compatibility + rebase * SHA256d definition --- .../core/contracts/ComponentGroupEnum.kt | 14 + .../net/corda/core/contracts/Structures.kt | 4 +- .../net/corda/core/crypto/CryptoUtils.kt | 28 ++ .../corda/core/crypto/PartialMerkleTree.kt | 43 +- .../net/corda/core/crypto/SecureHash.kt | 1 + .../MissingAttachmentsException.kt | 2 +- .../core/transactions/MerkleTransaction.kt | 417 ++++++++++-------- .../transactions/NotaryChangeTransactions.kt | 1 + .../core/transactions/TransactionBuilder.kt | 12 +- .../core/transactions/WireTransaction.kt | 159 ++++++- .../contracts/CompatibleTransactionTests.kt | 251 +++++++++++ .../core/contracts/DummyContractV2Tests.kt | 3 +- .../core/crypto/PartialMerkleTreeTest.kt | 58 +-- docs/source/changelog.rst | 34 ++ .../nodeapi/internal/serialization/Kryo.kt | 49 +- .../nodeapi/AttachmentsClassLoaderTests.kt | 75 ++-- .../BFTNonValidatingNotaryService.kt | 4 +- .../transactions/NonValidatingNotaryFlow.kt | 5 +- .../net/corda/irs/api/NodeInterestRates.kt | 9 +- .../corda/irs/api/NodeInterestRatesTest.kt | 2 +- 20 files changed, 804 insertions(+), 367 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/contracts/ComponentGroupEnum.kt create mode 100644 core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt diff --git a/core/src/main/kotlin/net/corda/core/contracts/ComponentGroupEnum.kt b/core/src/main/kotlin/net/corda/core/contracts/ComponentGroupEnum.kt new file mode 100644 index 0000000000..c32792a998 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/contracts/ComponentGroupEnum.kt @@ -0,0 +1,14 @@ +package net.corda.core.contracts + +/** + * An enum, for which each property corresponds to a transaction component group. The position in the enum class + * declaration (ordinal) is used for component-leaf ordering when computing the Merkle tree. + */ +enum class ComponentGroupEnum { + INPUTS_GROUP, // ordinal = 0. + OUTPUTS_GROUP, // ordinal = 1. + COMMANDS_GROUP, // ordinal = 2. + ATTACHMENTS_GROUP, // ordinal = 3. + NOTARY_GROUP, // ordinal = 4. + TIMEWINDOW_GROUP // ordinal = 5. +} diff --git a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt index 9c93fa26d3..dfad6a6e89 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt @@ -271,7 +271,7 @@ class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) { init { require(bytes.size == 32) { "Privacy salt should be 32 bytes." } - require(!bytes.all { it == 0.toByte() }) { "Privacy salt should not be all zeros." } + require(bytes.any { it != 0.toByte() }) { "Privacy salt should not be all zeros." } } } @@ -281,4 +281,4 @@ class PrivacySalt(bytes: ByteArray) : OpaqueBytes(bytes) { * @property state A state * @property contract The contract that should verify the state */ -data class StateAndContract(val state: ContractState, val contract: ContractClassName) \ No newline at end of file +data class StateAndContract(val state: ContractState, val contract: ContractClassName) diff --git a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt index 922359ca58..2dffd5afda 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CryptoUtils.kt @@ -2,10 +2,14 @@ package net.corda.core.crypto +import net.corda.core.contracts.PrivacySalt +import net.corda.core.serialization.SerializationDefaults +import net.corda.core.serialization.serialize import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.toBase58 import net.corda.core.utilities.toSHA256Bytes import java.math.BigInteger +import java.nio.ByteBuffer import java.security.* /** @@ -184,3 +188,27 @@ fun random63BitValue(): Long { } } } + +/** + * Compute the hash of each serialised component so as to be used as Merkle tree leaf. The resultant output (leaf) is + * calculated using the SHA256d algorithm, thus SHA256(SHA256(nonce || serializedComponent)), where nonce is computed + * from [computeNonce]. + */ +fun componentHash(opaqueBytes: OpaqueBytes, privacySalt: PrivacySalt, componentGroupIndex: Int, internalIndex: Int): SecureHash = + componentHash(computeNonce(privacySalt, componentGroupIndex, internalIndex), opaqueBytes) + +/** Return the SHA256(SHA256(nonce || serializedComponent)). */ +fun componentHash(nonce: SecureHash, opaqueBytes: OpaqueBytes): SecureHash = SecureHash.sha256Twice(nonce.bytes + opaqueBytes.bytes) + +/** Serialise the object and return the hash of the serialized bytes. */ +fun serializedHash(x: T): SecureHash = x.serialize(context = SerializationDefaults.P2P_CONTEXT.withoutReferences()).bytes.sha256() + +/** + * Method to compute a nonce based on privacySalt, component group index and component internal index. + * SHA256d (double SHA256) is used to prevent length extension attacks. + * @param privacySalt a [PrivacySalt]. + * @param groupIndex the fixed index (ordinal) of this component group. + * @param internalIndex the internal index of this object in its corresponding components list. + * @return SHA256(SHA256(privacySalt || groupIndex || internalIndex)) + */ +fun computeNonce(privacySalt: PrivacySalt, groupIndex: Int, internalIndex: Int) = SecureHash.sha256Twice(privacySalt.bytes + ByteBuffer.allocate(8).putInt(groupIndex).putInt(internalIndex).array()) diff --git a/core/src/main/kotlin/net/corda/core/crypto/PartialMerkleTree.kt b/core/src/main/kotlin/net/corda/core/crypto/PartialMerkleTree.kt index a8ac0356be..0011198d75 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/PartialMerkleTree.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/PartialMerkleTree.kt @@ -121,6 +121,28 @@ class PartialMerkleTree(val root: PartialTree) { } } } + + /** + * Recursive calculation of root of this partial tree. + * Modifies usedHashes to later check for inclusion with hashes provided. + * @param node the partial Merkle tree for which we want to calculate the Merkle root. + * @param usedHashes a mutable list that at the end of this recursive algorithm, it will consist of the included leaves (hashes of the visible components). + * @return the root [SecureHash] of this partial Merkle tree. + */ + fun rootAndUsedHashes(node: PartialTree, usedHashes: MutableList): SecureHash { + return when (node) { + is PartialTree.IncludedLeaf -> { + usedHashes.add(node.hash) + node.hash + } + is PartialTree.Leaf -> node.hash + is PartialTree.Node -> { + val leftHash = rootAndUsedHashes(node.left, usedHashes) + val rightHash = rootAndUsedHashes(node.right, usedHashes) + return leftHash.hashConcat(rightHash) + } + } + } } /** @@ -129,29 +151,10 @@ class PartialMerkleTree(val root: PartialTree) { */ fun verify(merkleRootHash: SecureHash, hashesToCheck: List): Boolean { val usedHashes = ArrayList() - val verifyRoot = verify(root, usedHashes) + val verifyRoot = rootAndUsedHashes(root, usedHashes) // It means that we obtained more/fewer hashes than needed or different sets of hashes. if (hashesToCheck.groupBy { it } != usedHashes.groupBy { it }) return false return (verifyRoot == merkleRootHash) } - - /** - * Recursive calculation of root of this partial tree. - * Modifies usedHashes to later check for inclusion with hashes provided. - */ - private fun verify(node: PartialTree, usedHashes: MutableList): SecureHash { - return when (node) { - is PartialTree.IncludedLeaf -> { - usedHashes.add(node.hash) - node.hash - } - is PartialTree.Leaf -> node.hash - is PartialTree.Node -> { - val leftHash = verify(node.left, usedHashes) - val rightHash = verify(node.right, usedHashes) - return leftHash.hashConcat(rightHash) - } - } - } } diff --git a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt index 837f27faea..f0773a7bac 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/SecureHash.kt @@ -40,6 +40,7 @@ sealed class SecureHash(bytes: ByteArray) : OpaqueBytes(bytes) { @JvmStatic fun randomSHA256() = sha256(newSecureRandom().generateSeed(32)) val zeroHash = SecureHash.SHA256(ByteArray(32, { 0.toByte() })) + val allOnesHash = SecureHash.SHA256(ByteArray(32, { 255.toByte() })) } // In future, maybe SHA3, truncated hashes etc. diff --git a/core/src/main/kotlin/net/corda/core/serialization/MissingAttachmentsException.kt b/core/src/main/kotlin/net/corda/core/serialization/MissingAttachmentsException.kt index 2094f1aeff..08a920ab63 100644 --- a/core/src/main/kotlin/net/corda/core/serialization/MissingAttachmentsException.kt +++ b/core/src/main/kotlin/net/corda/core/serialization/MissingAttachmentsException.kt @@ -2,6 +2,6 @@ package net.corda.core.serialization import net.corda.core.crypto.SecureHash -/** Thrown during deserialisation to indicate that an attachment needed to construct the [WireTransaction] is not found */ +/** Thrown during deserialisation to indicate that an attachment needed to construct the [WireTransaction] is not found. */ @CordaSerializable class MissingAttachmentsException(val ids: List) : Exception() \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt index b23800baec..ea99e30811 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt @@ -3,121 +3,190 @@ package net.corda.core.transactions import net.corda.core.contracts.* import net.corda.core.crypto.* import net.corda.core.identity.Party -import net.corda.core.serialization.CordaSerializable -import net.corda.core.serialization.SerializationFactory -import net.corda.core.serialization.serialize -import java.nio.ByteBuffer +import net.corda.core.serialization.* +import net.corda.core.utilities.OpaqueBytes +import java.security.PublicKey import java.util.function.Predicate /** - * If a privacy salt is provided, the resulted output (Merkle-leaf) is computed as - * Hash(serializedObject || Hash(privacy_salt || obj_index_in_merkle_tree)). - */ -fun serializedHash(x: T, privacySalt: PrivacySalt?, index: Int): SecureHash { - return if (privacySalt != null) - serializedHash(x, computeNonce(privacySalt, index)) - else - serializedHash(x) -} - -fun serializedHash(x: T, nonce: SecureHash): SecureHash { - return if (x !is PrivacySalt) // PrivacySalt is not required to have an accompanied nonce. - (x.serialize(context = SerializationFactory.defaultFactory.defaultContext.withoutReferences()).bytes + nonce.bytes).sha256() - else - serializedHash(x) -} - -fun serializedHash(x: T): SecureHash = x.serialize(context = SerializationFactory.defaultFactory.defaultContext.withoutReferences()).bytes.sha256() - -/** The nonce is computed as Hash(privacySalt || index). */ -fun computeNonce(privacySalt: PrivacySalt, index: Int) = (privacySalt.bytes + ByteBuffer.allocate(4).putInt(index).array()).sha256() - -/** - * Implemented by [WireTransaction] and [FilteredLeaves]. A TraversableTransaction allows you to iterate + * Implemented by [WireTransaction] and [FilteredTransaction]. A TraversableTransaction allows you to iterate * over the flattened components of the underlying transaction structure, taking into account that some * may be missing in the case of this representing a "torn" transaction. Please see the user guide section * "Transaction tear-offs" to learn more about this feature. - * - * The [availableComponents] property is used for calculation of the transaction's [MerkleTree], which is in - * turn used to derive the ID hash. */ -interface TraversableTransaction { - val inputs: List - val attachments: List - val outputs: List> - val commands: List> - val notary: Party? - val timeWindow: TimeWindow? - /** - * For privacy purposes, each part of a transaction should be accompanied by a nonce. - * To avoid storing a random number (nonce) per component, an initial "salt" is the sole value utilised, - * so that all component nonces are deterministically computed in the following way: - * nonce1 = H(salt || 1) - * nonce2 = H(salt || 2) - * - * Thus, all of the nonces are "independent" in the sense that knowing one or some of them, you can learn - * nothing about the rest. - */ - val privacySalt: PrivacySalt? +abstract class TraversableTransaction(open val componentGroups: List) : CoreTransaction() { + /** Hashes of the ZIP/JAR files that are needed to interpret the contents of this wire transaction. */ + val attachments: List = deserialiseComponentGroup(ComponentGroupEnum.ATTACHMENTS_GROUP, { SerializedBytes(it).deserialize() }) + + /** Pointers to the input states on the ledger, identified by (tx identity hash, output index). */ + override val inputs: List = deserialiseComponentGroup(ComponentGroupEnum.INPUTS_GROUP, { SerializedBytes(it).deserialize() }) + + override val outputs: List> = deserialiseComponentGroup(ComponentGroupEnum.OUTPUTS_GROUP, { SerializedBytes>(it).deserialize(context = SerializationFactory.defaultFactory.defaultContext.withAttachmentsClassLoader(attachments)) }) + + /** Ordered list of ([CommandData], [PublicKey]) pairs that instruct the contracts what to do. */ + val commands: List> = deserialiseComponentGroup(ComponentGroupEnum.COMMANDS_GROUP, { SerializedBytes>(it).deserialize(context = SerializationFactory.defaultFactory.defaultContext.withAttachmentsClassLoader(attachments)) }) + + override val notary: Party? = let { + val notaries: List = deserialiseComponentGroup(ComponentGroupEnum.NOTARY_GROUP, { SerializedBytes(it).deserialize() }) + check(notaries.size <= 1) { "Invalid Transaction. More than 1 notary party detected." } + if (notaries.isNotEmpty()) notaries[0] else null + } + + val timeWindow: TimeWindow? = let { + val timeWindows: List = deserialiseComponentGroup(ComponentGroupEnum.TIMEWINDOW_GROUP, { SerializedBytes(it).deserialize() }) + check(timeWindows.size <= 1) { "Invalid Transaction. More than 1 time-window detected." } + if (timeWindows.isNotEmpty()) timeWindows[0] else null + } /** - * Returns a flattened list of all the components that are present in the transaction, in the following order: - * - * - Each input that is present - * - Each attachment that is present - * - Each output that is present - * - Each command that is present - * - The notary [Party], if present - * - The time-window of the transaction, if present - * - The privacy salt required for nonces, always presented in [WireTransaction] and always null in [FilteredLeaves] - */ - val availableComponents: List - // NOTE: if the order below is altered or components are added/removed in the future, one should also reflect - // this change to the indexOffsets() method in WireTransaction. + * Returns a list of all the component groups that are present in the transaction, excluding the privacySalt, + * in the following order (which is the same with the order in [ComponentGroupEnum]: + * - list of each input that is present + * - list of each output that is present + * - list of each command that is present + * - list of each attachment that is present + * - The notary [Party], if present (list with one element) + * - The time-window of the transaction, if present (list with one element) + */ + val availableComponentGroups: List> get() { - // We may want to specify our own behaviour on certain tx fields. - // Like if we include them at all, what to do with null values, if we treat list as one or not etc. for building - // torn-off transaction and id calculation. - val result = mutableListOf(inputs, attachments, outputs, commands).flatten().toMutableList() - notary?.let { result += it } - timeWindow?.let { result += it } - privacySalt?.let { result += it } + val result = mutableListOf(inputs, outputs, commands, attachments) + notary?.let { result += listOf(it) } + timeWindow?.let { result += listOf(it) } return result } - /** - * Calculate the hashes of the sub-components of the transaction, that are used to build its Merkle tree. - * The root of the tree is the transaction identifier. The tree structure is helpful for privacy, please - * see the user-guide section "Transaction tear-offs" to learn more about this topic. - */ - val availableComponentHashes: List get() = availableComponents.mapIndexed { index, it -> serializedHash(it, privacySalt, index) } + // Helper function to return a meaningful exception if deserialisation of a component fails. + private fun deserialiseComponentGroup(groupEnum: ComponentGroupEnum, deserialiseBody: (ByteArray) -> T): List { + val group = componentGroups.firstOrNull { it.groupIndex == groupEnum.ordinal } + return if (group != null && group.components.isNotEmpty()) { + group.components.mapIndexed { internalIndex, component -> + try { + deserialiseBody(component.bytes) + } catch (e: MissingAttachmentsException) { + throw e + } catch (e: Exception) { + throw Exception("Malformed transaction, $groupEnum at index $internalIndex cannot be deserialised", e) + } + } + } else { + emptyList() + } + } } /** - * Class that holds filtered leaves for a partial Merkle transaction. We assume mixed leaf types, notice that every - * field from [WireTransaction] can be used in [PartialMerkleTree] calculation, except for the privacySalt. - * A list of nonces is also required to (re)construct component hashes. + * Class representing merkleized filtered transaction. + * @param id Merkle tree root hash. + * @param filteredComponentGroups list of transaction components groups remained after filters are applied to [WireTransaction]. + * @param groupHashes the roots of the transaction component groups. */ @CordaSerializable -class FilteredLeaves( - override val inputs: List, - override val attachments: List, - override val outputs: List>, - override val commands: List>, - override val notary: Party?, - override val timeWindow: TimeWindow?, - val nonces: List -) : TraversableTransaction { +class FilteredTransaction private constructor( + override val id: SecureHash, + val filteredComponentGroups: List, + val groupHashes: List +) : TraversableTransaction(filteredComponentGroups) { + + companion object { + /** + * Construction of filtered transaction with partial Merkle tree. + * @param wtx WireTransaction to be filtered. + * @param filtering filtering over the whole WireTransaction. + */ + @JvmStatic + fun buildFilteredTransaction(wtx: WireTransaction, filtering: Predicate): FilteredTransaction { + val filteredComponentGroups = filterWithFun(wtx, filtering) + return FilteredTransaction(wtx.id, filteredComponentGroups, wtx.groupHashes) + } + + /** + * Construction of partial transaction from [WireTransaction] based on filtering. + * Note that list of nonces to be sent is updated on the fly, based on the index of the filtered tx component. + * @param filtering filtering over the whole WireTransaction. + * @returns a list of [FilteredComponentGroup] used in PartialMerkleTree calculation and verification. + */ + private fun filterWithFun(wtx: WireTransaction, filtering: Predicate): List { + val filteredSerialisedComponents: MutableMap> = hashMapOf() + val filteredComponentNonces: MutableMap> = hashMapOf() + val filteredComponentHashes: MutableMap> = hashMapOf() // Required for partial Merkle tree generation. + + fun filter(t: T, componentGroupIndex: Int, internalIndex: Int) { + if (filtering.test(t)) { + val group = filteredSerialisedComponents[componentGroupIndex] + // Because the filter passed, we know there is a match. We also use first vs single as the init function + // of WireTransaction ensures there are no duplicated groups. + val serialisedComponent = wtx.componentGroups.first { it.groupIndex == componentGroupIndex }.components[internalIndex] + if (group == null) { + // As all of the helper Map structures, like availableComponentNonces, availableComponentHashes + // and groupsMerkleRoots, are computed lazily via componentGroups.forEach, there should always be + // a match on Map.get ensuring it will never return null. + filteredSerialisedComponents.put(componentGroupIndex, mutableListOf(serialisedComponent)) + filteredComponentNonces.put(componentGroupIndex, mutableListOf(wtx.availableComponentNonces[componentGroupIndex]!![internalIndex])) + filteredComponentHashes.put(componentGroupIndex, mutableListOf(wtx.availableComponentHashes[componentGroupIndex]!![internalIndex])) + } else { + group.add(serialisedComponent) + // If the group[componentGroupIndex] existed, then we guarantee that + // filteredComponentNonces[componentGroupIndex] and filteredComponentHashes[componentGroupIndex] are not null. + filteredComponentNonces[componentGroupIndex]!!.add(wtx.availableComponentNonces[componentGroupIndex]!![internalIndex]) + filteredComponentHashes[componentGroupIndex]!!.add(wtx.availableComponentHashes[componentGroupIndex]!![internalIndex]) + } + } + } + + fun updateFilteredComponents() { + wtx.inputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.INPUTS_GROUP.ordinal, internalIndex) } + wtx.outputs.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.OUTPUTS_GROUP.ordinal, internalIndex) } + wtx.commands.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.COMMANDS_GROUP.ordinal, internalIndex) } + wtx.attachments.forEachIndexed { internalIndex, it -> filter(it, ComponentGroupEnum.ATTACHMENTS_GROUP.ordinal, internalIndex) } + if (wtx.notary != null) filter(wtx.notary, ComponentGroupEnum.NOTARY_GROUP.ordinal, 0) + if (wtx.timeWindow != null) filter(wtx.timeWindow, ComponentGroupEnum.TIMEWINDOW_GROUP.ordinal, 0) + + // It's sometimes possible that when we receive a WireTransaction for which there is a new or more unknown component groups, + // we decide to filter and attach this field to a FilteredTransaction. + // An example would be to redact certain contract state types, but otherwise leave a transaction alone, + // including the unknown new components. + wtx.componentGroups.filter { it.groupIndex >= ComponentGroupEnum.values().size }.forEach { componentGroup -> componentGroup.components.forEachIndexed { internalIndex, component-> filter(component, componentGroup.groupIndex, internalIndex) }} + } + + fun createPartialMerkleTree(componentGroupIndex: Int) = PartialMerkleTree.build(MerkleTree.getMerkleTree(wtx.availableComponentHashes[componentGroupIndex]!!), filteredComponentHashes[componentGroupIndex]!!) + + fun createFilteredComponentGroups(): List { + updateFilteredComponents() + val filteredComponentGroups: MutableList = mutableListOf() + filteredSerialisedComponents.forEach { (groupIndex, value) -> + filteredComponentGroups.add(FilteredComponentGroup(groupIndex, value, filteredComponentNonces[groupIndex]!!, createPartialMerkleTree(groupIndex) )) + } + return filteredComponentGroups + } + + return createFilteredComponentGroups() + } + } /** - * PrivacySalt should be always null for FilteredLeaves, because making it accidentally visible would expose all - * nonces (including filtered out components) causing privacy issues, see [serializedHash] and - * [TraversableTransaction.privacySalt]. + * Runs verification of partial Merkle branch against [id]. + * Note that empty filtered transactions (with no component groups) are accepted as well, + * e.g. for Timestamp Authorities to blindly sign or any other similar case in the future + * that requires a blind signature over a transaction's [id]. + * @throws FilteredTransactionVerificationException if verification fails. */ - override val privacySalt: PrivacySalt? get() = null + @Throws(FilteredTransactionVerificationException::class) + fun verify() { + verificationCheck(groupHashes.isNotEmpty()) { "At least one component group hash is required" } + // Verify the top level Merkle tree (group hashes are its leaves, including allOnesHash for empty list or null components in WireTransaction). + verificationCheck(MerkleTree.getMerkleTree(groupHashes).hash == id) { "Top level Merkle tree cannot be verified against transaction's id" } - init { - require(availableComponents.size == nonces.size) { "Each visible component should be accompanied by a nonce." } + // For completely blind verification (no components are included). + if (filteredComponentGroups.isEmpty()) return + + // Compute partial Merkle roots for each filtered component and verify each of the partial Merkle trees. + filteredComponentGroups.forEach { (groupIndex, components, nonces, groupPartialTree) -> + verificationCheck(groupIndex < groupHashes.size ) { "There is no matching component group hash for group $groupIndex" } + val groupMerkleRoot = groupHashes[groupIndex] + verificationCheck(groupMerkleRoot == PartialMerkleTree.rootAndUsedHashes(groupPartialTree.root, mutableListOf())) { "Partial Merkle tree root and advertised full Merkle tree root for component group $groupIndex do not match" } + verificationCheck(groupPartialTree.verify(groupMerkleRoot, components.mapIndexed { index, component -> componentHash(nonces[index], component) })) { "Visible components in group $groupIndex cannot be verified against their partial Merkle tree" } + } } /** @@ -130,113 +199,75 @@ class FilteredLeaves( * @returns false if no elements were matched on a structure or checkingFun returned false. */ fun checkWithFun(checkingFun: (Any) -> Boolean): Boolean { - val checkList = availableComponents.map { checkingFun(it) } + val checkList = availableComponentGroups.flatten().map { checkingFun(it) } return (!checkList.isEmpty()) && checkList.all { it } } - override val availableComponentHashes: List get() = availableComponents.mapIndexed { index, it -> serializedHash(it, nonces[index]) } + /** + * Function that checks if all of the components in a particular group are visible. + * This functionality is required on non-Validating Notaries to check that all inputs are visible. + * It might also be applied in Oracles, where an Oracle should know it can see all commands. + * The logic behind this algorithm is that we check that the root of the provided group partialMerkleTree matches with the + * root of a fullMerkleTree if computed using all visible components. + * Note that this method is usually called after or before [verify], to also ensure that the provided partial Merkle + * tree corresponds to the correct leaf in the top Merkle tree. + * @param componentGroupEnum the [ComponentGroupEnum] that corresponds to the componentGroup for which we require full component visibility. + * @throws ComponentVisibilityException if not all of the components are visible or if the component group is not present in the [FilteredTransaction]. + */ + @Throws(ComponentVisibilityException::class) + fun checkAllComponentsVisible(componentGroupEnum: ComponentGroupEnum) { + val group = filteredComponentGroups.firstOrNull { it.groupIndex == componentGroupEnum.ordinal } + if (group == null) { + // If we don't receive elements of a particular component, check if its ordinal is bigger that the + // groupHashes.size or if the group hash is allOnesHash, + // to ensure there were indeed no elements in the original wire transaction. + visibilityCheck(componentGroupEnum.ordinal >= groupHashes.size || groupHashes[componentGroupEnum.ordinal] == SecureHash.allOnesHash) { + "Did not receive components for group ${componentGroupEnum.ordinal} and cannot verify they didn't exist in the original wire transaction" + } + } else { + visibilityCheck(group.groupIndex < groupHashes.size ) { "There is no matching component group hash for group ${group.groupIndex}" } + val groupPartialRoot = groupHashes[group.groupIndex] + val groupFullRoot = MerkleTree.getMerkleTree(group.components.mapIndexed { index, component -> componentHash(group.nonces[index], component) }).hash + visibilityCheck(groupPartialRoot == groupFullRoot) { "The partial Merkle tree root does not match with the received root for group ${group.groupIndex}" } + } + } + + inline private fun verificationCheck(value: Boolean, lazyMessage: () -> Any): Unit { + if (!value) { + val message = lazyMessage() + throw FilteredTransactionVerificationException(id, message.toString()) + } + } + + inline private fun visibilityCheck(value: Boolean, lazyMessage: () -> Any): Unit { + if (!value) { + val message = lazyMessage() + throw ComponentVisibilityException(id, message.toString()) + } + } } /** - * Class representing merkleized filtered transaction. - * @param id Merkle tree root hash. - * @param filteredLeaves Leaves included in a filtered transaction. - * @param partialMerkleTree Merkle branch needed to verify filteredLeaves. + * A FilteredComponentGroup is used to store the filtered list of transaction components of the same type in serialised form. + * This is similar to [ComponentGroup], but it also includes the corresponding nonce per component. */ @CordaSerializable -class FilteredTransaction private constructor( - val id: SecureHash, - val filteredLeaves: FilteredLeaves, - val partialMerkleTree: PartialMerkleTree -) { - companion object { - /** - * Construction of filtered transaction with Partial Merkle Tree. - * @param wtx WireTransaction to be filtered. - * @param filtering filtering over the whole WireTransaction - */ - @JvmStatic - fun buildMerkleTransaction(wtx: WireTransaction, - filtering: Predicate - ): FilteredTransaction { - val filteredLeaves = filterWithFun(wtx, filtering) - val merkleTree = wtx.merkleTree - val pmt = PartialMerkleTree.build(merkleTree, filteredLeaves.availableComponentHashes) - return FilteredTransaction(merkleTree.hash, filteredLeaves, pmt) - } - - /** - * Construction of partial transaction from WireTransaction based on filtering. - * Note that list of nonces to be sent is updated on the fly, based on the index of the filtered tx component. - * @param filtering filtering over the whole WireTransaction - * @returns FilteredLeaves used in PartialMerkleTree calculation and verification. - */ - private fun filterWithFun(wtx: WireTransaction, filtering: Predicate): FilteredLeaves { - val nonces: MutableList = mutableListOf() - val offsets = indexOffsets(wtx) - fun notNullFalseAndNoncesUpdate(elem: Any?, index: Int): Any? { - return if (elem == null || !filtering.test(elem)) { - null - } else { - nonces.add(computeNonce(wtx.privacySalt, index)) - elem - } - } - - fun filterAndNoncesUpdate(t: T, index: Int): Boolean { - return if (filtering.test(t)) { - nonces.add(computeNonce(wtx.privacySalt, index)) - true - } else { - false - } - } - - // TODO: We should have a warning (require) if all leaves (excluding salt) are visible after filtering. - // Consider the above after refactoring FilteredTransaction to implement TraversableTransaction, - // so that a WireTransaction can be used when required to send a full tx (e.g. RatesFixFlow in Oracles). - return FilteredLeaves( - wtx.inputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index) }, - wtx.attachments.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[0]) }, - wtx.outputs.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[1]) }, - wtx.commands.filterIndexed { index, it -> filterAndNoncesUpdate(it, index + offsets[2]) }, - notNullFalseAndNoncesUpdate(wtx.notary, offsets[3]) as Party?, - notNullFalseAndNoncesUpdate(wtx.timeWindow, offsets[4]) as TimeWindow?, - nonces - ) - } - - // We use index offsets, to get the actual leaf-index per transaction component required for nonce computation. - private fun indexOffsets(wtx: WireTransaction): List { - // There is no need to add an index offset for inputs, because they are the first components in the - // transaction format and it is always zero. Thus, offsets[0] corresponds to attachments, - // offsets[1] to outputs, offsets[2] to commands and so on. - val offsets = mutableListOf(wtx.inputs.size, wtx.inputs.size + wtx.attachments.size) - offsets.add(offsets.last() + wtx.outputs.size) - offsets.add(offsets.last() + wtx.commands.size) - if (wtx.notary != null) { - offsets.add(offsets.last() + 1) - } else { - offsets.add(offsets.last()) - } - if (wtx.timeWindow != null) { - offsets.add(offsets.last() + 1) - } else { - offsets.add(offsets.last()) - } - // No need to add offset for privacySalt as it doesn't require a nonce. - return offsets - } - } - - /** - * Runs verification of partial Merkle branch against [id]. - */ - @Throws(MerkleTreeException::class) - fun verify(): Boolean { - val hashes: List = filteredLeaves.availableComponentHashes - if (hashes.isEmpty()) - throw MerkleTreeException("Transaction without included leaves.") - return partialMerkleTree.verify(id, hashes) +data class FilteredComponentGroup(override val groupIndex: Int, override val components: List, val nonces: List, val partialMerkleTree: PartialMerkleTree): ComponentGroup(groupIndex, components) { + init { + check(components.size == nonces.size) { "Size of transaction components and nonces do not match" } } } + +/** Thrown when checking for visibility of all-components in a group in [FilteredTransaction.checkAllComponentsVisible]. + * @param id transaction's id. + * @param reason information about the exception. + */ +@CordaSerializable +class ComponentVisibilityException(val id: SecureHash, val reason: String) : Exception("Component visibility error for transaction with id:$id. Reason: $reason") + +/** Thrown when [FilteredTransaction.verify] fails. + * @param id transaction's id. + * @param reason information about the exception. + */ +@CordaSerializable +class FilteredTransactionVerificationException(val id: SecureHash, val reason: String) : Exception("Transaction with id:$id cannot be verified. Reason: $reason") diff --git a/core/src/main/kotlin/net/corda/core/transactions/NotaryChangeTransactions.kt b/core/src/main/kotlin/net/corda/core/transactions/NotaryChangeTransactions.kt index 9bbb9ca5b7..f592f998b7 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/NotaryChangeTransactions.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/NotaryChangeTransactions.kt @@ -3,6 +3,7 @@ package net.corda.core.transactions import net.corda.core.contracts.* import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature +import net.corda.core.crypto.serializedHash import net.corda.core.utilities.toBase58String import net.corda.core.identity.Party import net.corda.core.node.ServiceHub diff --git a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt index 39ffd5ce87..bcc2715f78 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/TransactionBuilder.kt @@ -2,13 +2,16 @@ package net.corda.core.transactions import co.paralleluniverse.strands.Strand import net.corda.core.contracts.* -import net.corda.core.crypto.* +import net.corda.core.crypto.SecureHash +import net.corda.core.crypto.SignableData +import net.corda.core.crypto.SignatureMetadata import net.corda.core.identity.Party import net.corda.core.internal.FlowStateMachine import net.corda.core.node.ServiceHub import net.corda.core.node.services.KeyManagementService import java.lang.UnsupportedOperationException -import java.security.KeyPair +import net.corda.core.serialization.SerializationContext +import net.corda.core.serialization.SerializationFactory import java.security.PublicKey import java.time.Duration import java.time.Instant @@ -72,8 +75,9 @@ open class TransactionBuilder( } // DOCEND 1 - fun toWireTransaction() = WireTransaction(ArrayList(inputs), ArrayList(attachments), - ArrayList(outputs), ArrayList(commands), notary, window, privacySalt) + fun toWireTransaction(serializationContext: SerializationContext? = null) = SerializationFactory.defaultFactory.withCurrentContext(serializationContext) { + WireTransaction(WireTransaction.createComponentGroups(inputs, outputs, commands, attachments, notary, window), privacySalt) + } @Throws(AttachmentResolutionException::class, TransactionResolutionException::class) fun toLedgerTransaction(services: ServiceHub) = toWireTransaction().toLedgerTransaction(services) diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt index 44a3797f75..95f18b185b 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt @@ -1,14 +1,13 @@ package net.corda.core.transactions import net.corda.core.contracts.* -import net.corda.core.crypto.MerkleTree -import net.corda.core.crypto.SecureHash -import net.corda.core.crypto.TransactionSignature -import net.corda.core.crypto.keys +import net.corda.core.contracts.ComponentGroupEnum.* +import net.corda.core.crypto.* import net.corda.core.identity.Party import net.corda.core.internal.Emoji import net.corda.core.node.ServicesForResolution -import net.corda.core.serialization.CordaSerializable +import net.corda.core.serialization.* +import net.corda.core.utilities.OpaqueBytes import java.security.PublicKey import java.security.SignatureException import java.util.function.Predicate @@ -17,21 +16,42 @@ import java.util.function.Predicate * A transaction ready for serialisation, without any signatures attached. A WireTransaction is usually wrapped * by a [SignedTransaction] that carries the signatures over this payload. * The identity of the transaction is the Merkle tree root of its components (see [MerkleTree]). + * + * For privacy purposes, each part of a transaction should be accompanied by a nonce. + * To avoid storing a random number (nonce) per component, an initial [privacySalt] is the sole value utilised, + * so that all component nonces are deterministically computed. + * + * A few notes about backwards compatibility: + * A wire transaction can be backwards compatible, in the sense that if an old client receives a [componentGroups] with + * more elements than expected, it will normally deserialise the required objects and omit any checks in the optional + * new fields. Moreover, because the Merkle tree is constructed from the received list of [ComponentGroup], which internally + * deals with bytes, any client can compute the Merkle tree and on the same time relay a [WireTransaction] object even + * if she is unable to read some of the "optional" component types. We stress that practically, a new type of + * [WireTransaction] should only be considered compatible if and only if the following rules apply: + *

    + *
  • Component-type ordering is fixed (eg. inputs, then outputs, then commands etc, see [ComponentGroupEnum] for the actual ordering). + *
  • Removing a component-type that existed in older wire transaction types is not allowed, because it will affect the Merkle tree structure. + *
  • Changing the order of existing component types is also not allowed, for the same reason. + *
  • New component types must be added at the end of the list of [ComponentGroup] and update the [ComponentGroupEnum] with the new type. After a component is added, its ordinal must never change. + *
  • A new component type should always be an "optional value", in the sense that lack of its visibility does not change the transaction and contract logic and details. An example of "optional" components could be a transaction summary or some statistics. + *

*/ @CordaSerializable -data class WireTransaction( - /** Pointers to the input states on the ledger, identified by (tx identity hash, output index). */ - override val inputs: List, - /** Hashes of the ZIP/JAR files that are needed to interpret the contents of this wire transaction. */ - override val attachments: List, - override val outputs: List>, - /** Ordered list of ([CommandData], [PublicKey]) pairs that instruct the contracts what to do. */ - override val commands: List>, - override val notary: Party?, - override val timeWindow: TimeWindow?, - override val privacySalt: PrivacySalt = PrivacySalt() -) : CoreTransaction(), TraversableTransaction { +class WireTransaction(componentGroups: List, val privacySalt: PrivacySalt = PrivacySalt()) : TraversableTransaction(componentGroups) { + + @Deprecated("Required only in some unit-tests and for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING) + constructor(inputs: List, + attachments: List, + outputs: List>, + commands: List>, + notary: Party?, + timeWindow: TimeWindow?, + privacySalt: PrivacySalt = PrivacySalt() + ) : this(createComponentGroups(inputs, outputs, commands, attachments, notary, timeWindow), privacySalt) + init { + check(componentGroups.all { it.components.isNotEmpty() }) { "Empty component groups are not allowed" } + check(componentGroups.map { it.groupIndex }.toSet().size == componentGroups.size) { "Duplicated component groups detected" } checkBaseInvariants() check(inputs.isNotEmpty() || outputs.isNotEmpty()) { "A transaction must contain at least one input or output state" } check(commands.isNotEmpty()) { "A transaction must contain at least one command" } @@ -44,7 +64,7 @@ data class WireTransaction( /** Public keys that need to be fulfilled by signatures in order for the transaction to be valid. */ val requiredSigningKeys: Set get() { val commandKeys = commands.flatMap { it.signers }.toSet() - // TODO: prevent notary field from being set if there are no inputs and no timestamp + // TODO: prevent notary field from being set if there are no inputs and no timestamp. return if (notary != null && (inputs.isNotEmpty() || timeWindow != null)) { commandKeys + notary.owningKey } else { @@ -97,14 +117,70 @@ data class WireTransaction( /** * Build filtered transaction using provided filtering functions. */ - fun buildFilteredTransaction(filtering: Predicate): FilteredTransaction { - return FilteredTransaction.buildMerkleTransaction(this, filtering) - } + fun buildFilteredTransaction(filtering: Predicate): FilteredTransaction = + FilteredTransaction.buildFilteredTransaction(this, filtering) /** * Builds whole Merkle tree for a transaction. + * Briefly, each component group has its own sub Merkle tree and all of the roots of these trees are used as leaves + * in a top level Merkle tree. + * Note that ordering of elements inside a [ComponentGroup] matters when computing the Merkle root. + * On the other hand, insertion group ordering does not affect the top level Merkle tree construction, as it is + * actually an ordered Merkle tree, where its leaves are ordered based on the group ordinal in [ComponentGroupEnum]. + * If any of the groups is an empty list or a null object, then [SecureHash.allOnesHash] is used as its hash. + * Also, [privacySalt] is not a Merkle tree leaf, because it is already "inherently" included via the component nonces. */ - val merkleTree: MerkleTree by lazy { MerkleTree.getMerkleTree(availableComponentHashes) } + val merkleTree: MerkleTree by lazy { MerkleTree.getMerkleTree(groupHashes) } + + /** + * The leaves (group hashes) of the top level Merkle tree. + * If a group's Merkle root is allOnesHash, it is a flag that denotes this group is empty (if list) or null (if single object) + * in the wire transaction. + */ + internal val groupHashes: List by lazy { + val listOfLeaves = mutableListOf() + // Even if empty and not used, we should at least send oneHashes for each known + // or received but unknown (thus, bigger than known ordinal) component groups. + for (i in 0..componentGroups.map { it.groupIndex }.max()!!) { + val root = groupsMerkleRoots[i] ?: SecureHash.allOnesHash + listOfLeaves.add(root) + } + listOfLeaves + } + + /** + * Calculate the hashes of the existing component groups, that are used to build the transaction's Merkle tree. + * Each group has its own sub Merkle tree and the hash of the root of this sub tree works as a leaf of the top + * level Merkle tree. The root of the latter is the transaction identifier. + * + * The tree structure is helpful for preserving privacy, please + * see the user-guide section "Transaction tear-offs" to learn more about this topic. + */ + internal val groupsMerkleRoots: Map by lazy { + availableComponentHashes.map { Pair(it.key, MerkleTree.getMerkleTree(it.value).hash) }.toMap() + } + + /** + * Calculate nonces for every transaction component, including new fields (due to backwards compatibility support) we cannot process. + * Nonce are computed in the following way: + * nonce1 = H(salt || path_for_1st_component) + * nonce2 = H(salt || path_for_2nd_component) + * etc. + * Thus, all of the nonces are "independent" in the sense that knowing one or some of them, you can learn + * nothing about the rest. + */ + internal val availableComponentNonces: Map> by lazy { + componentGroups.map { Pair(it.groupIndex, it.components.mapIndexed { internalIndex, internalIt -> componentHash(internalIt, privacySalt, it.groupIndex, internalIndex) }) }.toMap() + } + + /** + * Calculate hashes for every transaction component. These will be used to build the full Merkle tree. + * The root of the tree is the transaction identifier. The tree structure is helpful for privacy, please + * see the user-guide section "Transaction tear-offs" to learn more about this topic. + */ + internal val availableComponentHashes: Map> by lazy { + componentGroups.map { Pair(it.groupIndex, it.components.mapIndexed { internalIndex, internalIt -> componentHash(availableComponentNonces[it.groupIndex]!![internalIndex], internalIt) }) }.toMap() + } /** * Checks that the given signature matches one of the commands and that it is a correct signature over the tx. @@ -117,6 +193,28 @@ data class WireTransaction( sig.verify(id) } + internal companion object { + /** + * Creating list of [ComponentGroup] used in one of the constructors of [WireTransaction] required + * for backwards compatibility purposes. + */ + fun createComponentGroups(inputs: List, + outputs: List>, + commands: List>, + attachments: List, + notary: Party?, + timeWindow: TimeWindow?): List { + val componentGroupMap: MutableList = mutableListOf() + if (inputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(INPUTS_GROUP.ordinal, inputs.map { it.serialize() })) + if (outputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.map { it.serialize() })) + if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(COMMANDS_GROUP.ordinal, commands.map { it.serialize() })) + if (attachments.isNotEmpty()) componentGroupMap.add(ComponentGroup(ATTACHMENTS_GROUP.ordinal, attachments.map { it.serialize() })) + if (notary != null) componentGroupMap.add(ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary.serialize()))) + if (timeWindow != null) componentGroupMap.add(ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow.serialize()))) + return componentGroupMap + } + } + override fun toString(): String { val buf = StringBuilder() buf.appendln("Transaction:") @@ -126,4 +224,21 @@ data class WireTransaction( for (attachment in attachments) buf.appendln("${Emoji.paperclip}ATTACHMENT: $attachment") return buf.toString() } + + override fun equals(other: Any?): Boolean { + if (other is WireTransaction) { + return (this.id == other.id) + } + return false + } + + override fun hashCode(): Int = id.hashCode() } + +/** + * A ComponentGroup is used to store the full list of transaction components of the same type in serialised form. + * Practically, a group per component type of a transaction is required; thus, there will be a group for input states, + * a group for all attachments (if there are any) etc. + */ +@CordaSerializable +open class ComponentGroup(open val groupIndex: Int, open val components: List) diff --git a/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt b/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt new file mode 100644 index 0000000000..7854a0180b --- /dev/null +++ b/core/src/test/kotlin/net/corda/core/contracts/CompatibleTransactionTests.kt @@ -0,0 +1,251 @@ +package net.corda.core.contracts + +import net.corda.core.contracts.ComponentGroupEnum.* +import net.corda.core.crypto.MerkleTree +import net.corda.core.crypto.SecureHash +import net.corda.core.crypto.secureRandomBytes +import net.corda.core.serialization.serialize +import net.corda.core.transactions.ComponentGroup +import net.corda.core.transactions.ComponentVisibilityException +import net.corda.core.transactions.WireTransaction +import net.corda.core.utilities.OpaqueBytes +import net.corda.testing.* +import net.corda.testing.contracts.DUMMY_PROGRAM_ID +import net.corda.testing.contracts.DummyState +import org.junit.Test +import java.time.Instant +import java.util.function.Predicate +import kotlin.test.* + +class CompatibleTransactionTests : TestDependencyInjectionBase() { + + private val dummyOutState = TransactionState(DummyState(0), DUMMY_PROGRAM_ID, DUMMY_NOTARY) + private val stateRef1 = StateRef(SecureHash.randomSHA256(), 0) + private val stateRef2 = StateRef(SecureHash.randomSHA256(), 1) + private val stateRef3 = StateRef(SecureHash.randomSHA256(), 0) + + private val inputs = listOf(stateRef1, stateRef2, stateRef3) // 3 elements. + private val outputs = listOf(dummyOutState, dummyOutState.copy(notary = BOB)) // 2 elements. + private val commands = listOf(dummyCommand(DUMMY_KEY_1.public, DUMMY_KEY_2.public)) // 1 element. + private val attachments = emptyList() // Empty list. + private val notary = DUMMY_NOTARY + private val timeWindow = TimeWindow.fromOnly(Instant.now()) + private val privacySalt: PrivacySalt = PrivacySalt() + + private val inputGroup by lazy { ComponentGroup(INPUTS_GROUP.ordinal, inputs.map { it.serialize() }) } + private val outputGroup by lazy { ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.map { it.serialize() }) } + private val commandGroup by lazy { ComponentGroup(COMMANDS_GROUP.ordinal, commands.map { it.serialize() }) } + private val attachmentGroup by lazy { ComponentGroup(ATTACHMENTS_GROUP.ordinal, attachments.map { it.serialize() }) } // The list is empty. + private val notaryGroup by lazy { ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary.serialize())) } + private val timeWindowGroup by lazy { ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow.serialize())) } + + private val newUnknownComponentGroup = ComponentGroup(20, listOf(OpaqueBytes(secureRandomBytes(4)), OpaqueBytes(secureRandomBytes(8)))) + private val newUnknownComponentEmptyGroup = ComponentGroup(21, emptyList()) + + // Do not add attachments (empty list). + private val componentGroupsA by lazy { + listOf( + inputGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup + ) + } + private val wireTransactionA by lazy { WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) } + + @Test + fun `Merkle root computations`() { + // Merkle tree computation is deterministic if the same salt and ordering are used. + val wireTransactionB = WireTransaction(componentGroups = componentGroupsA, privacySalt = privacySalt) + assertEquals(wireTransactionA, wireTransactionB) + + // Merkle tree computation will change if privacy salt changes. + val wireTransactionOtherPrivacySalt = WireTransaction(componentGroups = componentGroupsA, privacySalt = PrivacySalt()) + assertNotEquals(wireTransactionA, wireTransactionOtherPrivacySalt) + + // Full Merkle root is computed from the list of Merkle roots of each component group. + assertEquals(wireTransactionA.merkleTree.hash, MerkleTree.getMerkleTree(wireTransactionA.groupHashes).hash) + + // Trying to add an empty component group (not allowed), e.g. the empty attachmentGroup. + val componentGroupsEmptyAttachment = listOf( + inputGroup, + outputGroup, + commandGroup, + attachmentGroup, + notaryGroup, + timeWindowGroup + ) + assertFails { WireTransaction(componentGroups = componentGroupsEmptyAttachment, privacySalt = privacySalt) } + + // Ordering inside a component group matters. + val inputsShuffled = listOf(stateRef2, stateRef1, stateRef3) + val inputShuffledGroup = ComponentGroup(INPUTS_GROUP.ordinal, inputsShuffled.map { it -> it.serialize() }) + val componentGroupsB = listOf( + inputShuffledGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup + ) + val wireTransaction1ShuffledInputs = WireTransaction(componentGroups = componentGroupsB, privacySalt = privacySalt) + // The ID has changed due to change of the internal ordering in inputs. + assertNotEquals(wireTransaction1ShuffledInputs, wireTransactionA) + + // Inputs group Merkle roots are not equal. + assertNotEquals(wireTransactionA.groupsMerkleRoots[INPUTS_GROUP.ordinal], wireTransaction1ShuffledInputs.groupsMerkleRoots[INPUTS_GROUP.ordinal]) + // But outputs group Merkle leaf (and the rest) remained the same. + assertEquals(wireTransactionA.groupsMerkleRoots[OUTPUTS_GROUP.ordinal], wireTransaction1ShuffledInputs.groupsMerkleRoots[OUTPUTS_GROUP.ordinal]) + assertEquals(wireTransactionA.groupsMerkleRoots[NOTARY_GROUP.ordinal], wireTransaction1ShuffledInputs.groupsMerkleRoots[NOTARY_GROUP.ordinal]) + assertNull(wireTransactionA.groupsMerkleRoots[ATTACHMENTS_GROUP.ordinal]) + assertNull(wireTransaction1ShuffledInputs.groupsMerkleRoots[ATTACHMENTS_GROUP.ordinal]) + + // Group leaves (components) ordering does not affect the id. In this case, we added outputs group before inputs. + val shuffledComponentGroupsA = listOf( + outputGroup, + inputGroup, + commandGroup, + notaryGroup, + timeWindowGroup + ) + assertEquals(wireTransactionA, WireTransaction(componentGroups = shuffledComponentGroupsA, privacySalt = privacySalt)) + } + + @Test + fun `WireTransaction constructors and compatibility`() { + val wireTransactionOldConstructor = WireTransaction(inputs, attachments, outputs, commands, notary, timeWindow, privacySalt) + assertEquals(wireTransactionA, wireTransactionOldConstructor) + + // Malformed tx - attachments is not List. For this example, we mistakenly added input-state (StateRef) serialised objects with ATTACHMENTS_GROUP.ordinal. + val componentGroupsB = listOf( + inputGroup, + outputGroup, + commandGroup, + ComponentGroup(ATTACHMENTS_GROUP.ordinal, inputGroup.components), + notaryGroup, + timeWindowGroup + ) + assertFails { WireTransaction(componentGroupsB, privacySalt) } + + // Malformed tx - duplicated component group detected. + val componentGroupsDuplicatedCommands = listOf( + inputGroup, + outputGroup, + commandGroup, // First commandsGroup. + commandGroup, // Second commandsGroup. + notaryGroup, + timeWindowGroup + ) + assertFails { WireTransaction(componentGroupsDuplicatedCommands, privacySalt) } + + // Malformed tx - inputs is not a serialised object at all. + val componentGroupsC = listOf( + ComponentGroup(INPUTS_GROUP.ordinal, listOf(OpaqueBytes(ByteArray(8)))), + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup + ) + assertFails { WireTransaction(componentGroupsC, privacySalt) } + + val componentGroupsCompatibleA = listOf( + inputGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup, + newUnknownComponentGroup // A new unknown component with ordinal 20 that we cannot process. + ) + + // The old client (receiving more component types than expected) is still compatible. + val wireTransactionCompatibleA = WireTransaction(componentGroupsCompatibleA, privacySalt) + assertEquals(wireTransactionCompatibleA.availableComponentGroups, wireTransactionA.availableComponentGroups) // The known components are the same. + assertNotEquals(wireTransactionCompatibleA, wireTransactionA) // But obviously, its Merkle root has changed Vs wireTransactionA (which doesn't include this extra component). + assertEquals(6, wireTransactionCompatibleA.componentGroups.size) + + // The old client will trhow if receiving an empty component (even if this unknown). + val componentGroupsCompatibleEmptyNew = listOf( + inputGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup, + newUnknownComponentEmptyGroup // A new unknown component with ordinal 21 that we cannot process. + ) + assertFails { WireTransaction(componentGroupsCompatibleEmptyNew, privacySalt) } + } + + @Test + fun `FilteredTransaction constructors and compatibility`() { + // Filter out all of the components. + val ftxNothing = wireTransactionA.buildFilteredTransaction(Predicate { false }) // Nothing filtered. + assertEquals(6, ftxNothing.groupHashes.size) // Although nothing filtered, we still receive the group hashes for the top level Merkle tree. + ftxNothing.verify() + + // Include all of the components. + val ftxAll = wireTransactionA.buildFilteredTransaction(Predicate { true }) // All filtered. + ftxAll.verify() + ftxAll.checkAllComponentsVisible(INPUTS_GROUP) + ftxAll.checkAllComponentsVisible(OUTPUTS_GROUP) + ftxAll.checkAllComponentsVisible(COMMANDS_GROUP) + ftxAll.checkAllComponentsVisible(ATTACHMENTS_GROUP) + ftxAll.checkAllComponentsVisible(NOTARY_GROUP) + ftxAll.checkAllComponentsVisible(TIMEWINDOW_GROUP) + + // Filter inputs only. + fun filtering(elem: Any): Boolean { + return when (elem) { + is StateRef -> true + else -> false + } + } + val ftxInputs = wireTransactionA.buildFilteredTransaction(Predicate(::filtering)) // Inputs only filtered. + ftxInputs.verify() + ftxInputs.checkAllComponentsVisible(INPUTS_GROUP) + + assertEquals(1, ftxInputs.filteredComponentGroups.size) // We only add component groups that are not empty, thus in this case: the inputs only. + assertEquals(3, ftxInputs.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.components.size) // All 3 inputs are present. + assertEquals(3, ftxInputs.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.nonces.size) // And their corresponding nonces. + assertNotNull(ftxInputs.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.partialMerkleTree) // And the Merkle tree. + + // Filter one input only. + fun filteringOneInput(elem: Any) = elem == inputs[0] + val ftxOneInput = wireTransactionA.buildFilteredTransaction(Predicate(::filteringOneInput)) // First input only filtered. + ftxOneInput.verify() + assertFailsWith { ftxOneInput.checkAllComponentsVisible(INPUTS_GROUP) } + + assertEquals(1, ftxOneInput.filteredComponentGroups.size) // We only add component groups that are not empty, thus in this case: the inputs only. + assertEquals(1, ftxOneInput.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.components.size) // 1 input is present. + assertEquals(1, ftxOneInput.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.nonces.size) // And its corresponding nonce. + assertNotNull(ftxOneInput.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.partialMerkleTree) // And the Merkle tree. + + // The old client (receiving more component types than expected) is still compatible. + val componentGroupsCompatibleA = listOf(inputGroup, + outputGroup, + commandGroup, + notaryGroup, + timeWindowGroup, + newUnknownComponentGroup // A new unknown component with ordinal 10,000 that we cannot process. + ) + val wireTransactionCompatibleA = WireTransaction(componentGroupsCompatibleA, privacySalt) + val ftxCompatible = wireTransactionCompatibleA.buildFilteredTransaction(Predicate(::filtering)) + ftxCompatible.verify() + assertEquals(ftxInputs.inputs, ftxCompatible.inputs) + assertEquals(wireTransactionCompatibleA.id, ftxCompatible.id) + + assertEquals(1, ftxCompatible.filteredComponentGroups.size) + assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.components.size) + assertEquals(3, ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.nonces.size) + assertNotNull(ftxCompatible.filteredComponentGroups.firstOrNull { it.groupIndex == INPUTS_GROUP.ordinal }!!.partialMerkleTree) + + // Now, let's allow everything, including the new component type that we cannot process. + val ftxCompatibleAll = wireTransactionCompatibleA.buildFilteredTransaction(Predicate { true }) // All filtered, including the unknown component. + ftxCompatibleAll.verify() + assertEquals(wireTransactionCompatibleA.id, ftxCompatibleAll.id) + + // Check we received the last (6th) element that we cannot process (backwards compatibility). + assertEquals(6, ftxCompatibleAll.filteredComponentGroups.size) + + + } +} diff --git a/core/src/test/kotlin/net/corda/core/contracts/DummyContractV2Tests.kt b/core/src/test/kotlin/net/corda/core/contracts/DummyContractV2Tests.kt index b960873a50..e8421fc7d0 100644 --- a/core/src/test/kotlin/net/corda/core/contracts/DummyContractV2Tests.kt +++ b/core/src/test/kotlin/net/corda/core/contracts/DummyContractV2Tests.kt @@ -7,6 +7,7 @@ import net.corda.testing.ALICE import net.corda.testing.DUMMY_NOTARY import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DUMMY_V2_PROGRAM_ID +import net.corda.testing.TestDependencyInjectionBase import org.junit.Test import kotlin.test.assertEquals import kotlin.test.assertTrue @@ -14,7 +15,7 @@ import kotlin.test.assertTrue /** * Tests for the version 2 dummy contract, to cover ensuring upgrade transactions are built correctly. */ -class DummyContractV2Tests { +class DummyContractV2Tests : TestDependencyInjectionBase() { @Test fun `upgrade from v1`() { val contractUpgrade = DummyContractV2() diff --git a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt index 4c14517faf..ce67219b0b 100644 --- a/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt +++ b/core/src/test/kotlin/net/corda/core/crypto/PartialMerkleTreeTest.kt @@ -19,7 +19,7 @@ import kotlin.test.* class PartialMerkleTreeTest : TestDependencyInjectionBase() { val nodes = "abcdef" - val hashed = nodes.map { + private val hashed = nodes.map { initialiseTestSerialization() try { it.serialize().sha256() @@ -27,10 +27,10 @@ class PartialMerkleTreeTest : TestDependencyInjectionBase() { resetTestSerialization() } } - val expectedRoot = MerkleTree.getMerkleTree(hashed.toMutableList() + listOf(zeroHash, zeroHash)).hash - val merkleTree = MerkleTree.getMerkleTree(hashed) + private val expectedRoot = MerkleTree.getMerkleTree(hashed.toMutableList() + listOf(zeroHash, zeroHash)).hash + private val merkleTree = MerkleTree.getMerkleTree(hashed) - val testLedger = ledger { + private val testLedger = ledger { unverifiedTransaction { output(CASH_PROGRAM_ID, "MEGA_CORP cash") { Cash.State( @@ -55,8 +55,8 @@ class PartialMerkleTreeTest : TestDependencyInjectionBase() { } } - val txs = testLedger.interpreter.transactionsToVerify - val testTx = txs[0] + private val txs = testLedger.interpreter.transactionsToVerify + private val testTx = txs[0] // Building full Merkle Tree tests. @Test @@ -115,17 +115,15 @@ class PartialMerkleTreeTest : TestDependencyInjectionBase() { assertEquals(testTx.id, d.id) val mt = testTx.buildFilteredTransaction(Predicate(::filtering)) - val leaves = mt.filteredLeaves - assertEquals(1, leaves.inputs.size) - assertEquals(0, leaves.attachments.size) - assertEquals(1, leaves.outputs.size) - assertEquals(1, leaves.commands.size) - assertNull(mt.filteredLeaves.notary) - assertNotNull(mt.filteredLeaves.timeWindow) - assertNull(mt.filteredLeaves.privacySalt) - assertEquals(4, leaves.nonces.size) - assertTrue(mt.verify()) + assertEquals(4, mt.filteredComponentGroups.size) + assertEquals(1, mt.inputs.size) + assertEquals(0, mt.attachments.size) + assertEquals(1, mt.outputs.size) + assertEquals(1, mt.commands.size) + assertNull(mt.notary) + assertNotNull(mt.timeWindow) + mt.verify() } @Test @@ -140,25 +138,15 @@ class PartialMerkleTreeTest : TestDependencyInjectionBase() { @Test fun `nothing filtered`() { - val mt = testTx.buildFilteredTransaction(Predicate { false }) - assertTrue(mt.filteredLeaves.attachments.isEmpty()) - assertTrue(mt.filteredLeaves.commands.isEmpty()) - assertTrue(mt.filteredLeaves.inputs.isEmpty()) - assertTrue(mt.filteredLeaves.outputs.isEmpty()) - assertTrue(mt.filteredLeaves.timeWindow == null) - assertTrue(mt.filteredLeaves.availableComponents.isEmpty()) - assertTrue(mt.filteredLeaves.availableComponentHashes.isEmpty()) - assertTrue(mt.filteredLeaves.nonces.isEmpty()) - assertFailsWith { mt.verify() } - - // Including only privacySalt still results to an empty FilteredTransaction. - fun filterPrivacySalt(elem: Any): Boolean = elem is PrivacySalt - val mt2 = testTx.buildFilteredTransaction(Predicate(::filterPrivacySalt)) - assertTrue(mt2.filteredLeaves.privacySalt == null) - assertTrue(mt2.filteredLeaves.availableComponents.isEmpty()) - assertTrue(mt2.filteredLeaves.availableComponentHashes.isEmpty()) - assertTrue(mt2.filteredLeaves.nonces.isEmpty()) - assertFailsWith { mt2.verify() } + val ftxNothing = testTx.buildFilteredTransaction(Predicate { false }) + assertTrue(ftxNothing.componentGroups.isEmpty()) + assertTrue(ftxNothing.attachments.isEmpty()) + assertTrue(ftxNothing.commands.isEmpty()) + assertTrue(ftxNothing.inputs.isEmpty()) + assertTrue(ftxNothing.outputs.isEmpty()) + assertNull(ftxNothing.timeWindow) + assertTrue(ftxNothing.availableComponentGroups.flatten().isEmpty()) + ftxNothing.verify() // We allow empty ftx transactions (eg from a timestamp authority that blindly signs). } // Partial Merkle Tree building tests. diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index dab2a42814..01198840c2 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -154,6 +154,40 @@ UNRELEASED * Moved ``CityDatabase`` out of ``core`` and into ``finance`` +* All of the ``serializedHash`` and ``computeNonce`` functions have been removed from ``MerkleTransaction``. + The ``serializedHash(x: T)`` and ``computeNonce`` were moved to ``CryptoUtils``. + +* Two overloaded methods ``componentHash(opaqueBytes: OpaqueBytes, privacySalt: PrivacySalt, componentGroupIndex: Int, + internalIndex: Int): SecureHash`` and ``componentHash(nonce: SecureHash, opaqueBytes: OpaqueBytes): SecureHash`` have + been added to ``CryptoUtils``. Similarly to ``computeNonce``, they internally use SHA256d for nonce and leaf hash + computations. + +* The ``verify(node: PartialTree, usedHashes: MutableList): SecureHash`` in ``PartialMerkleTree`` has been + renamed to ``rootAndUsedHashes`` and is now public, as it is required in the verify function of ``FilteredTransaction``. + +* ``TraversableTransaction`` is now an abstract class extending ``CoreTransaction``. ``WireTransaction`` and + ``FilteredTransaction`` now extend ``TraversableTransaction``. + +* Two classes, ``ComponentGroup(open val groupIndex: Int, open val components: List)`` and + ``FilteredComponentGroup(override val groupIndex: Int, override val components: List, + val nonces: List, val partialMerkleTree: PartialMerkleTree): ComponentGroup(groupIndex, components)`` + have been added, which are properties of the ``WireTransaction`` and ``FilteredTransaction``, respectively. + +* ``checkAllComponentsVisible(componentGroupEnum: ComponentGroupEnum)`` is added to ``FilteredTransaction``, a new + function to check if all components are visible in a specific component-group. + +* To allow for backwards compatibility, ``WireTransaction`` and ``FilteredTransaction`` have new fields and + constructors: ``WireTransaction(componentGroups: List, privacySalt: PrivacySalt = PrivacySalt())``, + ``FilteredTransaction private constructor(id: SecureHash,filteredComponentGroups: List, + groupHashes: List``. ``FilteredTransaction`` is still built via + ``buildFilteredTransaction(wtx: WireTransaction, filtering: Predicate). + +* ``FilteredLeaves`` class have been removed and as a result we can directly call the components from + ``FilteredTransaction``, such as ``ftx.inputs`` Vs the old ``ftx.filteredLeaves.inputs``. + +* A new ``ComponentGroupEnum`` is added with the following enum items: ``INPUTS_GROUP``, ``OUTPUTS_GROUP``, + ``COMMANDS_GROUP``, ``ATTACHMENTS_GROUP``, ``NOTARY_GROUP``, ``TIMEWINDOW_GROUP``. + Milestone 14 ------------ diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt index 784538c5c6..650d9ff92c 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/Kryo.kt @@ -7,20 +7,15 @@ import com.esotericsoftware.kryo.io.Output import com.esotericsoftware.kryo.serializers.CompatibleFieldSerializer import com.esotericsoftware.kryo.serializers.FieldSerializer import com.esotericsoftware.kryo.util.MapReferenceResolver -import net.corda.core.contracts.* +import net.corda.core.contracts.PrivacySalt +import net.corda.core.contracts.StateRef import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.Crypto -import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature import net.corda.core.identity.Party -import net.corda.nodeapi.internal.AttachmentsClassLoader -import net.corda.core.serialization.MissingAttachmentsException import net.corda.core.serialization.SerializeAsTokenContext import net.corda.core.serialization.SerializedBytes -import net.corda.core.transactions.CoreTransaction -import net.corda.core.transactions.NotaryChangeWireTransaction -import net.corda.core.transactions.SignedTransaction -import net.corda.core.transactions.WireTransaction +import net.corda.core.transactions.* import net.i2p.crypto.eddsa.EdDSAPrivateKey import net.i2p.crypto.eddsa.EdDSAPublicKey import net.i2p.crypto.eddsa.spec.EdDSANamedCurveSpec @@ -241,42 +236,15 @@ fun Input.readBytesWithLength(): ByteArray { @ThreadSafe object WireTransactionSerializer : Serializer() { override fun write(kryo: Kryo, output: Output, obj: WireTransaction) { - kryo.writeClassAndObject(output, obj.inputs) - kryo.writeClassAndObject(output, obj.attachments) - kryo.writeClassAndObject(output, obj.outputs) - kryo.writeClassAndObject(output, obj.commands) - kryo.writeClassAndObject(output, obj.notary) - kryo.writeClassAndObject(output, obj.timeWindow) + kryo.writeClassAndObject(output, obj.componentGroups) kryo.writeClassAndObject(output, obj.privacySalt) } - private fun attachmentsClassLoader(kryo: Kryo, attachmentHashes: List): ClassLoader? { - kryo.context[attachmentsClassLoaderEnabledPropertyName] as? Boolean ?: false || return null - val serializationContext = kryo.serializationContext() ?: return null // Some tests don't set one. - val missing = ArrayList() - val attachments = ArrayList() - attachmentHashes.forEach { id -> - serializationContext.serviceHub.attachments.openAttachment(id)?.let { attachments += it } ?: run { missing += id } - } - missing.isNotEmpty() && throw MissingAttachmentsException(missing) - return AttachmentsClassLoader(attachments) - } - @Suppress("UNCHECKED_CAST") override fun read(kryo: Kryo, input: Input, type: Class): WireTransaction { - val inputs = kryo.readClassAndObject(input) as List - val attachmentHashes = kryo.readClassAndObject(input) as List - - // If we're deserialising in the sandbox context, we use our special attachments classloader. - // Otherwise we just assume the code we need is on the classpath already. - kryo.useClassLoader(attachmentsClassLoader(kryo, attachmentHashes) ?: javaClass.classLoader) { - val outputs = kryo.readClassAndObject(input) as List> - val commands = kryo.readClassAndObject(input) as List> - val notary = kryo.readClassAndObject(input) as Party? - val timeWindow = kryo.readClassAndObject(input) as TimeWindow? - val privacySalt = kryo.readClassAndObject(input) as PrivacySalt - return WireTransaction(inputs, attachmentHashes, outputs, commands, notary, timeWindow, privacySalt) - } + val componentGroups = kryo.readClassAndObject(input) as List + val privacySalt = kryo.readClassAndObject(input) as PrivacySalt + return WireTransaction(componentGroups, privacySalt) } } @@ -410,8 +378,7 @@ inline fun readListOfLength(kryo: Kryo, input: Input, minLen: Int = if (elemCount < minLen) throw KryoException("Cannot deserialize list, too little elements. Minimum required: $minLen, got: $elemCount") if (expectedLen != null && elemCount != expectedLen) throw KryoException("Cannot deserialize list, expected length: $expectedLen, got: $elemCount.") - val list = (1..elemCount).map { kryo.readClassAndObject(input) as T } - return list + return (1..elemCount).map { kryo.readClassAndObject(input) as T } } /** diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentsClassLoaderTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentsClassLoaderTests.kt index 6037d1ed33..a900d72948 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentsClassLoaderTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/AttachmentsClassLoaderTests.kt @@ -21,7 +21,6 @@ import net.corda.nodeapi.internal.serialization.withTokenContext import net.corda.testing.DUMMY_NOTARY import net.corda.testing.MEGA_CORP import net.corda.testing.TestDependencyInjectionBase -import net.corda.testing.kryoSpecific import net.corda.testing.node.MockAttachmentStorage import org.apache.commons.io.IOUtils import org.junit.Assert @@ -75,7 +74,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { } } - fun importJar(storage: AttachmentStorage) = ISOLATED_CONTRACTS_JAR_PATH.openStream().use { storage.importAttachment(it) } + private fun importJar(storage: AttachmentStorage) = ISOLATED_CONTRACTS_JAR_PATH.openStream().use { storage.importAttachment(it) } // These ClassLoaders work together to load 'AnotherDummyContract' in a disposable way, such that even though // the class may be on the unit test class path (due to default IDE settings, etc), it won't be loaded into the @@ -83,10 +82,10 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { // ensures we have precise control over where it's loaded. object FilteringClassLoader : ClassLoader() { override fun loadClass(name: String, resolve: Boolean): Class<*>? { - if ("AnotherDummyContract" in name) { - return null + return if ("AnotherDummyContract" in name) { + null } else - return super.loadClass(name, resolve) + super.loadClass(name, resolve) } } @@ -102,7 +101,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { assertEquals("helloworld", contract.declaredField("magicString").value) } - fun fakeAttachment(filepath: String, content: String): ByteArray { + private fun fakeAttachment(filepath: String, content: String): ByteArray { val bs = ByteArrayOutputStream() val js = JarOutputStream(bs) js.putNextEntry(ZipEntry(filepath)) @@ -112,7 +111,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { return bs.toByteArray() } - fun readAttachment(attachment: Attachment, filepath: String): ByteArray { + private fun readAttachment(attachment: Attachment, filepath: String): ByteArray { ByteArrayOutputStream().use { attachment.extractFile(filepath, it) return it.toByteArray() @@ -193,7 +192,6 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { assertEquals("helloworld", contract.declaredField("magicString").value) } - @Test fun `verify that contract DummyContract is in classPath`() { val contractClass = Class.forName("net.corda.nodeapi.AttachmentsClassLoaderTests\$AttachmentDummyContract") @@ -202,7 +200,7 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { assertNotNull(contract) } - fun createContract2Cash(): Contract { + private fun createContract2Cash(): Contract { val cl = ClassLoaderForTests() val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, cl) return contractClass.newInstance() as Contract @@ -320,8 +318,8 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { val bytes = run { val attachmentRef = importJar(storage) tx.addAttachment(storage.openAttachment(attachmentRef)!!.id) - val wireTransaction = tx.toWireTransaction() - wireTransaction.serialize(context = context) + val wireTransaction = tx.toWireTransaction(serializationContext = context) + wireTransaction.serialize() } val copiedWireTransaction = bytes.deserialize(context = context) assertEquals(1, copiedWireTransaction.outputs.size) @@ -334,35 +332,36 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { @Test fun `test deserialize of WireTransaction where contract cannot be found`() { - kryoSpecific("Kryo verifies/loads attachments on deserialization, whereas AMQP currently does not") { - val child = ClassLoaderForTests() - val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child) - val contract = contractClass.newInstance() as DummyContractBackdoor - val tx = contract.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY) - val storage = MockAttachmentStorage() + val child = ClassLoaderForTests() + val contractClass = Class.forName(ISOLATED_CONTRACT_CLASS_NAME, true, child) + val contract = contractClass.newInstance() as DummyContractBackdoor + val tx = contract.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY) + val storage = MockAttachmentStorage() + val context = SerializationFactory.defaultFactory.defaultContext.withWhitelisted(contract.javaClass) + .withWhitelisted(Class.forName("net.corda.finance.contracts.isolated.AnotherDummyContract\$State", true, child)) + .withWhitelisted(Class.forName("net.corda.finance.contracts.isolated.AnotherDummyContract\$Commands\$Create", true, child)) + .withAttachmentStorage(storage) - // todo - think about better way to push attachmentStorage down to serializer - val attachmentRef = importJar(storage) - val bytes = run { + // todo - think about better way to push attachmentStorage down to serializer + val attachmentRef = importJar(storage) + val bytes = run { - tx.addAttachment(storage.openAttachment(attachmentRef)!!.id) + tx.addAttachment(storage.openAttachment(attachmentRef)!!.id) - val wireTransaction = tx.toWireTransaction() - - wireTransaction.serialize(context = SerializationFactory.defaultFactory.defaultContext.withAttachmentStorage(storage)) - } - // use empty attachmentStorage - - val e = assertFailsWith(MissingAttachmentsException::class) { - val mockAttStorage = MockAttachmentStorage() - bytes.deserialize(context = SerializationFactory.defaultFactory.defaultContext.withAttachmentStorage(mockAttStorage)) - - if(mockAttStorage.openAttachment(attachmentRef) == null) { - throw MissingAttachmentsException(listOf(attachmentRef)) - } - } - assertEquals(attachmentRef, e.ids.single()) + val wireTransaction = tx.toWireTransaction(serializationContext = context) + wireTransaction.serialize() } + // use empty attachmentStorage + + val e = assertFailsWith(MissingAttachmentsException::class) { + val mockAttStorage = MockAttachmentStorage() + bytes.deserialize(context = SerializationFactory.defaultFactory.defaultContext.withAttachmentStorage(mockAttStorage)) + + if(mockAttStorage.openAttachment(attachmentRef) == null) { + throw MissingAttachmentsException(listOf(attachmentRef)) + } + } + assertEquals(attachmentRef, e.ids.single()) } @Test @@ -395,10 +394,10 @@ class AttachmentsClassLoaderTests : TestDependencyInjectionBase() { val storage = MockAttachmentStorage() val attachmentRef = SecureHash.randomSHA256() val outboundContext = SerializationFactory.defaultFactory.defaultContext.withClassLoader(child) - // Serialize with custom context to avoid populating the default context with the specially loaded class + // Serialize with custom context to avoid populating the default context with the specially loaded class. val serialized = contract.serialize(context = outboundContext) - // Then deserialize with the attachment class loader associated with the attachment + // Then deserialize with the attachment class loader associated with the attachment. val e = assertFailsWith(MissingAttachmentsException::class) { // We currently ignore annotations in attachments, so manually whitelist. val inboundContext = SerializationFactory diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt index 780d389ef8..26970dec91 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt @@ -138,9 +138,9 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c fun verifyAndCommitTx(ftx: FilteredTransaction, callerIdentity: Party): BFTSMaRt.ReplicaResponse { return try { val id = ftx.id - val inputs = ftx.filteredLeaves.inputs + val inputs = ftx.inputs - validateTimeWindow(ftx.filteredLeaves.timeWindow) + validateTimeWindow(ftx.timeWindow) commitInputStates(inputs, id, callerIdentity) log.debug { "Inputs committed successfully, signing $id" } BFTSMaRt.ReplicaResponse.Signature(sign(ftx)) diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt index 2546d44afc..9abef4b38f 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt @@ -1,6 +1,7 @@ package net.corda.node.services.transactions import co.paralleluniverse.fibers.Suspendable +import net.corda.core.contracts.ComponentGroupEnum import net.corda.core.flows.NotaryFlow import net.corda.core.flows.TransactionParts import net.corda.core.identity.Party @@ -24,7 +25,9 @@ class NonValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryS when (it) { is FilteredTransaction -> { it.verify() - TransactionParts(it.id, it.filteredLeaves.inputs, it.filteredLeaves.timeWindow) + it.checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP) + it.checkAllComponentsVisible(ComponentGroupEnum.TIMEWINDOW_GROUP) + TransactionParts(it.id, it.inputs, it.timeWindow) } is NotaryChangeWireTransaction -> TransactionParts(it.id, it.inputs, null) else -> { diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt index eac2e1c742..ddf3d488ee 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt @@ -129,10 +129,8 @@ object NodeInterestRates { // It will be fixed by adding partial signatures later. // DOCSTART 1 fun sign(ftx: FilteredTransaction): TransactionSignature { - if (!ftx.verify()) { - throw MerkleTreeException("Rate Fix Oracle: Couldn't verify partial Merkle tree.") - } - // Performing validation of obtained FilteredLeaves. + ftx.verify() + // Performing validation of obtained filtered components. fun commandValidator(elem: Command<*>): Boolean { require(services.myInfo.legalIdentities.first().owningKey in elem.signers && elem.value is Fix) { "Oracle received unknown command (not in signers or not Fix)." @@ -151,8 +149,7 @@ object NodeInterestRates { } } - val leaves = ftx.filteredLeaves - require(leaves.checkWithFun(::check)) + require(ftx.checkWithFun(::check)) // It all checks out, so we can return a signature. // diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt index 5f0da4ae14..93f0bcaf20 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/api/NodeInterestRatesTest.kt @@ -193,7 +193,7 @@ class NodeInterestRatesTest : TestDependencyInjectionBase() { val tx = makeFullTx() val wtx = tx.toWireTransaction() val ftx = wtx.buildFilteredTransaction(Predicate { false }) - assertFailsWith { oracle.sign(ftx) } + assertFailsWith { oracle.sign(ftx) } // It throws failed requirement (as it is empty there is no command to check and sign). } @Test From fd57cf1c0cc3f98cf0cb882755e7982e03378137 Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Wed, 20 Sep 2017 13:19:57 +0100 Subject: [PATCH 014/230] Remove advertised services from NodeInfo (#1521) * Remove advertisedServices from NodeInfo. Introduce notaryIdentities in NetworkMapCache, that will be filled in later from NetworkParameters. Clean up NetworkMapCache API. Expose notaryIdentities through RPC. For now we assume as temporary solution that notaries in NetworkMap have to contain "notary" in name. * Further clean up of NetworkMapCache API Remve partyNodes. Introduce getAllNodeInfos function * Remove notaryIdentity from ServiceHub * Address Shams review comments * Address Andrius review comments * Add comments, cleanup * Fixes * Address comments * Yet another commit with comments addressed * Move ServiceType and ServiceInfo to node-api Add changelog entry. Address rest of comments. * Minor comments --- .../corda/client/jfx/NodeMonitorModelTest.kt | 23 +++-- .../client/jfx/model/NetworkIdentityModel.kt | 24 ++--- .../client/jfx/model/NodeMonitorModel.kt | 3 + .../client/rpc/CordaRPCJavaClientTest.java | 2 +- .../corda/client/rpc/CordaRPCClientTest.kt | 2 +- .../net/corda/core/messaging/CordaRPCOps.kt | 10 +- .../kotlin/net/corda/core/node/NodeInfo.kt | 19 +--- .../kotlin/net/corda/core/node/ServiceHub.kt | 4 +- .../core/node/services/NetworkMapCache.kt | 99 ++++--------------- .../net/corda/core/schemas/NodeInfoSchema.kt | 14 --- .../net/corda/core/flows/AttachmentTests.kt | 2 +- .../core/flows/CollectSignaturesFlowTests.kt | 7 +- .../core/flows/ContractUpgradeFlowTest.kt | 6 +- .../net/corda/core/flows/FinalityFlowTests.kt | 3 +- .../corda/core/flows/IdentitySyncFlowTests.kt | 4 +- .../core/flows/ManualFinalityFlowTests.kt | 3 +- .../internal/ResolveTransactionsFlowTest.kt | 3 +- .../net/corda/core/node/ServiceInfoTests.kt | 38 ------- .../AttachmentSerializationTest.kt | 2 +- docs/source/changelog.rst | 13 +++ .../corda/docs/IntegrationTestingTutorial.kt | 5 +- .../java/net/corda/docs/FlowCookbookJava.java | 17 ++-- .../net/corda/docs/ClientRpcTutorial.kt | 7 +- .../net/corda/docs/CustomNotaryTutorial.kt | 2 +- .../kotlin/net/corda/docs/CustomVaultQuery.kt | 3 +- .../kotlin/net/corda/docs/FlowCookbook.kt | 17 ++-- .../net/corda/docs/CustomVaultQueryTest.kt | 10 +- .../docs/FxTransactionBuildTutorialTest.kt | 10 +- .../WorkflowTransactionBuildTutorialTest.kt | 2 +- docs/source/flow-state-machines.rst | 2 +- docs/source/flow-testing.rst | 2 +- .../corda/finance/flows/TwoPartyDealFlow.kt | 20 ++-- .../corda/finance/flows/TwoPartyTradeFlow.kt | 1 - .../corda/finance/flows/CashExitFlowTests.kt | 3 +- .../corda/finance/flows/CashIssueFlowTests.kt | 3 +- .../finance/flows/CashPaymentFlowTests.kt | 5 +- .../kotlin/net/corda/nodeapi}/ServiceInfo.kt | 2 +- .../kotlin/net/corda/nodeapi}/ServiceType.kt | 11 +-- .../kotlin/net/corda/node/BootTests.kt | 8 +- .../net/corda/node/NodePerformanceTests.kt | 5 +- .../node/services/AdvertisedServiceTests.kt | 42 -------- .../node/services/BFTNotaryServiceTests.kt | 13 ++- .../node/services/DistributedServiceTests.kt | 8 +- .../services/messaging/P2PMessagingTest.kt | 5 +- .../test/node/NodeStatePersistenceTests.kt | 2 +- .../net/corda/node/internal/AbstractNode.kt | 38 ++++--- .../corda/node/internal/CordaRPCOpsImpl.kt | 7 +- .../kotlin/net/corda/node/internal/Node.kt | 2 +- .../net/corda/node/internal/NodeStartup.kt | 2 +- .../node/internal/cordapp/CordappLoader.kt | 5 - .../corda/node/services/CoreFlowHandlers.kt | 2 +- .../node/services/api/RegulatorService.kt | 12 --- .../node/services/config/NodeConfiguration.kt | 2 +- .../services/network/NetworkMapService.kt | 3 +- .../network/PersistentNetworkMapCache.kt | 32 ++++-- .../transactions/SimpleNotaryService.kt | 2 +- .../transactions/ValidatingNotaryFlow.kt | 2 +- .../transactions/ValidatingNotaryService.kt | 2 +- .../net/corda/node/CordaRPCOpsImplTest.kt | 13 ++- .../node/messaging/InMemoryMessagingTests.kt | 2 +- .../node/messaging/TwoPartyTradeFlowTests.kt | 56 ++++++----- .../corda/node/services/NotaryChangeTests.kt | 44 +++++---- .../services/events/ScheduledFlowTests.kt | 2 +- .../network/AbstractNetworkMapServiceTest.kt | 3 +- .../services/network/NetworkMapCacheTest.kt | 2 +- .../network/PersistentNetworkMapCacheTest.kt | 19 ++-- .../PersistentNetworkMapServiceTest.kt | 2 +- .../statemachine/FlowFrameworkTests.kt | 23 +++-- .../transactions/NotaryServiceTests.kt | 20 ++-- .../ValidatingNotaryServiceTests.kt | 14 ++- .../attachmentdemo/AttachmentDemoTest.kt | 2 +- .../kotlin/net/corda/attachmentdemo/Main.kt | 2 +- .../net/corda/bank/BankOfCordaHttpAPITest.kt | 2 +- .../corda/bank/BankOfCordaRPCClientTest.kt | 7 +- .../net/corda/bank/BankOfCordaDriver.kt | 6 +- .../corda/bank/api/BankOfCordaClientApi.kt | 5 +- .../net/corda/bank/api/BankOfCordaWebApi.kt | 4 +- .../kotlin/net/corda/irs/IRSDemoTest.kt | 2 +- .../net/corda/irs/flows/AutoOfferFlow.kt | 4 +- .../kotlin/net/corda/irs/flows/FixingFlow.kt | 4 +- .../src/test/kotlin/net/corda/irs/Main.kt | 2 +- .../corda/irs/flows/UpdateBusinessDayFlow.kt | 8 +- .../corda/netmap/simulation/IRSSimulation.kt | 3 +- .../net/corda/netmap/simulation/Simulation.kt | 4 +- .../net/corda/notarydemo/BFTNotaryCordform.kt | 2 +- .../kotlin/net/corda/notarydemo/Notarise.kt | 3 +- .../corda/notarydemo/RaftNotaryCordform.kt | 2 +- .../corda/notarydemo/SingleNotaryCordform.kt | 2 +- .../net/corda/vega/SimmValuationTest.kt | 2 +- .../kotlin/net/corda/vega/api/PortfolioApi.kt | 10 +- .../net/corda/vega/flows/IRSTradeFlow.kt | 6 +- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 4 +- .../src/test/kotlin/net/corda/vega/Main.kt | 2 +- .../net/corda/traderdemo/TraderDemoTest.kt | 2 +- .../corda/traderdemo/TraderDemoClientApi.kt | 10 +- .../net/corda/traderdemo/flow/BuyerFlow.kt | 5 +- .../net/corda/traderdemo/flow/SellerFlow.kt | 3 +- .../test/kotlin/net/corda/traderdemo/Main.kt | 2 +- .../net/corda/testing/driver/DriverTests.kt | 5 +- .../node/testing/MockServiceHubInternal.kt | 3 + .../net/corda/testing/DriverConstants.kt | 2 +- .../kotlin/net/corda/testing/driver/Driver.kt | 6 +- .../testing/internal/demorun/CordformUtils.kt | 2 +- .../testing/node/InMemoryMessagingNetwork.kt | 12 +-- .../kotlin/net/corda/testing/node/MockNode.kt | 40 ++++---- .../net/corda/testing/node/MockServices.kt | 1 + .../net/corda/testing/node/NodeBasedTest.kt | 4 +- .../kotlin/net/corda/testing/CoreTestUtils.kt | 3 + .../corda/demobench/model/InstallFactory.kt | 4 +- .../corda/demobench/model/NodeController.kt | 4 +- .../net/corda/explorer/ExplorerSimulation.kt | 13 ++- .../net/corda/explorer/model/IssuerModel.kt | 22 ++--- .../net/corda/explorer/views/Network.kt | 3 +- .../views/cordapps/cash/NewTransaction.kt | 10 +- .../kotlin/net/corda/loadtest/Disruption.kt | 7 +- .../kotlin/net/corda/loadtest/LoadTest.kt | 13 ++- .../main/kotlin/net/corda/loadtest/Main.kt | 4 +- .../net/corda/loadtest/tests/CrossCashTest.kt | 3 +- .../net/corda/loadtest/tests/NotaryTest.kt | 2 +- .../net/corda/loadtest/tests/SelfIssueTest.kt | 4 +- .../net/corda/loadtest/tests/StabilityTest.kt | 3 +- .../net/corda/verifier/VerifierTests.kt | 5 +- 122 files changed, 467 insertions(+), 615 deletions(-) rename {core/src/main/kotlin/net/corda/core/node/services => node-api/src/main/kotlin/net/corda/nodeapi}/ServiceInfo.kt (96%) rename {core/src/main/kotlin/net/corda/core/node/services => node-api/src/main/kotlin/net/corda/nodeapi}/ServiceType.kt (79%) delete mode 100644 node/src/integration-test/kotlin/net/corda/node/services/AdvertisedServiceTests.kt delete mode 100644 node/src/main/kotlin/net/corda/node/services/api/RegulatorService.kt diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt index 99554d5e1f..0fe1b48557 100644 --- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt +++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt @@ -9,6 +9,7 @@ import net.corda.core.crypto.keys import net.corda.core.flows.FlowInitiator import net.corda.core.flows.StateMachineRunId import net.corda.core.identity.CordaX500Name +import net.corda.core.identity.Party import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.StateMachineTransactionMapping @@ -16,7 +17,6 @@ import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.startFlow import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.OpaqueBytes @@ -27,7 +27,7 @@ import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.node.services.network.NetworkMapService +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.* @@ -39,7 +39,7 @@ import rx.Observable class NodeMonitorModelTest : DriverBasedTest() { lateinit var aliceNode: NodeInfo lateinit var bobNode: NodeInfo - lateinit var notaryNode: NodeInfo + lateinit var notaryParty: Party lateinit var rpc: CordaRPCOps lateinit var rpcBob: CordaRPCOps @@ -59,11 +59,9 @@ class NodeMonitorModelTest : DriverBasedTest() { startFlowPermission()) ) val aliceNodeFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(cashUser)) - val notaryNodeFuture = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) + val notaryHandle = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))).getOrThrow() val aliceNodeHandle = aliceNodeFuture.getOrThrow() - val notaryNodeHandle = notaryNodeFuture.getOrThrow() aliceNode = aliceNodeHandle.nodeInfo - notaryNode = notaryNodeHandle.nodeInfo newNode = { nodeName -> startNode(providedName = nodeName).getOrThrow().nodeInfo } val monitor = NodeMonitorModel() stateMachineTransactionMapping = monitor.stateMachineTransactionMapping.bufferUntilSubscribed() @@ -75,6 +73,7 @@ class NodeMonitorModelTest : DriverBasedTest() { monitor.register(aliceNodeHandle.configuration.rpcAddress!!, cashUser.username, cashUser.password, initialiseSerialization = false) rpc = monitor.proxyObservable.value!! + notaryParty = notaryHandle.nodeInfo.legalIdentities[1] val bobNodeHandle = startNode(providedName = BOB.name, rpcUsers = listOf(cashUser)).getOrThrow() bobNode = bobNodeHandle.nodeInfo @@ -87,9 +86,9 @@ class NodeMonitorModelTest : DriverBasedTest() { @Test fun `network map update`() { - newNode(CHARLIE.name) - networkMapUpdates.filter { !it.node.advertisedServices.any { it.info.type.isNotary() } } - .filter { !it.node.advertisedServices.any { it.info.type == NetworkMapService.type } } + val charlieNode = newNode(CHARLIE.name) + val nonServiceIdentities = aliceNode.legalIdentitiesAndCerts + bobNode.legalIdentitiesAndCerts + charlieNode.legalIdentitiesAndCerts + networkMapUpdates.filter { it.node.legalIdentitiesAndCerts.any { it in nonServiceIdentities } } .expectEvents(isStrict = false) { sequence( // TODO : Add test for remove when driver DSL support individual node shutdown. @@ -111,7 +110,7 @@ class NodeMonitorModelTest : DriverBasedTest() { rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), - notaryNode.notaryIdentity + notaryParty ) vaultUpdates.expectEvents(isStrict = false) { @@ -132,7 +131,7 @@ class NodeMonitorModelTest : DriverBasedTest() { @Test fun `cash issue and move`() { - val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow() + val (_, issueIdentity) = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes.of(1), notaryParty).returnValue.getOrThrow() rpc.startFlow(::CashPaymentFlow, 100.DOLLARS, bobNode.chooseIdentity()).returnValue.getOrThrow() var issueSmId: StateMachineRunId? = null @@ -191,7 +190,7 @@ class NodeMonitorModelTest : DriverBasedTest() { val signaturePubKeys = stx.sigs.map { it.by }.toSet() // Alice and Notary signed require(issueIdentity!!.owningKey.isFulfilledBy(signaturePubKeys)) - require(notaryNode.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys)) + require(notaryParty.owningKey.isFulfilledBy(signaturePubKeys)) moveTx = stx } ) diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt index 7977f93e2f..93d76405a5 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt @@ -7,8 +7,8 @@ import javafx.collections.FXCollections import javafx.collections.ObservableList import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.map -import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty +import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache.MapChange import java.security.PublicKey @@ -33,25 +33,13 @@ class NetworkIdentityModel { private val identityCache = CacheBuilder.newBuilder() .build>(CacheLoader.from { publicKey -> - publicKey?.let { rpcProxy.map { it?.nodeIdentityFromParty(AnonymousParty(publicKey)) } } + publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } } }) - val parties: ObservableList = networkIdentities.filtered { !it.isCordaService() } - val notaries: ObservableList = networkIdentities.filtered { it.advertisedServices.any { it.info.type.isNotary() } } - val myNodeInfo = rpcProxy.map { it?.nodeInfo() } // TODO Used only for querying for advertised services, remove with services. - val myIdentity = myNodeInfo.map { it?.legalIdentitiesAndCerts?.first()?.party } - - private fun NodeInfo.isCordaService(): Boolean { - // TODO: better way to identify Corda service? - return advertisedServices.any { it.info.type.isNetworkMap() || it.info.type.isNotary() } - } + val notaries: ObservableList = FXCollections.observableList(rpcProxy.value?.notaryIdentities()) + val notaryNodes: ObservableList = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it.party) }) + val parties: ObservableList = networkIdentities.filtered { it.legalIdentitiesAndCerts.all { it !in notaries } } + val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party } fun partyFromPublicKey(publicKey: PublicKey): ObservableValue = identityCache[publicKey] - //TODO rebase fix -// // TODO: Use Identity Service in service hub instead? -// fun lookup(publicKey: PublicKey): ObservableValue { -// val party = parties.flatMap { it.legalIdentitiesAndCerts }.firstOrNull { publicKey in it.owningKey.keys } ?: -// notaries.flatMap { it.legalIdentitiesAndCerts }.firstOrNull { it.owningKey.keys.any { it == publicKey }} -// return ReadOnlyObjectWrapper(party) -// } } diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt index 7bd9623f52..434b405d2d 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt @@ -5,6 +5,7 @@ import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClientConfiguration import net.corda.core.contracts.ContractState import net.corda.core.flows.StateMachineRunId +import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.* import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.Vault @@ -45,6 +46,7 @@ class NodeMonitorModel { val networkMap: Observable = networkMapSubject val proxyObservable = SimpleObjectProperty() + lateinit var notaryIdentities: List /** * Register for updates to/from a given vault. @@ -60,6 +62,7 @@ class NodeMonitorModel { ) val connection = client.start(username, password) val proxy = connection.proxy + notaryIdentities = proxy.notaryIdentities() val (stateMachines, stateMachineUpdates) = proxy.stateMachinesFeed() // Extract the flow tracking stream diff --git a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java index b01c9f340d..29a86c00aa 100644 --- a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java +++ b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java @@ -5,7 +5,6 @@ import net.corda.core.concurrent.CordaFuture; import net.corda.core.contracts.Amount; import net.corda.core.messaging.CordaRPCOps; import net.corda.core.messaging.FlowHandle; -import net.corda.core.node.services.ServiceInfo; import net.corda.core.utilities.OpaqueBytes; import net.corda.finance.flows.AbstractCashFlow; import net.corda.finance.flows.CashIssueFlow; @@ -14,6 +13,7 @@ import net.corda.finance.schemas.*; import net.corda.node.internal.Node; import net.corda.node.internal.StartedNode; import net.corda.node.services.transactions.ValidatingNotaryService; +import net.corda.nodeapi.ServiceInfo; import net.corda.nodeapi.User; import net.corda.testing.CoreTestUtils; import net.corda.testing.node.NodeBasedTest; diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt index b73622da24..03401224c2 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt @@ -6,7 +6,6 @@ import net.corda.core.messaging.FlowProgressHandle import net.corda.core.messaging.StateMachineUpdate import net.corda.core.messaging.startFlow import net.corda.core.messaging.startTrackedFlow -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow import net.corda.finance.DOLLARS @@ -20,6 +19,7 @@ import net.corda.finance.schemas.CashSchemaV1 import net.corda.node.internal.Node import net.corda.node.internal.StartedNode import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index ee5b36ef9a..a6bf3c63cb 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -9,6 +9,7 @@ import net.corda.core.flows.StateMachineRunId import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.Vault @@ -212,6 +213,11 @@ interface CordaRPCOps : RPCOps { */ fun nodeInfo(): NodeInfo + /** + * Returns network's notary identities, assuming this will not change while the node is running. + */ + fun notaryIdentities(): List + /* * Add note(s) to an existing Vault transaction */ @@ -284,11 +290,11 @@ interface CordaRPCOps : RPCOps { fun registeredFlows(): List /** - * Returns a node's identity from the network map cache, where known. + * Returns a node's info from the network map cache, where known. * * @return the node info if available. */ - fun nodeIdentityFromParty(party: AbstractParty): NodeInfo? + fun nodeInfoFromParty(party: AbstractParty): NodeInfo? /** * Clear all network map data from local node cache. diff --git a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt index 5f5ba9eda0..4abfca9b92 100644 --- a/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt +++ b/core/src/main/kotlin/net/corda/core/node/NodeInfo.kt @@ -2,37 +2,24 @@ package net.corda.core.node import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.NetworkHostAndPort -/** - * Information for an advertised service including the service specific identity information. - * The identity can be used in flows and is distinct from the Node's legalIdentity - */ -@CordaSerializable -data class ServiceEntry(val info: ServiceInfo, val identity: PartyAndCertificate) - /** * Info about a network node that acts on behalf of some form of contract party. + * @param legalIdentitiesAndCerts is a non-empty list, where the first identity is assumed to be the default identity of the node. */ // TODO We currently don't support multi-IP/multi-identity nodes, we only left slots in the data structures. @CordaSerializable data class NodeInfo(val addresses: List, - /** Non-empty list of all the identities, plus certificates, that belong to this node. */ val legalIdentitiesAndCerts: List, val platformVersion: Int, - val advertisedServices: List = emptyList(), val serial: Long ) { init { require(legalIdentitiesAndCerts.isNotEmpty()) { "Node should have at least one legal identity" } } - // TODO This part will be removed with services removal. - val notaryIdentity: Party get() = advertisedServices.single { it.info.type.isNotary() }.identity.party - @Transient private var _legalIdentities: List? = null val legalIdentities: List get() { return _legalIdentities ?: legalIdentitiesAndCerts.map { it.party }.also { _legalIdentities = it } @@ -40,8 +27,4 @@ data class NodeInfo(val addresses: List, /** Returns true if [party] is one of the identities of this node, else false. */ fun isLegalIdentity(party: Party): Boolean = party in legalIdentities - - fun serviceIdentities(type: ServiceType): List { - return advertisedServices.mapNotNull { if (it.info.type.isSubTypeOf(type)) it.identity.party else null } - } } diff --git a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt index eac55ab2b1..d5688c1fdf 100644 --- a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt @@ -143,7 +143,9 @@ interface ServiceHub : ServicesForResolution { * If the key is actually a [net.corda.core.crypto.CompositeKey], the first leaf key hosted on this node * will be used to create the signature. */ - val notaryIdentityKey: PublicKey get() = this.myInfo.notaryIdentity.owningKey + // TODO Remove that from ServiceHub, we could take that information from a transaction notary field and figure out what key to use from that. + // But, it's separate PR. + val notaryIdentityKey: PublicKey // Helper method to construct an initial partially signed transaction from a [TransactionBuilder]. private fun signInitialTransaction(builder: TransactionBuilder, publicKey: PublicKey, signatureMetadata: SignatureMetadata): SignedTransaction { diff --git a/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt b/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt index 4828643044..d19541eef3 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt @@ -5,10 +5,10 @@ import net.corda.core.contracts.Contract import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.randomOrNull import net.corda.core.messaging.DataFeed import net.corda.core.node.NodeInfo -import net.corda.core.node.ServiceEntry import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.NetworkHostAndPort import rx.Observable @@ -31,18 +31,9 @@ interface NetworkMapCache { data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange() } - /** A list of all nodes the cache is aware of */ - val partyNodes: List - /** A list of nodes that advertise a network map service */ - val networkMapNodes: List - /** A list of nodes that advertise a notary service */ - val notaryNodes: List get() = getNodesWithService(ServiceType.notary) - /** - * A list of nodes that advertise a regulatory service. Identifying the correct regulator for a trade is outside - * the scope of the network map service, and this is intended solely as a sanity check on configuration stored - * elsewhere. - */ - val regulatorNodes: List get() = getNodesWithService(ServiceType.regulator) + /** A list of notary services available on the network */ + // TODO this list will be taken from NetworkParameters distributed by NetworkMap. + val notaryIdentities: List /** Tracks changes to the network map cache */ val changed: Observable /** Future to track completion of the NetworkMapService registration. */ @@ -54,26 +45,6 @@ interface NetworkMapCache { */ fun track(): DataFeed, MapChange> - /** Get the collection of nodes which advertise a specific service. */ - fun getNodesWithService(serviceType: ServiceType): List { - return partyNodes.filter { it.advertisedServices.any { it.info.type.isSubTypeOf(serviceType) } } - } - - // TODO It will be removed with services + part of these functions will get merged into database backed NetworkMapCache - fun getPeersWithService(serviceType: ServiceType): List { - return partyNodes.fold(ArrayList()) { - acc, elem -> acc.addAll(elem.advertisedServices.filter { it.info.type.isSubTypeOf(serviceType)}) - acc - } - } - - /** - * Get a recommended node that advertises a service, and is suitable for the specified contract and parties. - * Implementations might understand, for example, the correct regulator to use for specific contracts/parties, - * or the appropriate oracle for a contract. - */ - fun getRecommended(type: ServiceType, contract: Contract, vararg party: Party): NodeInfo? = getNodesWithService(type).firstOrNull() - /** * Look up the node info for a specific party. Will attempt to de-anonymise the party if applicable; if the party * is anonymised and the well known party cannot be resolved, it is impossible ot identify the node and therefore this @@ -86,81 +57,47 @@ interface NetworkMapCache { fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? /** Look up the node info for a legal name. */ - fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? + fun getNodeByLegalName(name: CordaX500Name): NodeInfo? /** Look up the node info for a host and port. */ fun getNodeByAddress(address: NetworkHostAndPort): NodeInfo? - fun getPeerByLegalName(principal: CordaX500Name): Party? = getNodeByLegalName(principal)?.let { - it.legalIdentitiesAndCerts.singleOrNull { it.name == principal }?.party + fun getPeerByLegalName(name: CordaX500Name): Party? = getNodeByLegalName(name)?.let { + it.legalIdentitiesAndCerts.singleOrNull { it.name == name }?.party } + /** Return all [NodeInfo]s the node currently is aware of (including ourselves). */ + val allNodes: List + /** + * Look up the node infos for a specific peer key. * In general, nodes can advertise multiple identities: a legal identity, and separate identities for each of * the services it provides. In case of a distributed service – run by multiple nodes – each participant advertises * the identity of the *whole group*. */ - /** Look up the node infos for a specific peer key. */ fun getNodesByLegalIdentityKey(identityKey: PublicKey): List - /** Look up all nodes advertising the service owned by [publicKey] */ - fun getNodesByAdvertisedServiceIdentityKey(publicKey: PublicKey): List { - return partyNodes.filter { it.advertisedServices.any { it.identity.owningKey == publicKey } } - } - /** Returns information about the party, which may be a specific node or a service */ fun getPartyInfo(party: Party): PartyInfo? /** Gets a notary identity by the given name. */ - fun getNotary(principal: CordaX500Name): Party? { - val notaryNode = notaryNodes.filter { - it.advertisedServices.any { it.info.type.isSubTypeOf(ServiceType.notary) && it.info.name == principal } - }.randomOrNull() - return notaryNode?.notaryIdentity - } + fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }?.party /** * Returns a notary identity advertised by any of the nodes on the network (chosen at random) * @param type Limits the result to notaries of the specified type (optional) */ - fun getAnyNotary(type: ServiceType? = null): Party? { - val nodes = if (type == null) { - notaryNodes - } else { - require(type != ServiceType.notary && type.isSubTypeOf(ServiceType.notary)) { - "The provided type must be a specific notary sub-type" - } - notaryNodes.filter { it.advertisedServices.any { it.info.type == type } } - } - return nodes.randomOrNull()?.notaryIdentity - } - - /** - * Returns a service identity advertised by one of the nodes on the network - * @param type Specifies the type of the service - */ - fun getAnyServiceOfType(type: ServiceType): Party? { - for (node in partyNodes) { - val serviceIdentities = node.serviceIdentities(type) - if (serviceIdentities.isNotEmpty()) { - return serviceIdentities.randomOrNull() - } - } - return null; - } + fun getAnyNotary(): Party? = notaryIdentities.randomOrNull()?.party /** Checks whether a given party is an advertised notary identity */ - fun isNotary(party: Party): Boolean = notaryNodes.any { it.notaryIdentity == party } + fun isNotary(party: Party): Boolean = notaryIdentities.any { party == it.party } - /** Checks whether a given party is an advertised validating notary identity */ + /** Checks whether a given party is an validating notary identity */ fun isValidatingNotary(party: Party): Boolean { - val notary = notaryNodes.firstOrNull { it.notaryIdentity == party } - ?: throw IllegalArgumentException("No notary found with identity $party. This is most likely caused " + - "by using the notary node's legal identity instead of its advertised notary identity. " + - "Your options are: ${notaryNodes.map { "\"${it.notaryIdentity.name}\"" }.joinToString()}.") - return notary.advertisedServices.any { it.info.type.isValidatingNotary() } + val notary = notaryIdentities.firstOrNull { it.party == party } ?: + throw IllegalArgumentException("No notary found with identity $party.") + return !notary.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters. } - /** * Clear all network map data from local node cache. */ diff --git a/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt b/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt index 64fc6e1148..8e019d7b5b 100644 --- a/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt +++ b/core/src/main/kotlin/net/corda/core/schemas/NodeInfoSchema.kt @@ -2,7 +2,6 @@ package net.corda.core.schemas import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo -import net.corda.core.node.ServiceEntry import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.NetworkHostAndPort @@ -39,10 +38,6 @@ object NodeInfoSchemaV1 : MappedSchema( @Column(name = "platform_version") val platformVersion: Int, - @Column(name = "advertised_services") - @ElementCollection - var advertisedServices: List = emptyList(), - /** * serial is an increasing value which represents the version of [NodeInfo]. * Not expected to be sequential, but later versions of the registration must have higher values @@ -56,9 +51,6 @@ object NodeInfoSchemaV1 : MappedSchema( this.addresses.map { it.toHostAndPort() }, (this.legalIdentitiesAndCerts.filter { it.isMain } + this.legalIdentitiesAndCerts.filter { !it.isMain }).map { it.toLegalIdentityAndCert() }, this.platformVersion, - this.advertisedServices.map { - it.serviceEntry?.deserialize() ?: throw IllegalStateException("Service entry shouldn't be null") - }, this.serial ) } @@ -85,12 +77,6 @@ object NodeInfoSchemaV1 : MappedSchema( } } - @Embeddable // TODO To be removed with services. - data class DBServiceEntry( - @Column(length = 65535) - val serviceEntry: ByteArray? = null - ) - /** * PartyAndCertificate entity (to be replaced by referencing final Identity Schema). */ diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt index f1f743ef5c..e1511eaa77 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -8,9 +8,9 @@ import net.corda.core.identity.Party import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchDataFlow import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.NodeAttachmentService diff --git a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt index 9de4df3c82..540a8a3546 100644 --- a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt @@ -16,6 +16,7 @@ import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentityAndCert import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyContract +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockServices import org.junit.After @@ -39,8 +40,8 @@ class CollectSignaturesFlowTests { a = nodes.partyNodes[0] b = nodes.partyNodes[1] c = nodes.partyNodes[2] - notary = nodes.notaryNode.info.notaryIdentity mockNet.runNetwork() + notary = a.services.getDefaultNotary() a.internals.ensureRegistered() } @@ -86,7 +87,7 @@ class CollectSignaturesFlowTests { @Suspendable override fun call(): SignedTransaction { val state = receive(otherParty).unwrap { it } - val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity + val notary = serviceHub.getDefaultNotary() val myInputKeys = state.participants.map { it.owningKey } val myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey @@ -107,7 +108,7 @@ class CollectSignaturesFlowTests { class Initiator(val state: DummyContract.MultiOwnerState) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - val notary = serviceHub.networkMapCache.notaryNodes.single().notaryIdentity + val notary = serviceHub.getDefaultNotary() val myInputKeys = state.participants.map { it.owningKey } val command = Command(DummyContract.Commands.Create(), myInputKeys) val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 9169322de4..69a2d06d79 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -25,6 +25,7 @@ import net.corda.testing.RPCDriverExposedDSLInterface import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContractV2 +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import net.corda.testing.rpcDriver import net.corda.testing.rpcTestUser @@ -54,9 +55,8 @@ class ContractUpgradeFlowTest { mockNet.runNetwork() a.internals.ensureRegistered() - notary = nodes.notaryNode.info.notaryIdentity - - val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == nodes.notaryNode.info.notaryIdentity } + notary = a.services.getDefaultNotary() + val nodeIdentity = nodes.notaryNode.info.legalIdentitiesAndCerts.single { it.party == notary } a.database.transaction { a.services.identityService.verifyAndRegisterIdentity(nodeIdentity) } diff --git a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt index cc32c48e16..48e7df3537 100644 --- a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt @@ -10,6 +10,7 @@ import net.corda.finance.contracts.asset.Cash import net.corda.testing.ALICE import net.corda.node.internal.StartedNode import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockServices import org.junit.After @@ -31,9 +32,9 @@ class FinalityFlowTests { val nodes = mockNet.createSomeNodes(2) nodeA = nodes.partyNodes[0] nodeB = nodes.partyNodes[1] - notary = nodes.notaryNode.info.notaryIdentity mockNet.runNetwork() nodeA.internals.ensureRegistered() + notary = nodeA.services.getDefaultNotary() } @After diff --git a/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt index 79232e14c0..f75635d418 100644 --- a/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt @@ -13,6 +13,7 @@ import net.corda.testing.ALICE import net.corda.testing.BOB import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Before @@ -47,7 +48,8 @@ class IdentitySyncFlowTests { // Alice issues then pays some cash to a new confidential identity that Bob doesn't know about val anonymous = true val ref = OpaqueBytes.of(0x01) - val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notaryNode.services.myInfo.notaryIdentity)) + val notary = aliceNode.services.getDefaultNotary() + val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary)) val issueTx = issueFlow.resultFuture.getOrThrow().stx val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance().single().owner assertNull(bobNode.database.transaction { bobNode.services.identityService.partyFromAnonymous(confidentialIdentity) }) diff --git a/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt index 68492b0216..88505ebbfc 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt @@ -9,6 +9,7 @@ import net.corda.finance.GBP import net.corda.finance.contracts.asset.Cash import net.corda.node.internal.StartedNode import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockServices import org.junit.After @@ -32,9 +33,9 @@ class ManualFinalityFlowTests { nodeA = nodes.partyNodes[0] nodeB = nodes.partyNodes[1] nodeC = nodes.partyNodes[2] - notary = nodes.notaryNode.info.notaryIdentity mockNet.runNetwork() nodeA.internals.ensureRegistered() + notary = nodeA.services.getDefaultNotary() } @After diff --git a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt index 84a7a79947..dc752b1da0 100644 --- a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt @@ -17,6 +17,7 @@ import net.corda.testing.MEGA_CORP_KEY import net.corda.testing.MINI_CORP import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DummyContract +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockServices import org.junit.After @@ -47,8 +48,8 @@ class ResolveTransactionsFlowTest { b = nodes.partyNodes[1] a.internals.registerInitiatedFlow(TestResponseFlow::class.java) b.internals.registerInitiatedFlow(TestResponseFlow::class.java) - notary = nodes.notaryNode.info.notaryIdentity mockNet.runNetwork() + notary = a.services.getDefaultNotary() } @After diff --git a/core/src/test/kotlin/net/corda/core/node/ServiceInfoTests.kt b/core/src/test/kotlin/net/corda/core/node/ServiceInfoTests.kt index 0855ee1bbf..e69de29bb2 100644 --- a/core/src/test/kotlin/net/corda/core/node/ServiceInfoTests.kt +++ b/core/src/test/kotlin/net/corda/core/node/ServiceInfoTests.kt @@ -1,38 +0,0 @@ -package net.corda.core.node - -import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType -import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith - -class ServiceInfoTests { - val serviceType = ServiceType.getServiceType("test", "service").getSubType("subservice") - val name = CordaX500Name(organisation = "Service.name", locality = "London", country = "GB") - - @Test - fun `type and name encodes correctly`() { - assertEquals(ServiceInfo(serviceType, name).toString(), "$serviceType|$name") - } - - @Test - fun `type and name parses correctly`() { - assertEquals(ServiceInfo.parse("$serviceType|$name"), ServiceInfo(serviceType, name)) - } - - @Test - fun `type only encodes correctly`() { - assertEquals(ServiceInfo(serviceType).toString(), "$serviceType") - } - - @Test - fun `type only parses correctly`() { - assertEquals(ServiceInfo.parse("$serviceType"), ServiceInfo(serviceType)) - } - - @Test - fun `invalid encoding throws`() { - assertFailsWith { ServiceInfo.parse("$serviceType|$name|something") } - } -} diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index 8c5cb3fcc0..f935671300 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -10,11 +10,11 @@ import net.corda.core.identity.Party import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchDataFlow import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.NodeAttachmentService diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 01198840c2..4f7e359a92 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -6,6 +6,19 @@ from the previous milestone release. UNRELEASED ---------- +* ``NodeInfo`` and ``NetworkMapCache`` changes: + * Removed ``NodeInfo::legalIdentity`` in preparation for handling of multiple identities. We left list of ``NodeInfo::legalIdentitiesAndCerts``, + the first identity still plays a special role of main node identity. + * We no longer support advertising services in network map. Removed ``NodeInfo::advertisedServices``, ``serviceIdentities`` + and ``notaryIdentity``. + * Removed service methods from ``NetworkMapCache``: ``partyNodes``, ``networkMapNodes``, ``notaryNodes``, ``regulatorNodes``, + ``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, + ``notaryNode``, ``getAnyServiceOfType``. To get all known ``NodeInfo``s call ``allNodes``. + * In preparation for ``NetworkMapService`` redesign and distributing notaries through ``NetworkParameters`` we added + ``NetworkMapCache::notaryIdentities`` list to enable to lookup for notary parties known to the network. Related ``CordaRPCOps::notaryIdentities`` + was introduced. Other special nodes parties like Oracles or Regulators need to be specified directly in CorDapp or flow. + * Moved ``ServiceType`` and ``ServiceInfo`` to ``net.corda.nodeapi`` package as services are only required on node startup. + * Adding enum support to the class carpenter * ``ContractState::contract`` has been moved ``TransactionState::contract`` and it's type has changed to ``String`` in order to diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index 28a2337044..c181ea39c8 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -3,7 +3,6 @@ package net.corda.docs import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow import net.corda.core.messaging.vaultTrackBy -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow @@ -12,6 +11,7 @@ import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.* @@ -56,11 +56,12 @@ class IntegrationTestingTutorial { // START 4 val issueRef = OpaqueBytes.of(0) + val notaryParty = aliceProxy.notaryIdentities().first().party (1..10).map { i -> aliceProxy.startFlow(::CashIssueFlow, i.DOLLARS, issueRef, - notary.nodeInfo.notaryIdentity + notaryParty ).returnValue }.transpose().getOrThrow() // We wait for all of the issuances to run before we start making payments diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java index b09d31c4f3..a02b7183e2 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java @@ -10,7 +10,6 @@ import net.corda.core.flows.*; import net.corda.core.identity.CordaX500Name; import net.corda.core.identity.Party; import net.corda.core.internal.FetchDataFlow; -import net.corda.core.node.services.ServiceType; import net.corda.core.node.services.Vault; import net.corda.core.node.services.Vault.Page; import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria; @@ -54,11 +53,13 @@ public class FlowCookbookJava { private final boolean arg1; private final int arg2; private final Party counterparty; + private final Party regulator; - public InitiatorFlow(boolean arg1, int arg2, Party counterparty) { + public InitiatorFlow(boolean arg1, int arg2, Party counterparty, Party regulator) { this.arg1 = arg1; this.arg2 = arg2; this.counterparty = counterparty; + this.regulator = regulator; } /*---------------------------------- @@ -124,11 +125,11 @@ public class FlowCookbookJava { // We retrieve a notary from the network map. // DOCSTART 1 Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK")); - Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary(null); + Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary(); // Unlike the first two methods, ``getNotaryNodes`` returns a // ``List``. We have to extract the notary identity of // the node we want. - Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryNodes().get(0).getNotaryIdentity(); + Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0).getParty(); // DOCEND 1 // We may also need to identify a specific counterparty. @@ -138,12 +139,6 @@ public class FlowCookbookJava { Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey); // DOCEND 2 - // Finally, we can use the map to identify nodes providing a - // specific service (e.g. a regulator or an oracle). - // DOCSTART 3 - Party regulator = getServiceHub().getNetworkMapCache().getPeersWithService(ServiceType.Companion.getRegulator()).get(0).getIdentity().getParty(); - // DOCEND 3 - /*------------------------------ * SENDING AND RECEIVING DATA * ------------------------------*/ @@ -528,7 +523,7 @@ public class FlowCookbookJava { // We can also choose to send it to additional parties who aren't one // of the state's participants. // DOCSTART 10 - Set additionalParties = ImmutableSet.of(regulator, regulator); + Set additionalParties = ImmutableSet.of(regulator); SignedTransaction notarisedTx2 = subFlow(new FinalityFlow(ImmutableList.of(fullySignedTx), additionalParties, FINALISATION.childProgressTracker())).get(0); // DOCEND 10 diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index a27088cdc3..9c4ca13eef 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -5,17 +5,18 @@ import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.core.messaging.vaultQueryBy import net.corda.core.node.CordaPluginRegistry -import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializationCustomization import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.OpaqueBytes +import net.corda.core.utilities.getOrThrow import net.corda.finance.USD import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE @@ -56,6 +57,7 @@ fun main(args: Array) { // START 2 val client = node.rpcClientToNode() val proxy = client.start("user", "password").proxy + proxy.waitUntilNetworkReady().getOrThrow() thread { generateTransactions(proxy) @@ -111,8 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) { sum + state.state.data.amount.quantity } val issueRef = OpaqueBytes.of(0) - val parties = proxy.networkMapSnapshot() - val notary = parties.first { it.advertisedServices.any { it.info.type.isNotary() } }.notaryIdentity + val notary = proxy.notaryIdentities().first().party val me = proxy.nodeInfo().legalIdentities.first() while (true) { Thread.sleep(1000) diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt index a9509e2d5e..5b46131e95 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt @@ -49,7 +49,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary private fun checkSignatures(stx: SignedTransaction) { try { - stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey) + stx.verifySignaturesExcept(serviceHub.notaryIdentityKey) } catch (e: SignatureException) { throw NotaryException(NotaryError.TransactionInvalid(e)) } diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt index 9f886590ff..b540d11df4 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt @@ -20,6 +20,7 @@ import net.corda.finance.flows.AbstractCashFlow import net.corda.finance.flows.CashException import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow +import net.corda.testing.getDefaultNotary import java.util.* // DOCSTART CustomVaultQuery @@ -132,7 +133,7 @@ object TopupIssuerFlow { issueTo: Party, issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result { // TODO: pass notary in as request parameter - val notaryParty = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity + val notaryParty = serviceHub.networkMapCache.getAnyNotary() ?: throw IllegalArgumentException("Couldn't find any notary in NetworkMapCache") // invoke Cash subflow to issue Asset progressTracker.currentStep = ISSUING val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty) diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt index b434b68a5a..d6a361d7f5 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt @@ -10,7 +10,6 @@ import net.corda.core.flows.* import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.internal.FetchDataFlow -import net.corda.core.node.services.ServiceType import net.corda.core.node.services.Vault.Page import net.corda.core.node.services.queryBy import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria @@ -40,7 +39,7 @@ object FlowCookbook { @StartableByRPC // Every flow must subclass ``FlowLogic``. The generic indicates the // flow's return type. - class InitiatorFlow(val arg1: Boolean, val arg2: Int, val counterparty: Party) : FlowLogic() { + class InitiatorFlow(val arg1: Boolean, val arg2: Int, val counterparty: Party, val regulator: Party) : FlowLogic() { /**--------------------------------- * WIRING UP THE PROGRESS TRACKER * @@ -109,22 +108,18 @@ object FlowCookbook { // Unlike the first two methods, ``getNotaryNodes`` returns a // ``List``. We have to extract the notary identity of // the node we want. - val firstNotary: Party = serviceHub.networkMapCache.notaryNodes[0].notaryIdentity + val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities[0].party // DOCEND 1 // We may also need to identify a specific counterparty. We // do so using identity service. // DOCSTART 2 - val namedCounterparty: Party? = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) - val keyedCounterparty: Party? = serviceHub.identityService.partyFromKey(dummyPubKey) + val namedCounterparty: Party = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) ?: + throw IllegalArgumentException("Couldn't find counterparty for NodeA in identity service") + val keyedCounterparty: Party = serviceHub.identityService.partyFromKey(dummyPubKey) ?: + throw IllegalArgumentException("Couldn't find counterparty with key: $dummyPubKey in identity service") // DOCEND 2 - // Finally, we can use the map to identify nodes providing a - // specific service (e.g. a regulator or an oracle). - // DOCSTART 3 - val regulator: Party = serviceHub.networkMapCache.getPeersWithService(ServiceType.regulator)[0].identity.party - // DOCEND 3 - /**----------------------------- * SENDING AND RECEIVING DATA * -----------------------------**/ diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt index 65e6cacf3a..182248414c 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt @@ -1,7 +1,7 @@ package net.corda.docs import net.corda.core.contracts.Amount -import net.corda.core.node.services.ServiceInfo +import net.corda.core.identity.Party import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow import net.corda.finance.* @@ -9,11 +9,13 @@ import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.StartedNode import net.corda.finance.schemas.CashSchemaV1 +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Assert @@ -27,6 +29,7 @@ class CustomVaultQueryTest { lateinit var notaryNode: StartedNode lateinit var nodeA: StartedNode lateinit var nodeB: StartedNode + lateinit var notary: Party @Before fun setup() { @@ -43,6 +46,7 @@ class CustomVaultQueryTest { nodeA.internals.installCordaService(CustomVaultQuery.Service::class.java) nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1)) + notary = nodeA.services.getDefaultNotary() } @After @@ -71,7 +75,7 @@ class CustomVaultQueryTest { // Use NodeA as issuer and create some dollars val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(amountToIssue, OpaqueBytes.of(0x01), - notaryNode.info.notaryIdentity)) + notary)) // Wait for the flow to stop and print flowHandle1.resultFuture.getOrThrow() } @@ -81,7 +85,7 @@ class CustomVaultQueryTest { nodeA.info.chooseIdentity(), OpaqueBytes.of(0x01), nodeA.info.chooseIdentity(), - notaryNode.info.notaryIdentity)) + notary)) flowHandle1.resultFuture.getOrThrow() } diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt index 734b258ce1..fc84e71509 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt @@ -1,6 +1,6 @@ package net.corda.docs -import net.corda.core.node.services.ServiceInfo +import net.corda.core.identity.Party import net.corda.core.toFuture import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow @@ -9,11 +9,13 @@ import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.StartedNode import net.corda.finance.schemas.CashSchemaV1 +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Before @@ -25,6 +27,7 @@ class FxTransactionBuildTutorialTest { lateinit var notaryNode: StartedNode lateinit var nodeA: StartedNode lateinit var nodeB: StartedNode + lateinit var notary: Party @Before fun setup() { @@ -39,6 +42,7 @@ class FxTransactionBuildTutorialTest { nodeA.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeB.internals.registerCustomSchemas(setOf(CashSchemaV1)) nodeB.internals.registerInitiatedFlow(ForeignExchangeRemoteFlow::class.java) + notary = nodeA.services.getDefaultNotary() } @After @@ -51,7 +55,7 @@ class FxTransactionBuildTutorialTest { // Use NodeA as issuer and create some dollars val flowHandle1 = nodeA.services.startFlow(CashIssueFlow(DOLLARS(1000), OpaqueBytes.of(0x01), - notaryNode.info.notaryIdentity)) + notary)) // Wait for the flow to stop and print flowHandle1.resultFuture.getOrThrow() printBalances() @@ -59,7 +63,7 @@ class FxTransactionBuildTutorialTest { // Using NodeB as Issuer create some pounds. val flowHandle2 = nodeB.services.startFlow(CashIssueFlow(POUNDS(1000), OpaqueBytes.of(0x01), - notaryNode.info.notaryIdentity)) + notary)) // Wait for flow to come to an end and print flowHandle2.resultFuture.getOrThrow() printBalances() diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt index 809010552f..604b63f676 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt @@ -4,12 +4,12 @@ import net.corda.core.contracts.LinearState import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.UniqueIdentifier import net.corda.core.node.ServiceHub -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.queryBy import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.toFuture import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.DUMMY_NOTARY diff --git a/docs/source/flow-state-machines.rst b/docs/source/flow-state-machines.rst index 4aa5c5369d..2ca3b56759 100644 --- a/docs/source/flow-state-machines.rst +++ b/docs/source/flow-state-machines.rst @@ -331,7 +331,7 @@ the initiator then the buyer side would need to register their flow, perhaps wit services.registerServiceFlow(TwoPartyTradeFlow.Seller::class.java) { TwoPartyTradeFlow.Buyer( it, - notary = services.networkMapCache.notaryNodes[0].notaryIdentity, + notary = services.networkMapCache.notaryIdentities[0].party, acceptablePrice = TODO(), typeToBuy = TODO()) } diff --git a/docs/source/flow-testing.rst b/docs/source/flow-testing.rst index acf3e86be2..1d53696b61 100644 --- a/docs/source/flow-testing.rst +++ b/docs/source/flow-testing.rst @@ -31,8 +31,8 @@ with this basic skeleton: val nodes = mockNet.createSomeNodes() a = nodes.partyNodes[0] b = nodes.partyNodes[1] - notary = nodes.notaryNode.info.notaryIdentity mockNet.runNetwork() + notary = a.services.getDefaultNotary() } @After diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index 956b1b250e..9aeb2bd755 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -11,8 +11,6 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.SignTransactionFlow import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party -import net.corda.core.node.NodeInfo -import net.corda.core.node.services.ServiceType import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder @@ -51,7 +49,7 @@ object TwoPartyDealFlow { } abstract val payload: Any - abstract val notaryNode: NodeInfo + abstract val notaryParty: Party abstract val otherParty: Party @Suspendable override fun call(): SignedTransaction { @@ -82,7 +80,8 @@ object TwoPartyDealFlow { /** * Abstracted bilateral deal flow participant that is recipient of initial communication. */ - abstract class Secondary(override val progressTracker: ProgressTracker = Secondary.tracker()) : FlowLogic() { + abstract class Secondary(override val progressTracker: ProgressTracker = Secondary.tracker(), + val regulators: List = emptyList()) : FlowLogic() { companion object { object RECEIVING : ProgressTracker.Step("Waiting for deal info.") @@ -126,12 +125,10 @@ object TwoPartyDealFlow { logger.trace { "Recorded transaction." } progressTracker.currentStep = COPYING_TO_REGULATOR - val regulators = serviceHub.networkMapCache.regulatorNodes - if (regulators.isNotEmpty()) { - // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's - // just for demo purposes. - regulators.forEach { send(it.serviceIdentities(ServiceType.regulator).first(), ftx) } - } + + // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's + // just for demo purposes. + regulators.forEach { send(it, ftx) } progressTracker.currentStep = COPYING_TO_COUNTERPARTY // Send the final transaction hash back to the other party. @@ -173,8 +170,7 @@ object TwoPartyDealFlow { open class Instigator(override val otherParty: Party, override val payload: AutoOffer, override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { - override val notaryNode: NodeInfo get() = - serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == payload.notary } + override val notaryParty: Party get() = payload.notary @Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat { // Add some constraints here. diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index 032f23d301..991a95d464 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -56,7 +56,6 @@ object TwoPartyTradeFlow { ) open class Seller(val otherParty: Party, - val notaryNode: NodeInfo, val assetToSell: StateAndRef, val price: Amount, val myParty: PartyAndCertificate, // TODO Left because in tests it's used to pass anonymous party. diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt index 4715375ef5..ecfb07035a 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashExitFlowTests.kt @@ -8,6 +8,7 @@ import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash import net.corda.node.internal.StartedNode import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork.MockNode @@ -31,10 +32,10 @@ class CashExitFlowTests { val nodes = mockNet.createSomeNodes(1) notaryNode = nodes.notaryNode bankOfCordaNode = nodes.partyNodes[0] - notary = notaryNode.info.notaryIdentity bankOfCorda = bankOfCordaNode.info.chooseIdentity() mockNet.runNetwork() + notary = bankOfCordaNode.services.getDefaultNotary() val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture mockNet.runNetwork() future.getOrThrow() diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt index 511201e008..1102d2aeab 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashIssueFlowTests.kt @@ -8,6 +8,7 @@ import net.corda.finance.`issued by` import net.corda.finance.contracts.asset.Cash import net.corda.node.internal.StartedNode import net.corda.testing.chooseIdentity +import net.corda.testing.getDefaultNotary import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork.MockNode @@ -29,10 +30,10 @@ class CashIssueFlowTests { val nodes = mockNet.createSomeNodes(1) notaryNode = nodes.notaryNode bankOfCordaNode = nodes.partyNodes[0] - notary = notaryNode.info.notaryIdentity bankOfCorda = bankOfCordaNode.info.chooseIdentity() mockNet.runNetwork() + notary = bankOfCordaNode.services.getDefaultNotary() } @After diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt index 3c1ab49cae..ee215040c6 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt @@ -13,6 +13,7 @@ import net.corda.node.internal.StartedNode import net.corda.testing.chooseIdentity import net.corda.testing.expect import net.corda.testing.expectEvents +import net.corda.testing.getDefaultNotary import net.corda.testing.node.InMemoryMessagingNetwork.ServicePeerAllocationStrategy.RoundRobin import net.corda.testing.node.MockNetwork import net.corda.testing.node.MockNetwork.MockNode @@ -36,11 +37,11 @@ class CashPaymentFlowTests { val nodes = mockNet.createSomeNodes(1) notaryNode = nodes.notaryNode bankOfCordaNode = nodes.partyNodes[0] - notary = notaryNode.info.notaryIdentity bankOfCorda = bankOfCordaNode.info.chooseIdentity() - val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture mockNet.runNetwork() + notary = bankOfCordaNode.services.getDefaultNotary() + val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture future.getOrThrow() } diff --git a/core/src/main/kotlin/net/corda/core/node/services/ServiceInfo.kt b/node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt similarity index 96% rename from core/src/main/kotlin/net/corda/core/node/services/ServiceInfo.kt rename to node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt index 61b78aa241..c77e2cbb17 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/ServiceInfo.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt @@ -1,4 +1,4 @@ -package net.corda.core.node.services +package net.corda.nodeapi import net.corda.core.identity.CordaX500Name import net.corda.core.serialization.CordaSerializable diff --git a/core/src/main/kotlin/net/corda/core/node/services/ServiceType.kt b/node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt similarity index 79% rename from core/src/main/kotlin/net/corda/core/node/services/ServiceType.kt rename to node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt index 97d2888e88..05748eb564 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/ServiceType.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt @@ -1,4 +1,4 @@ -package net.corda.core.node.services +package net.corda.nodeapi import net.corda.core.serialization.CordaSerializable @@ -27,15 +27,8 @@ class ServiceType private constructor(val id: String) { } val notary: ServiceType = corda.getSubType("notary") - val regulator: ServiceType = corda.getSubType("regulator") val networkMap: ServiceType = corda.getSubType("network_map") - @JvmStatic - fun getServiceType(namespace: String, typeId: String): ServiceType { - require(!namespace.startsWith("corda")) { "Corda namespace is protected" } - return baseWithSubType(namespace, typeId) - } - fun parse(id: String): ServiceType = ServiceType(id) private fun baseWithSubType(baseId: String, subTypeId: String) = ServiceType("$baseId.$subTypeId") @@ -45,8 +38,6 @@ class ServiceType private constructor(val id: String) { fun isSubTypeOf(superType: ServiceType) = (id == superType.id) || id.startsWith(superType.id + ".") fun isNotary() = isSubTypeOf(notary) - fun isValidatingNotary() = isNotary() && id.contains(".validating") - fun isNetworkMap() = id == networkMap.id override fun equals(other: Any?): Boolean = other === this || other is ServiceType && other.id == this.id override fun hashCode(): Int = id.hashCode() diff --git a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt index 67cf30d78c..846b21d0b2 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -5,12 +5,12 @@ import net.corda.core.internal.div import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.getOrThrow import net.corda.testing.ALICE import net.corda.node.internal.NodeStartup import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.nodeapi.User import net.corda.testing.driver.ListenProcessDeathException import net.corda.testing.driver.NetworkMapStartStrategy @@ -18,6 +18,7 @@ import net.corda.testing.ProjectStructure.projectRootDir import net.corda.testing.driver.driver import org.assertj.core.api.Assertions.assertThat import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.Ignore import org.junit.Test import java.io.* import java.nio.file.Files @@ -54,9 +55,10 @@ class BootTests { } } + @Ignore("Need rewriting to produce too big network map registration (adverticed services trick doesn't work after services removal).") @Test fun `node quits on failure to register with network map`() { - val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.regulator.getSubType("$it")) }.toSet() + val tooManyAdvertisedServices = (1..100).map { ServiceInfo(ServiceType.notary.getSubType("$it")) }.toSet() driver(networkMapStartStrategy = NetworkMapStartStrategy.Nominated(ALICE.name)) { val future = startNode(providedName = ALICE.name, advertisedServices = tooManyAdvertisedServices) assertFailsWith(ListenProcessDeathException::class) { future.getOrThrow() } diff --git a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt index bf76ac9cff..93290c3079 100644 --- a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt @@ -6,13 +6,13 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.minutes import net.corda.finance.DOLLARS import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.chooseIdentity @@ -110,9 +110,10 @@ class NodePerformanceTests { a as NodeHandle.InProcess val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics) a.rpcClientToNode().use("A", "A") { connection -> + val notary = connection.proxy.notaryIdentities().first().party println("ISSUING") val doneFutures = (1..100).toList().parallelStream().map { - connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), a.nodeInfo.notaryIdentity).returnValue + connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue }.toList() doneFutures.transpose().get() println("STARTING PAYMENT") diff --git a/node/src/integration-test/kotlin/net/corda/node/services/AdvertisedServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/AdvertisedServiceTests.kt deleted file mode 100644 index f095592303..0000000000 --- a/node/src/integration-test/kotlin/net/corda/node/services/AdvertisedServiceTests.kt +++ /dev/null @@ -1,42 +0,0 @@ -package net.corda.node.services - -import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.StartableByRPC -import net.corda.core.identity.CordaX500Name -import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType -import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.User -import net.corda.testing.driver.driver -import org.junit.Test -import kotlin.test.assertTrue - -class AdvertisedServiceTests { - private val serviceName = CordaX500Name(organisation = "Custom Service", locality = "London", country = "GB") - private val serviceType = ServiceType.corda.getSubType("custom") - private val user = "bankA" - private val pass = "passA" - - - @StartableByRPC - class ServiceTypeCheckingFlow : FlowLogic() { - @Suspendable - override fun call(): Boolean { - return serviceHub.networkMapCache.getAnyServiceOfType(ServiceType.corda.getSubType("custom")) != null - } - } - - @Test - fun `service is accessible through getAnyServiceOfType`() { - driver(startNodesInProcess = true) { - val bankA = startNode(rpcUsers = listOf(User(user, pass, setOf(startFlowPermission())))).get() - startNode(providedName = serviceName, advertisedServices = setOf(ServiceInfo(serviceType))).get() - bankA.rpcClientToNode().use(user, pass) { connection -> - val result = connection.proxy.startFlow(::ServiceTypeCheckingFlow).returnValue.get() - assertTrue(result) - } - } - } -} diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index b391f34c7b..baa1fe3759 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -10,7 +10,6 @@ import net.corda.core.flows.NotaryFlow import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.NetworkHostAndPort @@ -23,10 +22,12 @@ import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.minClusterSize import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.utilities.ServiceIdentityGenerator +import net.corda.nodeapi.ServiceInfo import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyContract import net.corda.testing.dummyCommand +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Test @@ -47,7 +48,7 @@ class BFTNotaryServiceTests { mockNet.stopNodes() } - private fun bftNotaryCluster(clusterSize: Int, exposeRaces: Boolean = false): Party { + private fun bftNotaryCluster(clusterSize: Int, exposeRaces: Boolean = false) { Files.deleteIfExists("config" / "currentView") // XXX: Make config object warn if this exists? val replicaIds = (0 until clusterSize) val party = ServiceIdentityGenerator.generateToDisk( @@ -66,13 +67,14 @@ class BFTNotaryServiceTests { whenever(it.notaryClusterAddresses).thenReturn(notaryClusterAddresses) }) } - return party + mockNet.runNetwork() // Exchange initial network map registration messages. } /** Failure mode is the redundant replica gets stuck in startup, so we can't dispose it cleanly at the end. */ @Test fun `all replicas start even if there is a new consensus during startup`() { - val notary = bftNotaryCluster(minClusterSize(1), true) // This true adds a sleep to expose the race. + bftNotaryCluster(minClusterSize(1), true) // This true adds a sleep to expose the race. + val notary = node.services.getDefaultNotary() val f = node.run { val trivialTx = signInitialTransaction(notary) { addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID) @@ -96,7 +98,8 @@ class BFTNotaryServiceTests { private fun detectDoubleSpend(faultyReplicas: Int) { val clusterSize = minClusterSize(faultyReplicas) - val notary = bftNotaryCluster(clusterSize) + bftNotaryCluster(clusterSize) + val notary = node.services.getDefaultNotary() node.run { val issueTx = signInitialTransaction(notary) { addOutputState(DummyContract.SingleOwnerState(owner = info.chooseIdentity()), DUMMY_PROGRAM_ID) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt index 094c05c095..3ce49fe837 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt @@ -2,7 +2,6 @@ package net.corda.node.services import net.corda.core.contracts.Amount import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.StateMachineUpdate @@ -51,14 +50,9 @@ class DistributedServiceTests : DriverBasedTest() { raftNotaryIdentity = notaryIdentity notaries = notaryNodes.map { it as NodeHandle.OutOfProcess } - val notariesIdentities = notaries.fold(HashSet()) { - acc, elem -> acc.addAll(elem.nodeInfo.legalIdentitiesAndCerts) - acc - } assertEquals(notaries.size, clusterSize) // Check that each notary has different identity as a node. - assertEquals(notaries.size, notariesIdentities.size - notaries[0].nodeInfo.advertisedServices.size) - + assertEquals(notaries.size, notaries.map { it.nodeInfo.chooseIdentity() }.toSet().size) // Connect to Alice and the notaries fun connectRpc(node: NodeHandle): CordaRPCOps { val client = node.rpcClientToNode() diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index f112ffde5d..1d37d5609d 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -8,7 +8,6 @@ import net.corda.core.internal.elapsedTime import net.corda.core.internal.times import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize @@ -19,6 +18,7 @@ import net.corda.node.services.messaging.* import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.utilities.ServiceIdentityGenerator +import net.corda.nodeapi.ServiceInfo import net.corda.testing.* import net.corda.testing.node.NodeBasedTest import org.assertj.core.api.Assertions.assertThat @@ -84,7 +84,8 @@ class P2PMessagingTest : NodeBasedTest() { startNode(ALICE.name) ).transpose().getOrThrow() - assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), SERVICE_2_NAME.copy(commonName = "DistributedService"), alice) + val serviceName = serviceNode2.info.legalIdentities[1].name + assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), serviceName, alice) } @Ignore diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index 5185a3bf4f..d37ad7f9ba 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -8,7 +8,6 @@ import net.corda.core.flows.StartableByRPC import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.PersistentState import net.corda.core.schemas.QueryableState @@ -19,6 +18,7 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.getOrThrow import net.corda.node.services.FlowPermissions +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.DUMMY_NOTARY diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 665194e27e..b61954da4f 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -22,7 +22,6 @@ import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.NodeInfo -import net.corda.core.node.ServiceEntry import net.corda.core.node.ServiceHub import net.corda.core.node.services.* import net.corda.core.node.services.NetworkMapCache.MapChange @@ -37,6 +36,8 @@ import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappProvider import net.corda.node.services.NotaryChangeHandler import net.corda.node.services.NotifyTransactionHandler +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.api.* import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.configureWithDevSSLCertificate @@ -75,6 +76,7 @@ import java.lang.reflect.InvocationTargetException import java.nio.file.Path import java.security.KeyPair import java.security.KeyStoreException +import java.security.PublicKey import java.security.cert.CertificateFactory import java.security.cert.X509Certificate import java.sql.Connection @@ -134,8 +136,9 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, protected val services: ServiceHubInternal get() = _services private lateinit var _services: ServiceHubInternalImpl - lateinit var legalIdentity: PartyAndCertificate + protected lateinit var legalIdentity: PartyAndCertificate protected lateinit var info: NodeInfo + protected var myNotaryIdentity: PartyAndCertificate? = null protected lateinit var checkpointStorage: CheckpointStorage protected lateinit var smm: StateMachineManager protected lateinit var attachments: NodeAttachmentService @@ -391,7 +394,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, services.auditService, services.monitoringService, services.networkMapCache, services.schemaService, services.transactionVerifierService, services.validatedTransactions, services.contractUpgradeService, services, this) - makeAdvertisedServices(tokenizableServices) + makeNetworkServices(tokenizableServices) return tokenizableServices } @@ -414,22 +417,21 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, } private fun makeInfo(legalIdentity: PartyAndCertificate): NodeInfo { - val advertisedServiceEntries = makeServiceEntries() + // TODO We keep only notary identity as additional legalIdentity if we run it on a node . Multiple identities need more design thinking. + myNotaryIdentity = getNotaryIdentity() val allIdentitiesList = mutableListOf(legalIdentity) - allIdentitiesList.addAll(advertisedServiceEntries.map { it.identity }) // TODO Will we keep service identities here, for example notaries? + myNotaryIdentity?.let { allIdentitiesList.add(it) } val addresses = myAddresses() // TODO There is no support for multiple IP addresses yet. - return NodeInfo(addresses, allIdentitiesList, platformVersion, advertisedServiceEntries, platformClock.instant().toEpochMilli()) + return NodeInfo(addresses, allIdentitiesList, platformVersion, platformClock.instant().toEpochMilli()) } /** * A service entry contains the advertised [ServiceInfo] along with the service identity. The identity *name* is * taken from the configuration or, if non specified, generated by combining the node's legal name and the service id. + * Used only for notary identities. */ - protected open fun makeServiceEntries(): List { - return advertisedServices.map { - val identity = obtainIdentity(it) - ServiceEntry(it, identity) - } + protected open fun getNotaryIdentity(): PartyAndCertificate? { + return advertisedServices.singleOrNull { it.type.isNotary() }?.let { obtainIdentity(it) } } @VisibleForTesting @@ -478,8 +480,8 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, } } - private fun makeAdvertisedServices(tokenizableServices: MutableList) { - val serviceTypes = info.advertisedServices.map { it.info.type } + private fun makeNetworkServices(tokenizableServices: MutableList) { + val serviceTypes = advertisedServices.map { it.type } inNodeNetworkMapService = if (NetworkMapService.type in serviceTypes) makeNetworkMapService() else NullNetworkMapService val notaryServiceType = serviceTypes.singleOrNull { it.isNotary() } if (notaryServiceType != null) { @@ -584,7 +586,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, .filterNotNull() .toTypedArray() val service = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates) - services.networkMapCache.partyNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } } + services.networkMapCache.allNodes.forEach { it.legalIdentitiesAndCerts.forEach { service.verifyAndRegisterIdentity(it) } } services.networkMapCache.changed.subscribe { mapChange -> // TODO how should we handle network map removal if (mapChange is MapChange.Added) { @@ -628,7 +630,12 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, // Create node identity if service info = null Pair("identity", myLegalName.copy(commonName = null)) } else { - val name = serviceInfo.name ?: myLegalName.copy(commonName = serviceInfo.type.id) + // Ensure that we always have notary in name and type of it. TODO It is temporary solution until we will have proper handling of NetworkParameters + val baseName = serviceInfo.name ?: myLegalName + val name = if (baseName.commonName == null) + baseName.copy(commonName = serviceInfo.type.id) + else + baseName.copy(commonName = baseName.commonName + " " + serviceInfo.type.id) Pair(serviceInfo.type.id, name) } @@ -728,6 +735,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, override val myInfo: NodeInfo get() = info override val database: CordaPersistence get() = this@AbstractNode.database override val configuration: NodeConfiguration get() = this@AbstractNode.configuration + override val notaryIdentityKey: PublicKey get() = myNotaryIdentity?.owningKey ?: throw IllegalArgumentException("Node doesn't have notary identity key") override fun cordaService(type: Class): T { require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" } diff --git a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt index a3058d9e03..e51223f932 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt @@ -10,6 +10,7 @@ import net.corda.core.flows.StartableByRPC import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.* import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache @@ -114,6 +115,10 @@ class CordaRPCOpsImpl( return services.myInfo } + override fun notaryIdentities(): List { + return services.networkMapCache.notaryIdentities + } + override fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) { return database.transaction { services.vaultService.addNoteToTransaction(txnId, txnNote) @@ -202,7 +207,7 @@ class CordaRPCOpsImpl( } } - override fun nodeIdentityFromParty(party: AbstractParty): NodeInfo? { + override fun nodeInfoFromParty(party: AbstractParty): NodeInfo? { return database.transaction { services.networkMapCache.getNodeByLegalIdentity(party) } diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index 6acf954f2e..957e8150f0 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -11,7 +11,6 @@ import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.uncheckedCast import net.corda.core.messaging.RPCOps import net.corda.core.node.ServiceHub -import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.SerializationDefaults import net.corda.core.utilities.* import net.corda.node.VersionInfo @@ -19,6 +18,7 @@ import net.corda.node.serialization.KryoServerSerializationScheme import net.corda.node.serialization.NodeClock import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserServiceImpl +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.messaging.ArtemisMessagingServer import net.corda.node.services.messaging.ArtemisMessagingServer.Companion.ipDetectRequestProperty diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index 75c83ab092..dfd3572333 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -5,9 +5,9 @@ import com.typesafe.config.ConfigException import joptsimple.OptionException import net.corda.core.internal.* import net.corda.core.internal.concurrent.thenMatch -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.loggerFor import net.corda.node.* +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.transactions.bftSMaRtSerialFilter import net.corda.node.shell.InteractiveShell diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt index 55d3979ba1..d35bbb47a8 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt @@ -8,13 +8,10 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatedBy import net.corda.core.flows.StartableByRPC import net.corda.core.internal.* -import net.corda.core.node.NodeInfo import net.corda.core.node.CordaPluginRegistry import net.corda.core.node.services.CordaService -import net.corda.core.node.services.ServiceType import net.corda.core.schemas.MappedSchema import net.corda.core.serialization.SerializeAsToken -import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor import net.corda.node.internal.classloading.requireAnnotation import java.lang.reflect.Modifier @@ -23,9 +20,7 @@ import java.net.URI import java.net.URL import java.net.URLClassLoader import java.nio.file.Path -import java.nio.file.Paths import java.util.* -import java.util.stream.Collectors import kotlin.reflect.KClass import kotlin.streams.toList diff --git a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt index 454a9aaddc..a63985d653 100644 --- a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt +++ b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt @@ -38,7 +38,7 @@ class NotaryChangeHandler(otherSide: Party) : AbstractStateReplacementFlow.Accep } // TODO: load and compare against notary whitelist from config. Remove the check below - val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.notaryIdentity == newNotary } + val isNotary = serviceHub.networkMapCache.isNotary(newNotary) if (!isNotary) { throw StateReplacementException("The proposed node $newNotary does not run a Notary service") } diff --git a/node/src/main/kotlin/net/corda/node/services/api/RegulatorService.kt b/node/src/main/kotlin/net/corda/node/services/api/RegulatorService.kt deleted file mode 100644 index 59144447b3..0000000000 --- a/node/src/main/kotlin/net/corda/node/services/api/RegulatorService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package net.corda.node.services.api - -import net.corda.core.node.services.ServiceType - -/** - * Placeholder interface for regulator services. - */ -interface RegulatorService { - companion object { - val type = ServiceType.regulator - } -} diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index 55aa375285..67a7d8efe1 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -1,9 +1,9 @@ package net.corda.node.services.config import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.internal.NetworkMapInfo +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.messaging.CertificateChainCheckPolicy import net.corda.node.services.network.NetworkMapService import net.corda.nodeapi.User diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt index e65d304130..c0fa5d0778 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt @@ -12,17 +12,16 @@ import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo import net.corda.core.node.services.KeyManagementService import net.corda.core.node.services.NetworkMapCache -import net.corda.core.node.services.ServiceType import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializedBytes import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor +import net.corda.nodeapi.ServiceType import net.corda.node.services.api.AbstractNodeService import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.messaging.MessageHandlerRegistration -import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.ServiceRequestMessage import net.corda.node.services.messaging.createMessage import net.corda.node.services.network.NetworkMapService.* diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index ef49d2e80c..4e6d232600 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -4,6 +4,7 @@ import net.corda.core.concurrent.CordaFuture import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.concurrent.map @@ -58,8 +59,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) // TODO Small explanation, partyNodes and registeredNodes is left in memory as it was before, because it will be removed in // next PR that gets rid of services. These maps are used only for queries by service. protected val registeredNodes: MutableMap = Collections.synchronizedMap(HashMap()) - override val partyNodes: MutableList get() = registeredNodes.map { it.value }.toMutableList() - override val networkMapNodes: List get() = getNodesWithService(NetworkMapService.type) + protected val partyNodes: MutableList get() = registeredNodes.map { it.value }.toMutableList() private val _changed = PublishSubject.create() // We use assignment here so that multiple subscribers share the same wrapped Observable. override val changed: Observable = _changed.wrapWithDatabaseTransaction() @@ -69,6 +69,15 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) override val nodeReady: CordaFuture get() = _registrationFuture private var _loadDBSuccess: Boolean = false override val loadDBSuccess get() = _loadDBSuccess + // TODO From the NetworkMapService redesign doc: Remove the concept of network services. + // As a temporary hack, just assume for now that every network has a notary service named "Notary Service" that can be looked up in the map. + // This should eliminate the only required usage of services. + // It is ensured on node startup when constructing a notary that the name contains "notary". + override val notaryIdentities: List get() { + return partyNodes.flatMap { it.legalIdentitiesAndCerts }.filter { + it.name.toString().contains("corda.notary", true) + }.distinct().sortedBy { it.name.toString() } // Distinct, because of distributed service nodes. + } init { serviceHub.database.transaction { loadFromDB() } @@ -80,8 +89,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) return PartyInfo.SingleNode(party, nodes[0].addresses) } for (node in nodes) { - for (service in node.advertisedServices) { - if (service.identity.party == party) { + for (identity in node.legalIdentities) { + if (identity == party) { return PartyInfo.DistributedNode(party) } } @@ -89,9 +98,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) return null } - // TODO See comment to queryByLegalName why it's left like that. - override fun getNodeByLegalName(principal: CordaX500Name): NodeInfo? = partyNodes.singleOrNull { principal in it.legalIdentities.map { it.name } } - //serviceHub!!.database.transaction { queryByLegalName(principal).firstOrNull() } + override fun getNodeByLegalName(name: CordaX500Name): NodeInfo? = serviceHub.database.transaction { queryByLegalName(name).firstOrNull() } override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List = serviceHub.database.transaction { queryByIdentityKey(identityKey) } override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? { @@ -194,6 +201,12 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) } } + override val allNodes: List get () = serviceHub.database.transaction { + createSession { + getAllInfos(it).map { it.toNodeInfo() } + } + } + private fun processRegistration(reg: NodeRegistration) { // TODO: Implement filtering by sequence number, so we only accept changes that are // more recent than the latest change we've processed. @@ -251,8 +264,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) // network map registration on network map node) serviceHub.database.dataSource.connection.use { val session = serviceHub.database.entityManagerFactory.withOptions().connection(it.apply { - transactionIsolation = 1 - }).openSession() + transactionIsolation = 1 + }).openSession() session.use { val tx = session.beginTransaction() // TODO For now the main legal identity is left in NodeInfo, this should be set comparision/come up with index for NodeInfo? @@ -322,7 +335,6 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem -> NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) }, platformVersion = nodeInfo.platformVersion, - advertisedServices = nodeInfo.advertisedServices.map { NodeInfoSchemaV1.DBServiceEntry(it.serialize().bytes) }, serial = nodeInfo.serial ) } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt index 5b92626f3b..6b5c4ef26f 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt @@ -2,9 +2,9 @@ package net.corda.node.services.transactions import net.corda.core.flows.NotaryFlow import net.corda.core.identity.Party -import net.corda.core.node.services.ServiceType import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService +import net.corda.nodeapi.ServiceType import net.corda.node.services.api.ServiceHubInternal /** A simple Notary service that does not perform transaction validation */ diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt index d4a1b11e60..5c968695c4 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt @@ -38,7 +38,7 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ private fun checkSignatures(stx: SignedTransaction) { try { - stx.verifySignaturesExcept(serviceHub.myInfo.notaryIdentity.owningKey) + stx.verifySignaturesExcept(serviceHub.notaryIdentityKey) } catch(e: SignatureException) { throw NotaryException(NotaryError.TransactionInvalid(e)) } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt index 9bb34b273c..bdb72bb3ef 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt @@ -2,9 +2,9 @@ package net.corda.node.services.transactions import net.corda.core.flows.NotaryFlow import net.corda.core.identity.Party -import net.corda.core.node.services.ServiceType import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService +import net.corda.nodeapi.ServiceType import net.corda.node.services.api.ServiceHubInternal /** A Notary service that validates the transaction chain of the submitted transaction before committing it */ diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index d6c98973e9..d818a90fae 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -9,8 +9,8 @@ import net.corda.core.crypto.keys import net.corda.core.flows.FlowLogic import net.corda.core.flows.StartableByRPC import net.corda.core.flows.StateMachineRunId +import net.corda.core.identity.Party import net.corda.core.messaging.* -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.node.services.queryBy import net.corda.core.transactions.SignedTransaction @@ -28,6 +28,7 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT import net.corda.node.services.messaging.RpcContext import net.corda.node.services.network.NetworkMapService import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.PermissionException import net.corda.nodeapi.User @@ -59,6 +60,7 @@ class CordaRPCOpsImplTest { lateinit var mockNet: MockNetwork lateinit var aliceNode: StartedNode lateinit var notaryNode: StartedNode + lateinit var notary: Party lateinit var rpc: CordaRPCOps lateinit var stateMachineUpdates: Observable lateinit var transactions: Observable @@ -78,6 +80,7 @@ class CordaRPCOpsImplTest { mockNet.runNetwork() networkMap.internals.ensureRegistered() + notary = rpc.notaryIdentities().first().party } @After @@ -102,7 +105,7 @@ class CordaRPCOpsImplTest { // Tell the monitoring service node to issue some cash val recipient = aliceNode.info.chooseIdentity() - val result = rpc.startFlow(::CashIssueFlow, Amount(quantity, GBP), ref, notaryNode.info.notaryIdentity) + val result = rpc.startFlow(::CashIssueFlow, Amount(quantity, GBP), ref, notary) mockNet.runNetwork() var issueSmId: StateMachineRunId? = null @@ -146,7 +149,7 @@ class CordaRPCOpsImplTest { val result = rpc.startFlow(::CashIssueFlow, 100.DOLLARS, OpaqueBytes(ByteArray(1, { 1 })), - notaryNode.info.notaryIdentity + notary ) mockNet.runNetwork() @@ -196,7 +199,7 @@ class CordaRPCOpsImplTest { val signaturePubKeys = stx.sigs.map { it.by }.toSet() // Alice and Notary signed require(aliceNode.services.keyManagementService.filterMyKeys(signaturePubKeys).toList().isNotEmpty()) - require(notaryNode.info.notaryIdentity.owningKey.isFulfilledBy(signaturePubKeys)) + require(notary.owningKey.isFulfilledBy(signaturePubKeys)) } ) } @@ -221,7 +224,7 @@ class CordaRPCOpsImplTest { fun `cash command by user not permissioned for cash`() { CURRENT_RPC_CONTEXT.set(RpcContext(User("user", "pwd", permissions = emptySet()))) assertThatExceptionOfType(PermissionException::class.java).isThrownBy { - rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), notaryNode.info.notaryIdentity) + rpc.startFlow(::CashIssueFlow, Amount(100, USD), OpaqueBytes(ByteArray(1, { 1 })), notary) } } diff --git a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt index 01f04ada97..d356afb76f 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt @@ -1,6 +1,6 @@ package net.corda.node.messaging -import net.corda.core.node.services.ServiceInfo +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.messaging.Message import net.corda.node.services.messaging.TopicStringValidator import net.corda.node.services.messaging.createMessage diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 69f687d066..fd05f8e9f7 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -18,8 +18,6 @@ import net.corda.core.internal.rootCause import net.corda.core.messaging.DataFeed import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.messaging.StateMachineTransactionMapping -import net.corda.core.node.NodeInfo -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SingletonSerializeAsToken @@ -38,6 +36,7 @@ import net.corda.finance.contracts.asset.* import net.corda.finance.flows.TwoPartyTradeFlow.Buyer import net.corda.finance.flows.TwoPartyTradeFlow.Seller import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.persistence.DBTransactionStorage @@ -99,23 +98,25 @@ class TwoPartyTradeFlowTests { val bankNode = basketOfNodes.partyNodes[2] val cashIssuer = bankNode.info.chooseIdentity().ref(1) val cpIssuer = bankNode.info.chooseIdentity().ref(1, 2, 3) + val notary = aliceNode.services.getDefaultNotary() + aliceNode.internals.disableDBCloseOnStop() bobNode.internals.disableDBCloseOnStop() bobNode.database.transaction { - bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notaryNode.info.notaryIdentity, + bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notary, issuedBy = cashIssuer) } val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, cpIssuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second } insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) - val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, + val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()) // TODO: Verify that the result was inserted into the transaction database. @@ -146,18 +147,19 @@ class TwoPartyTradeFlowTests { val bobNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOB.name) val bankNode = mockNet.createPartyNode(notaryNode.network.myAddress, BOC.name) val issuer = bankNode.info.chooseIdentity().ref(1) + val notary = aliceNode.services.getDefaultNotary() aliceNode.internals.disableDBCloseOnStop() bobNode.internals.disableDBCloseOnStop() val cashStates = bobNode.database.transaction { - bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notaryNode.info.notaryIdentity, 3, 3, + bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, notary, 3, 3, issuedBy = issuer) } val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second } insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) @@ -171,7 +173,7 @@ class TwoPartyTradeFlowTests { } } - val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, + val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()) assertEquals(aliceResult.getOrThrow(), bobStateMachine.getOrThrow().resultFuture.getOrThrow()) @@ -216,17 +218,18 @@ class TwoPartyTradeFlowTests { val networkMapAddress = notaryNode.network.myAddress mockNet.runNetwork() // Clear network map registration messages + val notary = aliceNode.services.getDefaultNotary() bobNode.database.transaction { - bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notaryNode.info.notaryIdentity, + bobNode.services.fillWithSomeTestCash(2000.DOLLARS, bankNode.services, outputNotary = notary, issuedBy = issuer) } val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), null, notary).second } insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) - val aliceFuture = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult + val aliceFuture = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerResult // Everything is on this thread so we can now step through the flow one step at a time. // Seller Alice already sent a message to Buyer Bob. Pump once: @@ -332,9 +335,9 @@ class TwoPartyTradeFlowTests { val bobNode = makeNodeWithTracking(notaryNode.network.myAddress, BOB.name) val bankNode = makeNodeWithTracking(notaryNode.network.myAddress, BOC.name) val issuer = bankNode.info.chooseIdentity().ref(1, 2, 3) - mockNet.runNetwork() notaryNode.internals.ensureRegistered() + val notary = aliceNode.services.getDefaultNotary() mockNet.registerIdentities() @@ -352,17 +355,17 @@ class TwoPartyTradeFlowTests { } val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobNode.info.chooseIdentity().owningKey), - notaryNode.info.notaryIdentity).second + notary).second val bobsSignedTxns = insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notary).second } val alicesSignedTxns = insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) mockNet.runNetwork() // Clear network map registration messages - runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()) + runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()) mockNet.runNetwork() @@ -441,6 +444,7 @@ class TwoPartyTradeFlowTests { mockNet.runNetwork() notaryNode.internals.ensureRegistered() + val notary = aliceNode.services.getDefaultNotary() mockNet.registerIdentities() @@ -458,12 +462,12 @@ class TwoPartyTradeFlowTests { val bobsKey = bobNode.services.keyManagementService.keys.single() val bobsFakeCash = fillUpForBuyer(false, issuer, AnonymousParty(bobsKey), - notaryNode.info.notaryIdentity).second + notary).second insertFakeTransactions(bobsFakeCash, bobNode, notaryNode, bankNode) val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(false, issuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` bankNode.info.chooseIdentity().ref(0), attachmentID, notary).second } insertFakeTransactions(alicesFakePaper, aliceNode, notaryNode, bankNode) @@ -474,7 +478,7 @@ class TwoPartyTradeFlowTests { val aliceTxMappings = with(aliceNode) { database.transaction { services.stateMachineRecordedTransactionMapping.track().updates } } - val aliceSmId = runBuyerAndSeller(notaryNode, aliceNode, bobNode, + val aliceSmId = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()).sellerId mockNet.runNetwork() @@ -533,21 +537,21 @@ class TwoPartyTradeFlowTests { val sellerId: StateMachineRunId ) - private fun runBuyerAndSeller(notaryNode: StartedNode, + private fun runBuyerAndSeller(notary: Party, sellerNode: StartedNode, buyerNode: StartedNode, assetToSell: StateAndRef, anonymous: Boolean = true): RunResult { val buyerFlows: Observable> = buyerNode.internals.registerInitiatedFlow(BuyerAcceptor::class.java) val firstBuyerFiber = buyerFlows.toFuture().map { it.stateMachine } - val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notaryNode.info, assetToSell, 1000.DOLLARS, anonymous) + val seller = SellerInitiator(buyerNode.info.chooseIdentity(), notary, assetToSell, 1000.DOLLARS, anonymous) val sellerResult = sellerNode.services.startFlow(seller).resultFuture return RunResult(firstBuyerFiber, sellerResult, seller.stateMachine.id) } @InitiatingFlow class SellerInitiator(private val buyer: Party, - private val notary: NodeInfo, + private val notary: Party, private val assetToSell: StateAndRef, private val price: Amount, private val anonymous: Boolean) : FlowLogic() { @@ -558,10 +562,9 @@ class TwoPartyTradeFlowTests { } else { ourIdentityAndCert } - send(buyer, TestTx(notary.notaryIdentity, price, anonymous)) + send(buyer, TestTx(notary, price, anonymous)) return subFlow(Seller( buyer, - notary, assetToSell, price, myPartyAndCert)) @@ -596,17 +599,18 @@ class TwoPartyTradeFlowTests { mockNet.runNetwork() notaryNode.internals.ensureRegistered() + val notary = aliceNode.services.getDefaultNotary() // Let the nodes know about each other - normally the network map would handle this mockNet.registerIdentities() val bobsBadCash = bobNode.database.transaction { fillUpForBuyer(bobError, issuer, bobNode.info.chooseIdentity(), - notaryNode.info.notaryIdentity).second + notary).second } val alicesFakePaper = aliceNode.database.transaction { fillUpForSeller(aliceError, issuer, aliceNode.info.chooseIdentity(), - 1200.DOLLARS `issued by` issuer, null, notaryNode.info.notaryIdentity).second + 1200.DOLLARS `issued by` issuer, null, notary).second } insertFakeTransactions(bobsBadCash, bobNode, notaryNode, bankNode) @@ -614,7 +618,7 @@ class TwoPartyTradeFlowTests { mockNet.runNetwork() // Clear network map registration messages - val (bobStateMachine, aliceResult) = runBuyerAndSeller(notaryNode, aliceNode, bobNode, "alice's paper".outputStateAndRef()) + val (bobStateMachine, aliceResult) = runBuyerAndSeller(notary, aliceNode, bobNode, "alice's paper".outputStateAndRef()) mockNet.runNetwork() diff --git a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt index e34f435a83..f577a15a01 100644 --- a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt @@ -6,7 +6,6 @@ import net.corda.core.flows.NotaryChangeFlow import net.corda.core.flows.StateReplacementException import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.node.services.ServiceInfo import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.getOrThrow @@ -14,6 +13,7 @@ import net.corda.core.utilities.seconds import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.SimpleNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.chooseIdentity @@ -36,6 +36,8 @@ class NotaryChangeTests { lateinit var newNotaryNode: StartedNode lateinit var clientNodeA: StartedNode lateinit var clientNodeB: StartedNode + lateinit var notaryNewId: Party + lateinit var notaryOldId: Party @Before fun setUp() { @@ -49,6 +51,8 @@ class NotaryChangeTests { mockNet.registerIdentities() mockNet.runNetwork() // Clear network map registration messages oldNotaryNode.internals.ensureRegistered() + notaryNewId = newNotaryNode.info.legalIdentities[1] + notaryOldId = oldNotaryNode.info.legalIdentities[1] } @After @@ -58,8 +62,8 @@ class NotaryChangeTests { @Test fun `should change notary for a state with single participant`() { - val state = issueState(clientNodeA, oldNotaryNode) - val newNotary = newNotaryNode.info.notaryIdentity + val state = issueState(clientNodeA, oldNotaryNode, notaryOldId) + val newNotary = notaryNewId val flow = NotaryChangeFlow(state, newNotary) val future = clientNodeA.services.startFlow(flow) @@ -71,8 +75,8 @@ class NotaryChangeTests { @Test fun `should change notary for a state with multiple participants`() { - val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode) - val newNotary = newNotaryNode.info.notaryIdentity + val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode, notaryOldId) + val newNotary = notaryNewId val flow = NotaryChangeFlow(state, newNotary) val future = clientNodeA.services.startFlow(flow) @@ -87,7 +91,7 @@ class NotaryChangeTests { @Test fun `should throw when a participant refuses to change Notary`() { - val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode) + val state = issueMultiPartyState(clientNodeA, clientNodeB, oldNotaryNode, notaryOldId) val newEvilNotary = getTestPartyAndCertificate(CordaX500Name(organisation = "Evil R3", locality = "London", country = "GB"), generateKeyPair().public) val flow = NotaryChangeFlow(state, newEvilNotary.party) val future = clientNodeA.services.startFlow(flow) @@ -101,10 +105,10 @@ class NotaryChangeTests { @Test fun `should not break encumbrance links`() { - val issueTx = issueEncumberedState(clientNodeA, oldNotaryNode) + val issueTx = issueEncumberedState(clientNodeA, notaryOldId) val state = StateAndRef(issueTx.outputs.first(), StateRef(issueTx.id, 0)) - val newNotary = newNotaryNode.info.notaryIdentity + val newNotary = notaryNewId val flow = NotaryChangeFlow(state, newNotary) val future = clientNodeA.services.startFlow(flow) mockNet.runNetwork() @@ -133,19 +137,17 @@ class NotaryChangeTests { } } - private fun issueEncumberedState(node: StartedNode<*>, notaryNode: StartedNode<*>): WireTransaction { + private fun issueEncumberedState(node: StartedNode<*>, notaryIdentity: Party): WireTransaction { val owner = node.info.chooseIdentity().ref(0) - val notary = notaryNode.info.notaryIdentity - val stateA = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val stateB = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val stateC = DummyContract.SingleOwnerState(Random().nextInt(), owner.party) val tx = TransactionBuilder(null).apply { addCommand(Command(DummyContract.Commands.Create(), owner.party.owningKey)) - addOutputState(stateA, DUMMY_PROGRAM_ID, notary, encumbrance = 2) // Encumbered by stateB - addOutputState(stateC, DUMMY_PROGRAM_ID, notary) - addOutputState(stateB, DUMMY_PROGRAM_ID, notary, encumbrance = 1) // Encumbered by stateC + addOutputState(stateA, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 2) // Encumbered by stateB + addOutputState(stateC, DUMMY_PROGRAM_ID, notaryIdentity) + addOutputState(stateB, DUMMY_PROGRAM_ID, notaryIdentity, encumbrance = 1) // Encumbered by stateC } val stx = node.services.signInitialTransaction(tx) node.services.recordTransactions(stx) @@ -161,21 +163,21 @@ class NotaryChangeTests { // - The transaction type is not a notary change transaction at all. } -fun issueState(node: StartedNode<*>, notaryNode: StartedNode<*>): StateAndRef<*> { - val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) +fun issueState(node: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef<*> { + val tx = DummyContract.generateInitial(Random().nextInt(), notaryIdentity, node.info.chooseIdentity().ref(0)) val signedByNode = node.services.signInitialTransaction(tx) - val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) + val stx = notaryNode.services.addSignature(signedByNode, notaryIdentity.owningKey) node.services.recordTransactions(stx) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) } -fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>): StateAndRef { +fun issueMultiPartyState(nodeA: StartedNode<*>, nodeB: StartedNode<*>, notaryNode: StartedNode<*>, notaryIdentity: Party): StateAndRef { val state = TransactionState(DummyContract.MultiOwnerState(0, - listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryNode.info.notaryIdentity) - val tx = TransactionBuilder(notary = notaryNode.info.notaryIdentity).withItems(state, dummyCommand()) + listOf(nodeA.info.chooseIdentity(), nodeB.info.chooseIdentity())), DUMMY_PROGRAM_ID, notaryIdentity) + val tx = TransactionBuilder(notary = notaryIdentity).withItems(state, dummyCommand()) val signedByA = nodeA.services.signInitialTransaction(tx) val signedByAB = nodeB.services.addSignature(signedByA) - val stx = notaryNode.services.addSignature(signedByAB, notaryNode.services.notaryIdentityKey) + val stx = notaryNode.services.addSignature(signedByAB, notaryIdentity.owningKey) nodeA.services.recordTransactions(stx) nodeB.services.recordTransactions(stx) val stateAndRef = StateAndRef(state, StateRef(stx.id, 0)) diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index da50a4c710..97d4d6b4e6 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -6,7 +6,6 @@ import net.corda.core.contracts.* import net.corda.core.flows.* import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.VaultQueryService import net.corda.core.node.services.queryBy import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM @@ -17,6 +16,7 @@ import net.corda.core.node.services.vault.SortAttribute import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.transactions.ValidatingNotaryService diff --git a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt index 306fcce08d..355e54c104 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt @@ -4,11 +4,10 @@ import net.corda.core.concurrent.CordaFuture import net.corda.core.identity.CordaX500Name import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.NodeInfo -import net.corda.core.node.services.ServiceInfo import net.corda.core.serialization.deserialize import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode -import net.corda.node.services.api.ServiceHubInternal +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.send diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt index 23748baaf1..d7e65d8162 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt @@ -1,8 +1,8 @@ package net.corda.node.services.network import net.corda.core.node.services.NetworkMapCache -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow +import net.corda.nodeapi.ServiceInfo import net.corda.testing.ALICE import net.corda.testing.BOB import net.corda.testing.chooseIdentity diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt index 5f156ce601..3d2956d069 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt @@ -60,8 +60,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { @Test fun `restart node with DB map cache and no network map`() { val alice = startNodesWithPort(listOf(ALICE), noNetworkMap = true)[0] - val partyNodes = alice.services.networkMapCache.partyNodes - assertTrue(NetworkMapService.type !in alice.info.advertisedServices.map { it.info.type }) + val partyNodes = alice.services.networkMapCache.allNodes assertEquals(NullNetworkMapService, alice.inNodeNetworkMapService) assertEquals(infos.size, partyNodes.size) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) @@ -72,9 +71,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { val parties = partiesList.subList(1, partiesList.size) val nodes = startNodesWithPort(parties, noNetworkMap = true) assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) - assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) nodes.forEach { - val partyNodes = it.services.networkMapCache.partyNodes + val partyNodes = it.services.networkMapCache.allNodes assertEquals(infos.size, partyNodes.size) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) } @@ -86,9 +84,8 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { val parties = partiesList.subList(1, partiesList.size) val nodes = startNodesWithPort(parties, noNetworkMap = false) assertTrue(nodes.all { it.inNodeNetworkMapService == NullNetworkMapService }) - assertTrue(nodes.all { NetworkMapService.type !in it.info.advertisedServices.map { it.info.type } }) nodes.forEach { - val partyNodes = it.services.networkMapCache.partyNodes + val partyNodes = it.services.networkMapCache.allNodes assertEquals(infos.size, partyNodes.size) assertEquals(infos.flatMap { it.legalIdentities }.toSet(), partyNodes.flatMap { it.legalIdentities }.toSet()) } @@ -118,7 +115,7 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { // Start node that is not in databases of other nodes. Point to NMS. Which has't started yet. val charlie = startNodesWithPort(listOf(CHARLIE), noNetworkMap = false)[0] otherNodes.forEach { - assertThat(it.services.networkMapCache.partyNodes).doesNotContain(charlie.info) + assertThat(it.services.networkMapCache.allNodes).doesNotContain(charlie.info) } // Start Network Map and see that charlie node appears in caches. val nms = startNodesWithPort(listOf(DUMMY_NOTARY), noNetworkMap = false)[0] @@ -126,13 +123,13 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { assertTrue(nms.inNodeNetworkMapService != NullNetworkMapService) assertTrue(infos.any { it.legalIdentities.toSet() == nms.info.legalIdentities.toSet() }) otherNodes.forEach { - assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.partyNodes.map { it.chooseIdentity() }) + assertTrue(nms.info.chooseIdentity() in it.services.networkMapCache.allNodes.map { it.chooseIdentity() }) } charlie.internals.nodeReadyFuture.get() // Finish registration. checkConnectivity(listOf(otherNodes[0], nms)) // Checks connectivity from A to NMS. - val cacheA = otherNodes[0].services.networkMapCache.partyNodes - val cacheB = otherNodes[1].services.networkMapCache.partyNodes - val cacheC = charlie.services.networkMapCache.partyNodes + val cacheA = otherNodes[0].services.networkMapCache.allNodes + val cacheB = otherNodes[1].services.networkMapCache.allNodes + val cacheC = charlie.services.networkMapCache.allNodes assertEquals(4, cacheC.size) // Charlie fetched data from NetworkMap assertThat(cacheB).contains(charlie.info) assertEquals(cacheA.toSet(), cacheB.toSet()) diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt index 340e5a7d09..ecb930a28f 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt @@ -1,7 +1,7 @@ package net.corda.node.services.network import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.ServiceInfo +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.config.NodeConfiguration import net.corda.testing.node.MockNetwork diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index a1f7b2c6c6..72b9edfa9c 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -15,7 +15,6 @@ import net.corda.core.internal.concurrent.flatMap import net.corda.core.internal.concurrent.map import net.corda.core.messaging.MessageRecipients import net.corda.core.node.services.PartyInfo -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.queryBy import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize @@ -32,6 +31,7 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.checkpoints import net.corda.node.services.transactions.ValidatingNotaryService @@ -72,6 +72,8 @@ class FlowFrameworkTests { private lateinit var node2: StartedNode private lateinit var notary1: StartedNode private lateinit var notary2: StartedNode + private lateinit var notary1Identity: Party + private lateinit var notary2Identity: Party @Before fun start() { @@ -95,6 +97,8 @@ class FlowFrameworkTests { // We don't create a network map, so manually handle registrations mockNet.registerIdentities() + notary1Identity = notary1.services.myInfo.legalIdentities[1] + notary2Identity = notary2.services.myInfo.legalIdentities[1] } @After @@ -333,11 +337,12 @@ class FlowFrameworkTests { @Test fun `different notaries are picked when addressing shared notary identity`() { - assertEquals(notary1.info.notaryIdentity, notary2.info.notaryIdentity) + assertEquals(notary1Identity, notary2Identity) + assertThat(node1.services.networkMapCache.notaryIdentities.size == 1) node1.services.startFlow(CashIssueFlow( 2000.DOLLARS, OpaqueBytes.of(0x01), - notary1.info.notaryIdentity)).resultFuture.getOrThrow() + notary1Identity)).resultFuture.getOrThrow() // We pay a couple of times, the notary picking should go round robin for (i in 1..3) { val flow = node1.services.startFlow(CashPaymentFlow(500.DOLLARS, node2.info.chooseIdentity())) @@ -345,11 +350,11 @@ class FlowFrameworkTests { flow.resultFuture.getOrThrow() } val endpoint = mockNet.messagingNetwork.endpoint(notary1.network.myAddress as InMemoryMessagingNetwork.PeerHandle)!! - val party1Info = notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!! + val party1Info = notary1.services.networkMapCache.getPartyInfo(notary1Identity)!! assertTrue(party1Info is PartyInfo.DistributedNode) - val notary1Address: MessageRecipients = endpoint.getAddressOfParty(notary1.services.networkMapCache.getPartyInfo(notary1.info.notaryIdentity)!!) + val notary1Address: MessageRecipients = endpoint.getAddressOfParty(notary1.services.networkMapCache.getPartyInfo(notary1Identity)!!) assertThat(notary1Address).isInstanceOf(InMemoryMessagingNetwork.ServiceHandle::class.java) - assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2.info.notaryIdentity)!!)) + assertEquals(notary1Address, endpoint.getAddressOfParty(notary2.services.networkMapCache.getPartyInfo(notary2Identity)!!)) receivedSessionMessages.expectEvents(isStrict = false) { sequence( // First Pay @@ -598,7 +603,7 @@ class FlowFrameworkTests { @Test fun `wait for transaction`() { - val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) + val ptx = TransactionBuilder(notary = notary1Identity) .addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addCommand(dummyCommand(node1.info.chooseIdentity().owningKey)) val stx = node1.services.signInitialTransaction(ptx) @@ -613,7 +618,7 @@ class FlowFrameworkTests { @Test fun `committer throws exception before calling the finality flow`() { - val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) + val ptx = TransactionBuilder(notary = notary1Identity) .addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addCommand(dummyCommand()) val stx = node1.services.signInitialTransaction(ptx) @@ -630,7 +635,7 @@ class FlowFrameworkTests { @Test fun `verify vault query service is tokenizable by force checkpointing within a flow`() { - val ptx = TransactionBuilder(notary = notary1.info.notaryIdentity) + val ptx = TransactionBuilder(notary = notary1Identity) .addOutputState(DummyState(), DUMMY_PROGRAM_ID) .addCommand(dummyCommand(node1.info.chooseIdentity().owningKey)) val stx = node1.services.signInitialTransaction(ptx) diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt index 859369d0ce..2f021beacd 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt @@ -7,17 +7,19 @@ import net.corda.core.crypto.TransactionSignature import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryException import net.corda.core.flows.NotaryFlow -import net.corda.core.node.services.ServiceInfo +import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DummyContract import net.corda.testing.dummyCommand +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.assertj.core.api.Assertions.assertThat import org.junit.After @@ -32,6 +34,7 @@ class NotaryServiceTests { lateinit var mockNet: MockNetwork lateinit var notaryNode: StartedNode lateinit var clientNode: StartedNode + lateinit var notary: Party @Before fun setup() { @@ -42,6 +45,7 @@ class NotaryServiceTests { clientNode = mockNet.createNode(notaryNode.network.myAddress) mockNet.runNetwork() // Clear network map registration messages notaryNode.internals.ensureRegistered() + notary = clientNode.services.getDefaultNotary() } @After @@ -53,7 +57,7 @@ class NotaryServiceTests { fun `should sign a unique transaction with a valid time-window`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .setTimeWindow(Instant.now(), 30.seconds) @@ -69,7 +73,7 @@ class NotaryServiceTests { fun `should sign a unique transaction without a time-window`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) clientNode.services.signInitialTransaction(tx) @@ -84,7 +88,7 @@ class NotaryServiceTests { fun `should report error for transaction with an invalid time-window`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) .setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds) @@ -101,7 +105,7 @@ class NotaryServiceTests { fun `should sign identical transaction multiple times (signing is idempotent)`() { val stx = run { val inputState = issueState(clientNode) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) clientNode.services.signInitialTransaction(tx) @@ -121,13 +125,13 @@ class NotaryServiceTests { fun `should report conflict when inputs are reused across transactions`() { val inputState = issueState(clientNode) val stx = run { - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) clientNode.services.signInitialTransaction(tx) } val stx2 = run { - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addInputState(issueState(clientNode)) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) @@ -155,7 +159,7 @@ class NotaryServiceTests { } fun issueState(node: StartedNode<*>): StateAndRef<*> { - val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) + val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0)) val signedByNode = node.services.signInitialTransaction(tx) val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) node.services.recordTransactions(stx) diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt index 3d69e40f97..1a29ad0811 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt @@ -8,11 +8,12 @@ import net.corda.core.crypto.TransactionSignature import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryException import net.corda.core.flows.NotaryFlow -import net.corda.core.node.services.ServiceInfo +import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.getOrThrow import net.corda.core.transactions.TransactionBuilder import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.issueInvalidState import net.corda.node.services.network.NetworkMapService import net.corda.testing.DUMMY_NOTARY @@ -20,6 +21,7 @@ import net.corda.testing.MEGA_CORP_KEY import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DummyContract import net.corda.testing.dummyCommand +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.assertj.core.api.Assertions.assertThat import org.junit.After @@ -33,6 +35,7 @@ class ValidatingNotaryServiceTests { lateinit var mockNet: MockNetwork lateinit var notaryNode: StartedNode lateinit var clientNode: StartedNode + lateinit var notary: Party @Before fun setup() { @@ -44,6 +47,7 @@ class ValidatingNotaryServiceTests { clientNode = mockNet.createNode(notaryNode.network.myAddress) mockNet.runNetwork() // Clear network map registration messages notaryNode.internals.ensureRegistered() + notary = clientNode.services.getDefaultNotary() } @After @@ -54,8 +58,8 @@ class ValidatingNotaryServiceTests { @Test fun `should report error for invalid transaction dependency`() { val stx = run { - val inputState = issueInvalidState(clientNode, notaryNode.info.notaryIdentity) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity) + val inputState = issueInvalidState(clientNode, notary) + val tx = TransactionBuilder(notary) .addInputState(inputState) .addCommand(dummyCommand(clientNode.info.chooseIdentity().owningKey)) clientNode.services.signInitialTransaction(tx) @@ -75,7 +79,7 @@ class ValidatingNotaryServiceTests { val inputState = issueState(clientNode) val command = Command(DummyContract.Commands.Move(), expectedMissingKey) - val tx = TransactionBuilder(notaryNode.info.notaryIdentity).withItems(inputState, command) + val tx = TransactionBuilder(notary).withItems(inputState, command) clientNode.services.signInitialTransaction(tx) } @@ -98,7 +102,7 @@ class ValidatingNotaryServiceTests { } fun issueState(node: StartedNode<*>): StateAndRef<*> { - val tx = DummyContract.generateInitial(Random().nextInt(), notaryNode.info.notaryIdentity, node.info.chooseIdentity().ref(0)) + val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0)) val signedByNode = node.services.signInitialTransaction(tx) val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) node.services.recordTransactions(stx) diff --git a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt index 347cb75c78..fc56ffee65 100644 --- a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt +++ b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt @@ -1,8 +1,8 @@ package net.corda.attachmentdemo -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.DUMMY_BANK_A diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt index 9f9c269e13..9cd19574bd 100644 --- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt +++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt @@ -1,7 +1,7 @@ package net.corda.attachmentdemo import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_NOTARY diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt index 5907cfa464..f477701a0b 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt @@ -2,8 +2,8 @@ package net.corda.bank import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.BOC import net.corda.testing.driver.driver diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index e7fd1378ee..c12f39a48f 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -1,7 +1,6 @@ package net.corda.bank import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo import net.corda.core.node.services.Vault import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.utilities.getOrThrow @@ -9,6 +8,7 @@ import net.corda.finance.DOLLARS import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.* @@ -33,6 +33,8 @@ class BankOfCordaRPCClientTest { // Big Corporation RPC Client val bigCorpClient = nodeBigCorporation.rpcClientToNode() val bigCorpProxy = bigCorpClient.start("bigCorpCFO", "password2").proxy + bocProxy.waitUntilNetworkReady() + bigCorpProxy.waitUntilNetworkReady() // Register for Bank of Corda Vault updates val criteria = QueryCriteria.VaultQueryCriteria(status = Vault.StateStatus.ALL) @@ -43,11 +45,12 @@ class BankOfCordaRPCClientTest { // Kick-off actual Issuer Flow val anonymous = true + val notary = bocProxy.notaryIdentities().first().party bocProxy.startFlow(::CashIssueAndPaymentFlow, 1000.DOLLARS, BIG_CORP_PARTY_REF, nodeBigCorporation.nodeInfo.chooseIdentity(), anonymous, - nodeBankOfCorda.nodeInfo.notaryIdentity).returnValue.getOrThrow() + notary).returnValue.getOrThrow() // Check Bank of Corda Vault Updates vaultUpdatesBoc.expectEvents { diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt index 4554b7d7c9..8b139ba6f2 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt @@ -4,13 +4,12 @@ import joptsimple.OptionParser import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.NetworkHostAndPort import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.BOC @@ -74,8 +73,7 @@ private class BankOfCordaDriver { advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val bankOfCorda = startNode( providedName = BOC.name, - rpcUsers = listOf(bankUser), - advertisedServices = setOf(ServiceInfo(ServiceType.corda.getSubType("issuer.USD")))) + rpcUsers = listOf(bankUser)) startNode(providedName = BIGCORP_LEGAL_NAME, rpcUsers = listOf(bigCorpUser)) startWebserver(bankOfCorda.get()) waitForAllNodesToFinish() diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt index 60c2e4adc4..b65a7f3131 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt @@ -36,20 +36,19 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) { // TODO: privileged security controls required client.start("bankUser", "test").use { connection -> val rpc = connection.proxy + rpc.waitUntilNetworkReady() // Resolve parties via RPC val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) ?: throw Exception("Unable to locate ${params.issueToPartyName} in Network Map Service") val notaryLegalIdentity = rpc.partyFromX500Name(params.notaryName) ?: throw IllegalStateException("Unable to locate ${params.notaryName} in Network Map Service") - val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity) - ?: throw IllegalStateException("Unable to locate notary node in network map cache") val amount = Amount(params.amount, Currency.getInstance(params.currency)) val anonymous = true val issuerBankPartyRef = OpaqueBytes.of(params.issuerBankPartyRef.toByte()) - return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity) + return rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryLegalIdentity) .returnValue.getOrThrow().stx } } diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt index e88c26868f..2a25342416 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt @@ -46,8 +46,6 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) { rpc.partyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build() val notaryParty = rpc.partyFromX500Name(params.notaryName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.notaryName} in identity service").build() - val notaryNode = rpc.nodeIdentityFromParty(notaryParty) - ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate $notaryParty in network map service").build() val amount = Amount(params.amount, Currency.getInstance(params.currency)) val anonymous = true @@ -56,7 +54,7 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) { // invoke client side of Issuer Flow: IssuanceRequester // The line below blocks and waits for the future to resolve. return try { - rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryNode.notaryIdentity).returnValue.getOrThrow() + rpc.startFlow(::CashIssueAndPaymentFlow, amount, issuerBankPartyRef, issueToParty, anonymous, notaryParty).returnValue.getOrThrow() logger.info("Issue and payment request completed successfully: $params") Response.status(Response.Status.CREATED).build() } catch (e: Exception) { diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 8882bb4627..51e2fca205 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -12,7 +12,6 @@ import net.corda.client.rpc.CordaRPCClient import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.Party import net.corda.core.messaging.vaultTrackBy -import net.corda.core.node.services.ServiceInfo import net.corda.core.toFuture import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow @@ -21,6 +20,7 @@ import net.corda.core.utilities.seconds import net.corda.finance.plugin.registerFinanceJSONMappers import net.corda.irs.contract.InterestRateSwap import net.corda.irs.utilities.uploadFile +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt index aa4ab59ce4..aaa1b17e89 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt @@ -47,8 +47,8 @@ object AutoOfferFlow { @Suspendable override fun call(): SignedTransaction { - require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } - val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity + require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } + val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. // need to pick which ever party is not us val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single() progressTracker.currentStep = DEALING diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt index 3393faa1e0..f020df2552 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt @@ -100,9 +100,7 @@ object FixingFlow { StateAndRef(state, payload.ref) } - override val notaryNode: NodeInfo get() { - return serviceHub.networkMapCache.notaryNodes.single { it.notaryIdentity == dealToFix.state.notary } - } + override val notaryParty: Party get() = dealToFix.state.notary @Suspendable override fun checkProposal(stx: SignedTransaction) = requireThat { // Add some constraints here. diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt index 32d8df11e9..e16314bff9 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt @@ -1,7 +1,7 @@ package net.corda.irs -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt index 13f0e93fb9..11534c404c 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt @@ -54,9 +54,11 @@ object UpdateBusinessDayFlow { * the notary or counterparty still use the old clock, so the time-window on the transaction does not validate. */ private fun getRecipients(): Iterable { - val notaryNodes = serviceHub.networkMapCache.notaryNodes.map { it.legalIdentitiesAndCerts.first().party } // TODO Will break on distributed nodes, but it will change after services removal. - val partyNodes = (serviceHub.networkMapCache.partyNodes.map { it.legalIdentitiesAndCerts.first().party } - notaryNodes).sortedBy { it.name.toString() } - return notaryNodes + partyNodes + val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party } + val peerParties = serviceHub.networkMapCache.allNodes.filter { + it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) } + }.map { it.legalIdentities[0] }.sortedBy { it.name.toString() } + return notaryParties + peerParties } @Suspendable diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt index 9f10e40c25..c6c1d513df 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt @@ -138,6 +138,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) + val notaryId = node1.rpcOps.notaryIdentities().first().party @InitiatingFlow class StartDealFlow(val otherParty: Party, val payload: AutoOffer) : FlowLogic() { @@ -160,7 +161,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten val instigator = StartDealFlow( node2.info.chooseIdentity(), - AutoOffer(notary.info.notaryIdentity, irs)) + AutoOffer(notaryId, irs)) // TODO Pass notary as parameter to Simulation. val instigatorTxFuture = node1.services.startFlow(instigator).resultFuture return allOf(instigatorTxFuture.toCompletableFuture(), acceptorTxFuture).thenCompose { instigatorTxFuture.toCompletableFuture() } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index a466501651..ab6ab1d037 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -6,11 +6,11 @@ import net.corda.finance.utils.CityDatabase import net.corda.finance.utils.WorldMapLocation import net.corda.core.internal.uncheckedCast import net.corda.core.messaging.SingleMessageRecipient -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.ProgressTracker import net.corda.irs.api.NodeInterestRates import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt index 0848b2244f..5d2230fb76 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt @@ -7,8 +7,8 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.internal.div import net.corda.core.internal.stream import net.corda.core.internal.toTypedArray -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.utilities.ServiceIdentityGenerator diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt index a95a5f7f94..503310711c 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt @@ -26,8 +26,7 @@ fun main(args: Array) { /** Interface for using the notary demo API from a client. */ private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private val notary by lazy { - val parties = rpc.networkMapSnapshot() - val id = parties.stream().filter { it.advertisedServices.any { it.info.type.isNotary() } }.map { it.notaryIdentity }.distinct().asSequence().singleOrNull() + val id = rpc.notaryIdentities().distinct().singleOrNull()?.party checkNotNull(id) { "No unique notary identity, try cleaning the node directories." } } diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt index 76c3f34221..f2ba787f10 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt @@ -5,8 +5,8 @@ import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformNode import net.corda.core.identity.CordaX500Name import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.testing.ALICE diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt index d0c3133de8..95398b1aae 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt @@ -1,7 +1,6 @@ package net.corda.notarydemo import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo import net.corda.testing.ALICE import net.corda.testing.BOB import net.corda.testing.DUMMY_NOTARY @@ -12,6 +11,7 @@ import net.corda.notarydemo.flows.DummyIssueAndMove import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformContext +import net.corda.nodeapi.ServiceInfo import net.corda.testing.internal.demorun.* fun main(args: Array) = SingleNotaryCordform.runNodes() diff --git a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt index 6629570ebe..b000d69b65 100644 --- a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt +++ b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt @@ -2,8 +2,8 @@ package net.corda.vega import com.opengamma.strata.product.common.BuySell import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt index ec6ef43a8a..e0f0458994 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt @@ -10,7 +10,6 @@ import net.corda.core.identity.Party import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow import net.corda.core.messaging.vaultQueryBy -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.getOrThrow import net.corda.finance.contracts.DealState import net.corda.vega.analytics.InitialMarginTriple @@ -22,7 +21,6 @@ import net.corda.vega.flows.SimmRevaluation import net.corda.vega.portfolio.Portfolio import net.corda.vega.portfolio.toPortfolio import net.corda.vega.portfolio.toStateAndRef -import org.bouncycastle.asn1.x500.X500Name import java.time.LocalDate import java.time.LocalDateTime import java.time.ZoneId @@ -254,11 +252,11 @@ class PortfolioApi(val rpc: CordaRPCOps) { @Produces(MediaType.APPLICATION_JSON) fun getWhoAmI(): AvailableParties { val parties = rpc.networkMapSnapshot() - val counterParties = parties.filterNot { - it.advertisedServices.any { it.info.type in setOf(ServiceType.networkMap, ServiceType.notary) } - || ownParty in it.legalIdentitiesAndCerts.map { it.party } + val notaries = rpc.notaryIdentities() + // TODO We are not able to filter by network map node now + val counterParties = parties.filterNot { it.legalIdentitiesAndCerts.any { it in notaries } + || ownParty in it.legalIdentities } - return AvailableParties( self = ApiParty(ownParty.owningKey.toBase58String(), ownParty.name), // TODO It will show all identities including service identities. diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt index 0a63c159f5..52d4c4d733 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt @@ -22,8 +22,8 @@ object IRSTradeFlow { class Requester(val swap: SwapData, val otherParty: Party) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } - val notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity + require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } + val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. val (buyer, seller) = if (swap.buyer.second == ourIdentity.owningKey) { Pair(ourIdentity, otherParty) @@ -52,7 +52,7 @@ object IRSTradeFlow { val offer = receive(replyToParty).unwrap { it } // Automatically agree - in reality we'd vet the offer message - require(serviceHub.networkMapCache.notaryNodes.map { it.notaryIdentity }.contains(offer.notary)) + require(serviceHub.networkMapCache.notaryIdentities.map { it.party }.contains(offer.notary)) send(replyToParty, true) subFlow(TwoPartyDealFlow.Acceptor(replyToParty)) } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index 8ad4e384a1..50feca8445 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -61,8 +61,8 @@ object SimmFlow { @Suspendable override fun call(): RevisionedState { logger.debug("Calling from: $ourIdentity. Sending to: $otherParty") - require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } - notary = serviceHub.networkMapCache.notaryNodes.first().notaryIdentity + require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } + notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. val criteria = LinearStateQueryCriteria(participants = listOf(otherParty)) val trades = serviceHub.vaultQueryService.queryBy(criteria).states diff --git a/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt b/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt index c31048985d..a017760163 100644 --- a/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt +++ b/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt @@ -1,7 +1,7 @@ package net.corda.vega -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_C diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 3721c4dfab..68900d95fe 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -1,7 +1,6 @@ package net.corda.traderdemo import net.corda.client.rpc.CordaRPCClient -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.millis import net.corda.finance.DOLLARS @@ -10,6 +9,7 @@ import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CommercialPaperSchemaV1 import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.BOC diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt index 9ac6d6d51f..dd6fab51f6 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt @@ -46,12 +46,10 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) { val ref = OpaqueBytes.of(1) val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") - val notaryLegalIdentity = rpc.partyFromX500Name(DUMMY_NOTARY.name) - ?: throw IllegalStateException("Unable to locate ${DUMMY_NOTARY.name} in Network Map Service") - val notaryNode = rpc.nodeIdentityFromParty(notaryLegalIdentity) - ?: throw IllegalStateException("Unable to locate notary node in network map cache") + val notaryIdentity = rpc.notaryIdentities().first().party + val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) - rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryNode.notaryIdentity).returnValue.getOrThrow() + rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryIdentity).returnValue.getOrThrow() // Pay random amounts of currency up to the requested amount amounts.forEach { pennies -> // TODO This can't be done in parallel, perhaps due to soft-locking issues? @@ -71,7 +69,7 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) { } // The line below blocks and waits for the future to resolve. - rpc.startFlow(::CommercialPaperIssueFlow, amount, ref, seller, notaryNode.notaryIdentity).returnValue.getOrThrow() + rpc.startFlow(::CommercialPaperIssueFlow, amount, ref, seller, notaryIdentity).returnValue.getOrThrow() println("Commercial paper issued to seller") } diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt index e4a3a11802..c7b8c61b2c 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt @@ -29,10 +29,11 @@ class BuyerFlow(val otherParty: Party) : FlowLogic() { // Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation) val amount = receive>(otherParty).unwrap { it } - val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] + require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } + val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party val buyer = TwoPartyTradeFlow.Buyer( otherParty, - notary.notaryIdentity, + notary, amount, CommercialPaper.State::class.java) diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt index c7eeccb797..1d6b3717ba 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt @@ -40,7 +40,7 @@ class SellerFlow(private val otherParty: Party, override fun call(): SignedTransaction { progressTracker.currentStep = SELF_ISSUING - val notary: NodeInfo = serviceHub.networkMapCache.notaryNodes[0] + val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first() @@ -50,7 +50,6 @@ class SellerFlow(private val otherParty: Party, send(otherParty, amount) val seller = TwoPartyTradeFlow.Seller( otherParty, - notary, commercialPaper, amount, cpOwner, diff --git a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt index 7ed7f689cd..1b19fedd9f 100644 --- a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt +++ b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt @@ -1,9 +1,9 @@ package net.corda.traderdemo import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo import net.corda.finance.flows.CashIssueFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.BOC diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt index 2ebcea15d2..c7089024a6 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt @@ -3,14 +3,13 @@ package net.corda.testing.driver import net.corda.core.concurrent.CordaFuture import net.corda.core.internal.div import net.corda.core.internal.list -import net.corda.core.node.services.ServiceInfo import net.corda.core.internal.readLines import net.corda.core.utilities.getOrThrow import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_REGULATOR import net.corda.node.internal.NodeStartup -import net.corda.node.services.api.RegulatorService +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.ProjectStructure.projectRootDir import org.assertj.core.api.Assertions.assertThat @@ -42,7 +41,7 @@ class DriverTests { fun `simple node startup and shutdown`() { val handles = driver { val notary = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) - val regulator = startNode(providedName = DUMMY_REGULATOR.name, advertisedServices = setOf(ServiceInfo(RegulatorService.type))) + val regulator = startNode(providedName = DUMMY_REGULATOR.name) listOf(nodeMustBeUp(notary), nodeMustBeUp(regulator)) } handles.map { nodeMustBeDown(it) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt index 31e5ce8440..ce5db3b6ad 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt @@ -24,6 +24,7 @@ import net.corda.testing.node.MockAttachmentStorage import net.corda.testing.node.MockNetworkMapCache import net.corda.testing.node.MockStateMachineRecordedTransactionMappingStorage import net.corda.testing.node.MockTransactionStorage +import java.security.PublicKey import java.sql.Connection import java.time.Clock @@ -67,6 +68,8 @@ open class MockServiceHubInternal( get() = overrideClock ?: throw UnsupportedOperationException() override val myInfo: NodeInfo get() = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L) // Required to get a dummy platformVersion when required for tests. + override val notaryIdentityKey: PublicKey + get() = throw IllegalStateException("No notary identity in MockServiceHubInternal") override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) override val rpcFlows: List>> get() = throw UnsupportedOperationException() diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt index 709f48da8a..fc82022656 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt @@ -5,7 +5,7 @@ package net.corda.testing import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.CordaRPCOps -import net.corda.core.node.services.ServiceInfo +import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.driver.DriverDSLExposedInterface diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index 1fa121623c..250d29f957 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -19,12 +19,12 @@ import net.corda.core.internal.div import net.corda.core.internal.times import net.corda.core.messaging.CordaRPCOps import net.corda.core.node.NodeInfo -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.* import net.corda.node.internal.Node import net.corda.node.internal.NodeStartup import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.config.* import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.RaftValidatingNotaryService @@ -751,7 +751,7 @@ class DriverDSL( } return firstNotaryFuture.flatMap { firstNotary -> - val notaryParty = firstNotary.nodeInfo.notaryIdentity + val notaryParty = firstNotary.nodeInfo.legalIdentities[1] // TODO For now the second identity is notary identity. restNotaryFutures.transpose().map { restNotaries -> Pair(notaryParty, listOf(firstNotary) + restNotaries) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt index 144cb172eb..7de9b15f40 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt @@ -5,8 +5,8 @@ package net.corda.testing.internal.demorun import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformNode import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.ServiceInfo import net.corda.nodeapi.User fun CordformDefinition.node(configure: CordformNode.() -> Unit) { diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt index 1dc247fb86..e16e3c9eef 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt @@ -11,7 +11,7 @@ import net.corda.core.messaging.MessageRecipientGroup import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.identity.Party -import net.corda.core.node.ServiceEntry +import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.services.PartyInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SingletonSerializeAsToken @@ -106,10 +106,10 @@ class InMemoryMessagingNetwork( @Synchronized fun createNode(manuallyPumped: Boolean, executor: AffinityExecutor, - advertisedServices: List, + notaryService: PartyAndCertificate?, database: CordaPersistence): Pair> { check(counter >= 0) { "In memory network stopped: please recreate." } - val builder = createNodeWithID(manuallyPumped, counter, executor, advertisedServices, database = database) as Builder + val builder = createNodeWithID(manuallyPumped, counter, executor, notaryService, database = database) as Builder counter++ val id = builder.id return Pair(id, builder) @@ -127,14 +127,14 @@ class InMemoryMessagingNetwork( manuallyPumped: Boolean, id: Int, executor: AffinityExecutor, - advertisedServices: List, + notaryService: PartyAndCertificate?, description: CordaX500Name = CordaX500Name(organisation = "In memory node $id", locality = "London", country = "UK"), database: CordaPersistence) : MessagingServiceBuilder { val peerHandle = PeerHandle(id, description) peersMapping[peerHandle.description] = peerHandle // Assume that the same name - the same entity in MockNetwork. - advertisedServices.forEach { if(it.identity.owningKey !is CompositeKey) peersMapping[it.identity.name] = peerHandle } - val serviceHandles = advertisedServices.map { ServiceHandle(it.identity.party) } + notaryService?.let { if (it.owningKey !is CompositeKey) peersMapping[it.name] = peerHandle } + val serviceHandles = notaryService?.let { listOf(ServiceHandle(it.party)) } ?: emptyList() //TODO only notary can be distributed? return Builder(manuallyPumped, peerHandle, serviceHandles, executor, database = database) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index 0e79451095..d5887474f0 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -16,7 +16,6 @@ import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.node.CordaPluginRegistry -import net.corda.core.node.ServiceEntry import net.corda.core.node.services.* import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow @@ -24,6 +23,8 @@ import net.corda.core.utilities.loggerFor import net.corda.finance.utils.WorldMapLocation import net.corda.node.internal.AbstractNode import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.identity.PersistentIdentityService import net.corda.node.services.keys.E2ETestKeyManagementService @@ -163,7 +164,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, !mockNet.threadPerNode, id, serverThread, - makeServiceEntries(), + getNotaryIdentity(), myLegalName, database) .start() @@ -178,7 +179,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, .toTypedArray() val identityService = PersistentIdentityService(info.legalIdentitiesAndCerts, trustRoot = trustRoot, caCertificates = *caCertificates) - services.networkMapCache.partyNodes.forEach { it.legalIdentitiesAndCerts.forEach { identityService.verifyAndRegisterIdentity(it) } } + services.networkMapCache.allNodes.forEach { it.legalIdentitiesAndCerts.forEach { identityService.verifyAndRegisterIdentity(it) } } services.networkMapCache.changed.subscribe { mapChange -> // TODO how should we handle network map removal if (mapChange is NetworkMapCache.MapChange.Added) { @@ -202,20 +203,15 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, return InMemoryNetworkMapService(services, platformVersion) } - override fun makeServiceEntries(): List { - val defaultEntries = super.makeServiceEntries() - return if (overrideServices == null) { - defaultEntries - } else { - defaultEntries.map { - val override = overrideServices[it.info] - if (override != null) { - // TODO: Store the key - ServiceEntry(it.info, getTestPartyAndCertificate(it.identity.name, override.public)) - } else { - it - } - } + override fun getNotaryIdentity(): PartyAndCertificate? { + val defaultIdentity = super.getNotaryIdentity() + val override = overrideServices?.filter { it.key.type.isNotary() }?.entries?.singleOrNull() + return if (override == null || defaultIdentity == null) + defaultIdentity + else { + // Ensure that we always have notary in name and type of it. TODO It is temporary solution until we will have proper handling of NetworkParameters + myNotaryIdentity = getTestPartyAndCertificate(defaultIdentity.name, override.value.public) + myNotaryIdentity } } @@ -264,7 +260,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, return BFTNonValidatingNotaryService(services, object : BFTSMaRt.Cluster { override fun waitUntilAllReplicasHaveInitialized() { val clusterNodes = mockNet.nodes.filter { - services.notaryIdentityKey in it.started!!.info.serviceIdentities(BFTNonValidatingNotaryService.type).map { it.owningKey } + services.notaryIdentityKey in it.info.legalIdentitiesAndCerts.map { it.owningKey } } if (clusterNodes.size != configuration.notaryClusterAddresses.size) { throw IllegalStateException("Unable to enumerate all nodes in BFT cluster.") @@ -321,10 +317,10 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, /** Like the other [createNode] but takes a [Factory] and propagates its [MockNode] subtype. */ fun createNode(networkMapAddress: SingleMessageRecipient? = null, forcedID: Int? = null, nodeFactory: Factory, - legalName: CordaX500Name? = null, overrideServices: Map? = null, - entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), - vararg advertisedServices: ServiceInfo, - configOverrides: (NodeConfiguration) -> Any? = {}): StartedNode { + legalName: CordaX500Name? = null, overrideServices: Map? = null, + entropyRoot: BigInteger = BigInteger.valueOf(random63BitValue()), + vararg advertisedServices: ServiceInfo, + configOverrides: (NodeConfiguration) -> Any? = {}): StartedNode { return uncheckedCast(createNodeImpl(networkMapAddress, forcedID, nodeFactory, true, legalName, overrideServices, entropyRoot, advertisedServices, configOverrides).started)!! } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt index bb2ccf5c05..1d23868243 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -156,6 +156,7 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub { val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public) return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L) } + override val notaryIdentityKey: PublicKey get() = throw UnsupportedOperationException() override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2) lateinit var hibernatePersister: HibernateObserver diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt index 37222c9f80..6d99d28d19 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt @@ -5,11 +5,11 @@ import net.corda.core.identity.CordaX500Name import net.corda.core.internal.concurrent.* import net.corda.core.internal.createDirectories import net.corda.core.internal.div -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.getOrThrow import net.corda.node.internal.Node import net.corda.node.internal.StartedNode +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.config.ConfigHelper import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.config.configOf diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index 25059c5d8e..e449461ab8 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -11,6 +11,7 @@ import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.cert import net.corda.core.node.NodeInfo +import net.corda.core.node.ServiceHub import net.corda.core.node.services.IdentityService import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.OpaqueBytes @@ -162,3 +163,5 @@ inline fun amqpSpecific(reason: String, function: () -> Unit) */ fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first() fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party + +fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first().party diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt index ae76a18c06..d0137bd76b 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt @@ -2,9 +2,9 @@ package net.corda.demobench.model import com.typesafe.config.Config import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.NetworkHostAndPort +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import tornadofx.* import java.io.IOException import java.nio.file.Files diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 72adb34d53..95d5592c5b 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -1,10 +1,10 @@ package net.corda.demobench.model import net.corda.core.identity.CordaX500Name -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.demobench.plugin.PluginController import net.corda.demobench.pty.R3Pty +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import tornadofx.* import java.io.IOException import java.lang.management.ManagementFactory diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index c9097fa7fb..eef900b1b7 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -12,8 +12,6 @@ import net.corda.core.internal.concurrent.thenMatch import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.FlowHandle import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo -import net.corda.core.node.services.ServiceType import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.getOrThrow import net.corda.finance.GBP @@ -26,6 +24,8 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow.IssueAndPaymentRequest import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE @@ -52,6 +52,7 @@ class ExplorerSimulation(val options: OptionSet) { private lateinit var bobNode: NodeHandle private lateinit var issuerNodeGBP: NodeHandle private lateinit var issuerNodeUSD: NodeHandle + private lateinit var notary: Party private val RPCConnections = ArrayList() private val issuers = HashMap() @@ -172,9 +173,10 @@ class ExplorerSimulation(val options: OptionSet) { private fun startNormalSimulation() { println("Running simulation mode ...") setUpRPC() + notary = aliceNode.rpc.notaryIdentities().first().party val eventGenerator = EventGenerator( parties = parties.map { it.first }, - notary = notaryNode.nodeInfo.notaryIdentity, + notary = notary, currencies = listOf(GBP, USD) ) val maxIterations = 100_000 @@ -184,7 +186,8 @@ class ExplorerSimulation(val options: OptionSet) { for (ref in 0..1) { for ((currency, issuer) in issuers) { val amount = Amount(1_000_000, currency) - issuer.startFlow(::CashIssueAndPaymentFlow, amount, OpaqueBytes(ByteArray(1, { ref.toByte() })), it, anonymous, notaryNode.nodeInfo.notaryIdentity).returnValue.getOrThrow() + issuer.startFlow(::CashIssueAndPaymentFlow, amount, OpaqueBytes(ByteArray(1, { ref.toByte() })), + it, anonymous, notary).returnValue.getOrThrow() } } } @@ -197,7 +200,7 @@ class ExplorerSimulation(val options: OptionSet) { setUpRPC() val eventGenerator = ErrorFlowsEventGenerator( parties = parties.map { it.first }, - notary = notaryNode.nodeInfo.notaryIdentity, + notary = notary, currencies = listOf(GBP, USD) ) val maxIterations = 10_000 diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt index cc713da51c..25a85ec19e 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt @@ -7,36 +7,28 @@ import net.corda.client.jfx.model.observableList import net.corda.client.jfx.model.observableValue import net.corda.client.jfx.utils.ChosenList import net.corda.client.jfx.utils.map +import net.corda.core.identity.Party import net.corda.core.node.NodeInfo -import net.corda.core.node.ServiceEntry import tornadofx.* -import java.util.* val ISSUER_SERVICE_TYPE = Regex("corda.issuer.(USD|GBP|CHF|EUR)") class IssuerModel { + // TODO Explorer will be fixed as separate PR. private val networkIdentities by observableList(NetworkIdentityModel::networkIdentities) - private val myNodeInfo by observableValue(NetworkIdentityModel::myNodeInfo) + private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) private val supportedCurrencies by observableList(ReportingCurrencyModel::supportedCurrencies) - val issuers: ObservableList = FXCollections.observableList(networkIdentities.flatMap { it.advertisedServices }.filter { it.info.type.id.matches(ISSUER_SERVICE_TYPE) }) + val issuers: ObservableList = FXCollections.observableList(networkIdentities) - val currencyTypes = ChosenList(myNodeInfo.map { - it?.issuerCurrency()?.let { (listOf(it)).observable() } ?: supportedCurrencies - }) + val currencyTypes = ChosenList(myIdentity.map { supportedCurrencies }) - val transactionTypes = ChosenList(myNodeInfo.map { + val transactionTypes = ChosenList(myIdentity.map { if (it?.isIssuerNode() ?: false) CashTransaction.values().asList().observable() else listOf(CashTransaction.Pay).observable() }) - private fun NodeInfo.isIssuerNode() = advertisedServices.any { it.info.type.id.matches(ISSUER_SERVICE_TYPE) } - - private fun NodeInfo.issuerCurrency() = if (isIssuerNode()) { - val issuer = advertisedServices.first { it.info.type.id.matches(ISSUER_SERVICE_TYPE) } - Currency.getInstance(issuer.info.type.id.substringAfterLast(".")) - } else - null + private fun Party.isIssuerNode() = true } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index c3bff3753e..6470c57c5b 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -42,7 +42,7 @@ class Network : CordaView() { override val icon = FontAwesomeIcon.GLOBE // Inject data. private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) - private val notaries by observableList(NetworkIdentityModel::notaries) + private val notaries by observableList(NetworkIdentityModel::notaryNodes) private val peers by observableList(NetworkIdentityModel::parties) private val transactions by observableList(TransactionDataModel::partiallyResolvedTransactions) var centralPeer: String? = null @@ -102,7 +102,6 @@ class Network : CordaView() { copyableLabel(SimpleObjectProperty(identity.owningKey.toBase58String())).apply { minWidth = 400.0 } } } - row("Services :") { label(node.advertisedServices.map { it.info }.joinToString(", ")) } node.getWorldMapLocation()?.apply { row("Location :") { label(this@apply.description) } } } } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt index 65536a0bbe..d92993d52a 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt @@ -42,6 +42,8 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow.IssueAndPaymentRequest import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow.PaymentRequest +import net.corda.testing.chooseIdentity +import net.corda.testing.chooseIdentityAndCert import org.controlsfx.dialog.ExceptionDialog import tornadofx.* import java.math.BigDecimal @@ -154,7 +156,7 @@ class NewTransaction : Fragment() { val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef when (it) { executeButton -> when (transactionTypeCB.value) { - CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first().notaryIdentity, anonymous) + CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first().party, anonymous) CashTransaction.Pay -> PaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), partyBChoiceBox.value.party, anonymous = anonymous) CashTransaction.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef) else -> null @@ -183,16 +185,14 @@ class NewTransaction : Fragment() { partyBLabel.textProperty().bind(transactionTypeCB.valueProperty().map { it?.partyNameB?.let { "$it : " } }) partyBChoiceBox.apply { visibleProperty().bind(transactionTypeCB.valueProperty().map { it?.partyNameB }.isNotNull()) - val services = parties.flatMap { it.advertisedServices.map { it.identity }} - // TODO It's a bit hacky and ugly now, because we lost main identity... and we will loose services. - items = FXCollections.observableList(parties.flatMap { it.legalIdentitiesAndCerts } - services).sorted() + items = FXCollections.observableList(parties.map { it.chooseIdentityAndCert() }).sorted() converter = stringConverter { it?.let { PartyNameFormatter.short.format(it.name) } ?: "" } } // Issuer issuerLabel.visibleProperty().bind(transactionTypeCB.valueProperty().isNotNull) // TODO This concept should burn (after services removal...) issuerChoiceBox.apply { - items = issuers.map { it.identity.party }.unique().sorted() + items = issuers.map { it.chooseIdentity() }.unique().sorted() converter = stringConverter { PartyNameFormatter.short.format(it.name) } visibleProperty().bind(transactionTypeCB.valueProperty().map { it == CashTransaction.Pay }) } diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt index 4db3fa1863..b914b12028 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt @@ -42,9 +42,10 @@ data class DisruptionSpec( * * Randomly block queues. * * Randomly duplicate messages, perhaps to other queues even. */ - -val isNetworkMap = { node: NodeConnection -> node.info.advertisedServices.any { it.info.type == NetworkMapService.type } } -val isNotary = { node: NodeConnection -> node.info.advertisedServices.any { it.info.type.isNotary() } } +val isNotary = { node: NodeConnection -> + val notaries = node.proxy.notaryIdentities() + node.info.legalIdentitiesAndCerts.any { it in notaries } +} fun ((A) -> Boolean).or(other: (A) -> Boolean): (A) -> Boolean = { this(it) || other(it) } fun hang(hangIntervalRange: LongRange) = Disruption("Hang randomly") { node, random -> diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt index 884a7fd1ca..b90fa55076 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt @@ -173,6 +173,8 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List log.info("Connected to all nodes!") val hostNodeMap = ConcurrentHashMap() @@ -191,16 +193,13 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Main.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Main.kt index 4a9c59d780..0bd12ae78d 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Main.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Main.kt @@ -88,7 +88,7 @@ private fun runLoadTest(loadTestConfiguration: LoadTestConfiguration) { ), DisruptionSpec( disruption = kill, - nodeFilter = isNetworkMap.or(isNotary), + nodeFilter = isNotary, // TODO Fix it with network map, isNetworkMap.or(isNotary). noDisruptionWindowMs = 10000L..20000L // Takes a while for it to restart ), // DOCS START 1 @@ -117,7 +117,7 @@ private fun runLoadTest(loadTestConfiguration: LoadTestConfiguration) { ), DisruptionSpec( disruption = kill, - nodeFilter = isNetworkMap.or(isNotary), + nodeFilter = isNotary, // TODO Fix it with network map, isNetworkMap.or(isNotary). noDisruptionWindowMs = 10000L..20000L // Takes a while for it to restart ), DisruptionSpec( diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt index 58189eef97..ec1f6c1e7a 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/CrossCashTest.kt @@ -123,6 +123,7 @@ val crossCashTest = LoadTest( generate = { (nodeVaults), parallelism -> val nodeMap = simpleNodes.associateBy { it.mainIdentity } + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party Generator.pickN(parallelism, simpleNodes).flatMap { nodes -> Generator.sequence( nodes.map { node -> @@ -139,7 +140,7 @@ val crossCashTest = LoadTest( } } val command = Generator.frequency( - listOf(1.0 to generateIssue(10000, USD, notary.info.notaryIdentity, possibleRecipients)) + moves + exits + listOf(1.0 to generateIssue(10000, USD, notaryIdentity, possibleRecipients)) + moves + exits ) command.map { CrossCashCommand(it, nodeMap[node.mainIdentity]!!) } } diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/NotaryTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/NotaryTest.kt index 81ea0b4fa2..b96f6f4f40 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/NotaryTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/NotaryTest.kt @@ -24,7 +24,7 @@ val dummyNotarisationTest = LoadTest( val issuerServices = MockServices(DUMMY_CASH_ISSUER_KEY) val generateTx = Generator.pickOne(simpleNodes).flatMap { node -> Generator.int().map { - val issueBuilder = DummyContract.generateInitial(it, notary.info.notaryIdentity, DUMMY_CASH_ISSUER) + val issueBuilder = DummyContract.generateInitial(it, notary.info.legalIdentities[1], DUMMY_CASH_ISSUER) // TODO notary choice val issueTx = issuerServices.signInitialTransaction(issueBuilder) val asset = issueTx.tx.outRef(0) val moveBuilder = DummyContract.move(asset, DUMMY_CASH_ISSUER.party) diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt index 650a872619..bb259d19bf 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt @@ -35,10 +35,10 @@ data class SelfIssueState( val selfIssueTest = LoadTest( // DOCS END 1 "Self issuing cash randomly", - generate = { _, parallelism -> + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party val generateIssue = Generator.pickOne(simpleNodes).flatMap { node -> - generateIssue(1000, USD, notary.info.notaryIdentity, listOf(node.mainIdentity)).map { + generateIssue(1000, USD, notaryIdentity, listOf(node.mainIdentity)).map { SelfIssueCommand(it, node) } } diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt index 368df94138..d92f8deadf 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt @@ -49,10 +49,11 @@ object StabilityTest { fun selfIssueTest(replication: Int) = LoadTest( "Self issuing lot of cash", generate = { _, _ -> + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party // Self issue cash is fast, its ok to flood the node with this command. val generateIssue = simpleNodes.map { issuer -> - SelfIssueCommand(IssueAndPaymentRequest(Amount(100000, USD), OpaqueBytes.of(0), issuer.mainIdentity, notary.info.notaryIdentity, anonymous = true), issuer) + SelfIssueCommand(IssueAndPaymentRequest(Amount(100000, USD), OpaqueBytes.of(0), issuer.mainIdentity, notaryIdentity, anonymous = true), issuer) } Generator.pure(List(replication) { generateIssue }.flatten()) }, diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt index 9df62e4232..0c1ec073ca 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt @@ -3,7 +3,6 @@ package net.corda.verifier import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow -import net.corda.core.node.services.ServiceInfo import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.OpaqueBytes @@ -12,6 +11,7 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.config.VerifierType import net.corda.node.services.transactions.ValidatingNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.ALICE import net.corda.testing.DUMMY_NOTARY import net.corda.testing.driver.NetworkMapStartStrategy @@ -117,8 +117,9 @@ class VerifierTests { val notaryFuture = startNode(providedName = DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(ValidatingNotaryService.type)), verifierType = VerifierType.OutOfProcess) val alice = aliceFuture.get() val notary = notaryFuture.get() + val notaryIdentity = notary.nodeInfo.legalIdentities[1] startVerifier(notary) - alice.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notaryFuture.get().nodeInfo.notaryIdentity).returnValue.get() + alice.rpc.startFlow(::CashIssueFlow, 10.DOLLARS, OpaqueBytes.of(0), notaryIdentity).returnValue.get() notary.waitUntilNumberOfVerifiers(1) for (i in 1..10) { alice.rpc.startFlow(::CashPaymentFlow, 10.DOLLARS, alice.nodeInfo.chooseIdentity()).returnValue.get() From 806d1b9b822c6584563bf1f13d2d7bc50828f0dc Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Wed, 20 Sep 2017 14:52:33 +0100 Subject: [PATCH 015/230] Removes repo link in tut to lower maint. overhead. (#1567) --- docs/source/tut-two-party-introduction.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/docs/source/tut-two-party-introduction.rst b/docs/source/tut-two-party-introduction.rst index e49de7dd9e..95ad302e2c 100644 --- a/docs/source/tut-two-party-introduction.rst +++ b/docs/source/tut-two-party-introduction.rst @@ -1,10 +1,7 @@ Introduction ============ -.. note:: This tutorial extends the CorDapp built during the :doc:`Hello, World tutorial `. You can - download the final version of the CorDapp produced in that tutorial for - `Java `_ or - `Kotlin `_. +.. note:: This tutorial extends the CorDapp built during the :doc:`Hello, World tutorial `. In the Hello, World tutorial, we built a CorDapp allowing us to model IOUs on ledger. Our CorDapp was made up of three elements: From ef2352a4046edc53527695701e37105c96ad148b Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Wed, 20 Sep 2017 13:06:43 +0200 Subject: [PATCH 016/230] Adjustments to the PR checklist * Use github task list format. * Remove (seemingly?) duplicated items. * People keep forgetting to delete the section so give up and just try to ensure the top line is edited. * Add a police emoji to make it clear we're serious --- .github/PULL_REQUEST_TEMPLATE.md | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 62d77dd2d8..5aec9bd194 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -1,15 +1,11 @@ -Thank you for choosing to contribute to Corda. +👮🏻👮🏻👮🏻 !!!! DESCRIBE YOUR CHANGES HERE !!!! DO NOT FORGET !!!! 👮🏻👮🏻👮🏻 -Your PR must be approved by one or more reviewers and all tests must be passed on TeamCity (https://ci.corda.r3cev.com) in order to be merged. -Once you have submitted a PR you are responsible for keeping it up to date until the time it is merged. +# PR Checklist: -PR Checklist: +- [ ] Have you run the unit, integration and smoke tests as described here? https://docs.corda.net/head/testing.html +- [ ] If you added/changed public APIs, did you write/update the JavaDocs? +- [ ] If the changes are of interest to application developers, have you added them to the changelog, and potentially release notes? +- [ ] If you are contributing for the first time, please read the agreement in CONTRIBUTING.md now and add to this Pull Request that you agree to it. -1. Ensure any new code is tested as described in https://docs.corda.net/testing.html -2. Ensure you have done any relevant automated testing and manual testing -3. Add your changes to docs/source/changelog.rst -4. Update any documentation in docs/source relating to your changes and learn how to build them in https://docs.corda.net/building-the-docs.html -5. If you are contributing for the first time please read the agreement in CONTRIBUTING.md now and add to this Pull Request that you have read, and agreed to, the agreement. - -Please remove this message when you have read it. +Thanks for your code, it's appreciated! :) From adb8c5ead2d7d4c4525501d0e1eddfad16a3a1f3 Mon Sep 17 00:00:00 2001 From: Patrick Kuo Date: Wed, 20 Sep 2017 17:05:29 +0100 Subject: [PATCH 017/230] Generate distributed service certificate properly in keystore (#1529) * * generate distributed service certificate properly in keystre instead of saving key in flat file when using `generateToDisk` * move composite key loading hack to devSSL keystore generation process. * fix and distributed service un-ignore test * update comment to clarify the composite key certificate creation process. * fixup after rebase --- .../node/services/BFTNotaryServiceTests.kt | 5 +- .../node/services/DistributedServiceTests.kt | 2 +- .../node/services/RaftNotaryServiceTests.kt | 7 +-- .../services/messaging/P2PMessagingTest.kt | 10 ++-- .../net/corda/node/internal/AbstractNode.kt | 58 ++++++------------- .../node/services/config/ConfigUtilities.kt | 16 +++++ .../keys/PersistentKeyManagementService.kt | 2 +- .../utilities/ServiceIdentityGenerator.kt | 23 +++++--- .../statemachine/FlowFrameworkTests.kt | 4 +- .../kotlin/net/corda/testing/driver/Driver.kt | 2 +- .../net/corda/testing/node/NodeBasedTest.kt | 11 ++-- 11 files changed, 69 insertions(+), 71 deletions(-) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index baa1fe3759..693a9d83fc 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -37,7 +37,7 @@ import kotlin.test.assertTrue class BFTNotaryServiceTests { companion object { - private val clusterName = CordaX500Name(organisation = "BFT", locality = "Zurich", country = "CH") + private val clusterName = CordaX500Name(commonName = BFTNonValidatingNotaryService.type.id, organisation = "BFT", locality = "Zurich", country = "CH") private val serviceType = BFTNonValidatingNotaryService.type } @@ -55,12 +55,11 @@ class BFTNotaryServiceTests { replicaIds.map { mockNet.baseDirectory(mockNet.nextNodeId + it) }, serviceType.id, clusterName) - val bftNotaryService = ServiceInfo(serviceType) + val bftNotaryService = ServiceInfo(serviceType, clusterName) val notaryClusterAddresses = replicaIds.map { NetworkHostAndPort("localhost", 11000 + it * 10) } replicaIds.forEach { replicaId -> mockNet.createNode( node.network.myAddress, - legalName = clusterName.copy(organisation = clusterName.organisation + replicaId), advertisedServices = bftNotaryService, configOverrides = { whenever(it.bftSMaRt).thenReturn(BFTSMaRtConfiguration(replicaId, false, exposeRaces)) diff --git a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt index 3ce49fe837..36db192797 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/DistributedServiceTests.kt @@ -39,7 +39,7 @@ class DistributedServiceTests : DriverBasedTest() { ) val aliceFuture = startNode(providedName = ALICE.name, rpcUsers = listOf(testUser)) val notariesFuture = startNotaryCluster( - DUMMY_NOTARY.name, + DUMMY_NOTARY.name.copy(commonName = RaftValidatingNotaryService.type.id), rpcUsers = listOf(testUser), clusterSize = clusterSize, type = RaftValidatingNotaryService.type diff --git a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt index 4534874e9b..c70ffb050a 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/RaftNotaryServiceTests.kt @@ -12,22 +12,21 @@ import net.corda.core.internal.concurrent.transpose import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode +import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.testing.DUMMY_BANK_A +import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyContract import net.corda.testing.dummyCommand -import net.corda.testing.chooseIdentity import net.corda.testing.node.NodeBasedTest -import org.junit.Ignore import org.junit.Test import java.util.* import kotlin.test.assertEquals import kotlin.test.assertFailsWith class RaftNotaryServiceTests : NodeBasedTest() { - private val notaryName = CordaX500Name(organisation = "RAFT Notary Service", locality = "London", country = "GB") + private val notaryName = CordaX500Name(commonName = RaftValidatingNotaryService.type.id, organisation = "RAFT Notary Service", locality = "London", country = "GB") - @Ignore @Test fun `detect double spend`() { val (bankA) = listOf( diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index 1d37d5609d..97b488130e 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -31,7 +31,7 @@ import java.util.concurrent.atomic.AtomicInteger class P2PMessagingTest : NodeBasedTest() { private companion object { - val DISTRIBUTED_SERVICE_NAME = CordaX500Name(organisation = "DistributedService", locality = "London", country = "GB") + val DISTRIBUTED_SERVICE_NAME = CordaX500Name(commonName = RaftValidatingNotaryService.type.id, organisation = "DistributedService", locality = "London", country = "GB") val SERVICE_2_NAME = CordaX500Name(organisation = "Service 2", locality = "London", country = "GB") } @@ -69,23 +69,23 @@ class P2PMessagingTest : NodeBasedTest() { RaftValidatingNotaryService.type.id, DISTRIBUTED_SERVICE_NAME) + val distributedService = ServiceInfo(RaftValidatingNotaryService.type, DISTRIBUTED_SERVICE_NAME) val notaryClusterAddress = freeLocalHostAndPort() startNetworkMapNode( DUMMY_MAP.name, - advertisedServices = setOf(ServiceInfo(RaftValidatingNotaryService.type, DUMMY_MAP.name.copy(commonName = "DistributedService"))), + advertisedServices = setOf(distributedService), configOverrides = mapOf("notaryNodeAddress" to notaryClusterAddress.toString())) val (serviceNode2, alice) = listOf( startNode( SERVICE_2_NAME, - advertisedServices = setOf(ServiceInfo(RaftValidatingNotaryService.type, SERVICE_2_NAME.copy(commonName = "DistributedService"))), + advertisedServices = setOf(distributedService), configOverrides = mapOf( "notaryNodeAddress" to freeLocalHostAndPort().toString(), "notaryClusterAddresses" to listOf(notaryClusterAddress.toString()))), startNode(ALICE.name) ).transpose().getOrThrow() - val serviceName = serviceNode2.info.legalIdentities[1].name - assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), serviceName, alice) + assertAllNodesAreUsed(listOf(networkMapNode, serviceNode2), DISTRIBUTED_SERVICE_NAME, alice) } @Ignore diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index b61954da4f..b4fbfcb6c5 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -13,10 +13,12 @@ import net.corda.core.flows.ContractUpgradeFlow.Acceptor import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate -import net.corda.core.internal.* +import net.corda.core.internal.VisibleForTesting +import net.corda.core.internal.cert import net.corda.core.internal.concurrent.doneFuture import net.corda.core.internal.concurrent.flatMap import net.corda.core.internal.concurrent.openFuture +import net.corda.core.internal.toX509CertHolder import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.RPCOps import net.corda.core.messaging.SingleMessageRecipient @@ -36,8 +38,6 @@ import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappProvider import net.corda.node.services.NotaryChangeHandler import net.corda.node.services.NotifyTransactionHandler -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType import net.corda.node.services.api.* import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.config.configureWithDevSSLCertificate @@ -67,13 +67,14 @@ import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.VaultSoftLockManager import net.corda.node.utilities.* import net.corda.node.utilities.AddOrRemove.ADD +import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.ServiceType import net.corda.nodeapi.internal.serialization.DefaultWhitelist import org.apache.activemq.artemis.utils.ReusableLatch import org.slf4j.Logger import rx.Observable import java.io.IOException import java.lang.reflect.InvocationTargetException -import java.nio.file.Path import java.security.KeyPair import java.security.KeyStoreException import java.security.PublicKey @@ -431,7 +432,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, * Used only for notary identities. */ protected open fun getNotaryIdentity(): PartyAndCertificate? { - return advertisedServices.singleOrNull { it.type.isNotary() }?.let { obtainIdentity(it) } + return advertisedServices.singleOrNull { it.type.isNotary() }?.let { + it.name?.let { + require(it.commonName != null) {"Common name must not be null for notary service, use service type id as common name."} + require(ServiceType.parse(it.commonName!!).isNotary()) {"Common name for notary service must be the notary service type id."} + } + obtainIdentity(it) + } } @VisibleForTesting @@ -630,43 +637,30 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, // Create node identity if service info = null Pair("identity", myLegalName.copy(commonName = null)) } else { - // Ensure that we always have notary in name and type of it. TODO It is temporary solution until we will have proper handling of NetworkParameters - val baseName = serviceInfo.name ?: myLegalName - val name = if (baseName.commonName == null) - baseName.copy(commonName = serviceInfo.type.id) - else - baseName.copy(commonName = baseName.commonName + " " + serviceInfo.type.id) + val name = serviceInfo.name ?: myLegalName.copy(commonName = serviceInfo.type.id) Pair(serviceInfo.type.id, name) } // TODO: Integrate with Key management service? val privateKeyAlias = "$id-private-key" - val compositeKeyAlias = "$id-composite-key" if (!keyStore.containsAlias(privateKeyAlias)) { - val privKeyFile = configuration.baseDirectory / privateKeyAlias - val pubIdentityFile = configuration.baseDirectory / "$id-public" - val compositeKeyFile = configuration.baseDirectory / compositeKeyAlias // TODO: Remove use of [ServiceIdentityGenerator.generateToDisk]. - // Get keys from key file. - // TODO: this is here to smooth out the key storage transition, remove this migration in future release. - if (privKeyFile.exists()) { - migrateKeysFromFile(keyStore, name, pubIdentityFile, privKeyFile, compositeKeyFile, privateKeyAlias, compositeKeyAlias) - } else { log.info("$privateKeyAlias not found in key store ${configuration.nodeKeystore}, generating fresh key!") keyStore.signAndSaveNewKeyPair(name, privateKeyAlias, generateKeyPair()) - } } val (x509Cert, keys) = keyStore.certificateAndKeyPair(privateKeyAlias) // TODO: Use configuration to indicate composite key should be used instead of public key for the identity. + val compositeKeyAlias = "$id-composite-key" val certificates = if (keyStore.containsAlias(compositeKeyAlias)) { // Use composite key instead if it exists val certificate = keyStore.getCertificate(compositeKeyAlias) - // We have to create the certificate chain for the composite key manually, this is because in order to store - // the chain in key store we need a private key, however there is no corresponding private key for the composite key. - Lists.asList(certificate, keyStore.getCertificateChain(X509Utilities.CORDA_CLIENT_CA)) + // We have to create the certificate chain for the composite key manually, this is because we don't have a keystore + // provider that understand compositeKey-privateKey combo. The cert chain is created using the composite key certificate + + // the tail of the private key certificates, as they are both signed by the same certificate chain. + Lists.asList(certificate, keyStore.getCertificateChain(privateKeyAlias).drop(1).toTypedArray()) } else { keyStore.getCertificateChain(privateKeyAlias).let { check(it[0].toX509CertHolder() == x509Cert) { "Certificates from key store do not line up!" } @@ -683,22 +677,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, return PartyAndCertificate(CertificateFactory.getInstance("X509").generateCertPath(certificates)) } - private fun migrateKeysFromFile(keyStore: KeyStoreWrapper, serviceName: CordaX500Name, - pubKeyFile: Path, privKeyFile: Path, compositeKeyFile:Path, - privateKeyAlias: String, compositeKeyAlias: String) { - log.info("Migrating $privateKeyAlias from file to key store...") - // Check that the identity in the config file matches the identity file we have stored to disk. - // Load the private key. - val publicKey = Crypto.decodePublicKey(pubKeyFile.readAll()) - val privateKey = Crypto.decodePrivateKey(privKeyFile.readAll()) - keyStore.signAndSaveNewKeyPair(serviceName, privateKeyAlias, KeyPair(publicKey, privateKey)) - // Store composite key separately. - if (compositeKeyFile.exists()) { - keyStore.savePublicKey(serviceName, compositeKeyAlias, Crypto.decodePublicKey(compositeKeyFile.readAll())) - } - log.info("Finish migrating $privateKeyAlias from file to keystore.") - } - protected open fun generateKeyPair() = cryptoGenerateKeyPair() private inner class ServiceHubInternalImpl : ServiceHubInternal, SingletonSerializeAsToken() { diff --git a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt index fa631fe0a1..f8d68d3146 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/ConfigUtilities.kt @@ -56,6 +56,22 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) { if (!sslKeystore.exists() || !nodeKeystore.exists()) { val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass") createKeystoreForCordaNode(sslKeystore, nodeKeystore, keyStorePassword, keyStorePassword, caKeyStore, "cordacadevkeypass", myLegalName) + + // Move distributed service composite key (generated by ServiceIdentityGenerator.generateToDisk) to keystore if exists. + val distributedServiceKeystore = certificatesDirectory / "distributedService.jks" + if (distributedServiceKeystore.exists()) { + val serviceKeystore = loadKeyStore(distributedServiceKeystore, "cordacadevpass") + val cordaNodeKeystore = loadKeyStore(nodeKeystore, keyStorePassword) + + serviceKeystore.aliases().iterator().forEach { + if (serviceKeystore.isKeyEntry(it)) { + cordaNodeKeystore.setKeyEntry(it, serviceKeystore.getKey(it, "cordacadevkeypass".toCharArray()), keyStorePassword.toCharArray(), serviceKeystore.getCertificateChain(it)) + } else { + cordaNodeKeystore.setCertificateEntry(it, serviceKeystore.getCertificate(it)) + } + } + cordaNodeKeystore.save(nodeKeystore, keyStorePassword) + } } } diff --git a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt index 5117edd8c1..de1b479c1f 100644 --- a/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt +++ b/node/src/main/kotlin/net/corda/node/services/keys/PersistentKeyManagementService.kt @@ -36,7 +36,7 @@ class PersistentKeyManagementService(val identityService: IdentityService, class PersistentKey( @Id - @Column(name = "public_key") + @Column(length = 6000, name = "public_key") var publicKey: String = "", @Lob diff --git a/node/src/main/kotlin/net/corda/node/utilities/ServiceIdentityGenerator.kt b/node/src/main/kotlin/net/corda/node/utilities/ServiceIdentityGenerator.kt index 70ba6af802..198a139bd5 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/ServiceIdentityGenerator.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/ServiceIdentityGenerator.kt @@ -4,6 +4,8 @@ import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.generateKeyPair import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party +import net.corda.core.internal.cert +import net.corda.core.internal.div import net.corda.core.utilities.loggerFor import net.corda.core.utilities.trace import java.nio.file.Files @@ -30,15 +32,20 @@ object ServiceIdentityGenerator { log.trace { "Generating a group identity \"serviceName\" for nodes: ${dirs.joinToString()}" } val keyPairs = (1..dirs.size).map { generateKeyPair() } val notaryKey = CompositeKey.Builder().addKeys(keyPairs.map { it.public }).build(threshold) - // Avoid adding complexity! This class is a hack that needs to stay runnable in the gradle environment. - val privateKeyFile = "$serviceId-private-key" - val publicKeyFile = "$serviceId-public" - val compositeKeyFile = "$serviceId-composite-key" + + val caKeyStore = loadKeyStore(javaClass.classLoader.getResourceAsStream("net/corda/node/internal/certificates/cordadevcakeys.jks"), "cordacadevpass") + val issuer = caKeyStore.getCertificateAndKeyPair(X509Utilities.CORDA_INTERMEDIATE_CA, "cordacadevkeypass") + val rootCert = caKeyStore.getCertificate(X509Utilities.CORDA_ROOT_CA) + keyPairs.zip(dirs) { keyPair, dir -> - Files.createDirectories(dir) - Files.write(dir.resolve(compositeKeyFile), notaryKey.encoded) - Files.write(dir.resolve(privateKeyFile), keyPair.private.encoded) - Files.write(dir.resolve(publicKeyFile), keyPair.public.encoded) + val serviceKeyCert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, issuer.certificate, issuer.keyPair, serviceName, keyPair.public) + val compositeKeyCert = X509Utilities.createCertificate(CertificateType.CLIENT_CA, issuer.certificate, issuer.keyPair, serviceName, notaryKey) + val certPath = Files.createDirectories(dir / "certificates") / "distributedService.jks" + + val keystore = loadOrCreateKeyStore(certPath, "cordacadevpass") + keystore.setCertificateEntry("$serviceId-composite-key", compositeKeyCert.cert) + keystore.setKeyEntry("$serviceId-private-key", keyPair.private, "cordacadevkeypass".toCharArray(), arrayOf(serviceKeyCert.cert, issuer.certificate.cert, rootCert)) + keystore.save(certPath, "cordacadevpass") } return Party(serviceName, notaryKey) } diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index 72b9edfa9c..a383eb3396 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -31,10 +31,10 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.checkpoints import net.corda.node.services.transactions.ValidatingNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.* import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyState @@ -85,7 +85,7 @@ class FlowFrameworkTests { // We intentionally create our own notary and ignore the one provided by the network val notaryKeyPair = generateKeyPair() - val notaryService = ServiceInfo(ValidatingNotaryService.type, CordaX500Name(organisation = "Notary service 2000", locality = "London", country = "GB")) + val notaryService = ServiceInfo(ValidatingNotaryService.type, CordaX500Name(commonName = ValidatingNotaryService.type.id, organisation = "Notary service 2000", locality = "London", country = "GB")) val overrideServices = mapOf(Pair(notaryService, notaryKeyPair)) // Note that these notaries don't operate correctly as they don't share their state. They are only used for testing // service addressing. diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index 250d29f957..e9522358e1 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -729,7 +729,7 @@ class DriverDSL( val nodeNames = (0 until clusterSize).map { CordaX500Name(organisation = "Notary Service $it", locality = "Zurich", country = "CH") } val paths = nodeNames.map { baseDirectory(it) } ServiceIdentityGenerator.generateToDisk(paths, type.id, notaryName) - val advertisedServices = setOf(ServiceInfo(type)) + val advertisedServices = setOf(ServiceInfo(type, notaryName)) val notaryClusterAddress = portAllocation.nextHostAndPort() // Start the first node that will bootstrap the cluster diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt index 6d99d28d19..7223814c7a 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt @@ -136,20 +136,19 @@ abstract class NodeBasedTest : TestDependencyInjectionBase() { serviceType.id, notaryName) + val serviceInfo = ServiceInfo(serviceType, notaryName) val nodeAddresses = getFreeLocalPorts("localhost", clusterSize).map { it.toString() } - val masterNode = CordaX500Name(organisation = "${notaryName.organisation}-0", locality = notaryName.locality, country = notaryName.country) val masterNodeFuture = startNode( - masterNode, - advertisedServices = setOf(ServiceInfo(serviceType, masterNode.copy(commonName = serviceType.id))), + CordaX500Name(organisation = "${notaryName.organisation}-0", locality = notaryName.locality, country = notaryName.country), + advertisedServices = setOf(serviceInfo), configOverrides = mapOf("notaryNodeAddress" to nodeAddresses[0], "database" to mapOf("serverNameTablePrefix" to if (clusterSize > 1) "${notaryName.organisation}0".replace(Regex("[^0-9A-Za-z]+"), "") else ""))) val remainingNodesFutures = (1 until clusterSize).map { - val nodeName = CordaX500Name(organisation = "${notaryName.organisation}-$it", locality = notaryName.locality, country = notaryName.country) startNode( - nodeName, - advertisedServices = setOf(ServiceInfo(serviceType, nodeName.copy(commonName = serviceType.id))), + CordaX500Name(organisation = "${notaryName.organisation}-$it", locality = notaryName.locality, country = notaryName.country), + advertisedServices = setOf(serviceInfo), configOverrides = mapOf( "notaryNodeAddress" to nodeAddresses[it], "notaryClusterAddresses" to listOf(nodeAddresses[0]), From 002c6c46876c5ac5c3732e0406bf8edc4b1586f7 Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Wed, 20 Sep 2017 17:47:45 +0100 Subject: [PATCH 018/230] Remove notaryIdentityKey from ServiceHub (#1541) * Remove notaryIdentityKey from ServiceHub It was redundant, as we have notary field on a transaction. Notaries can use this field to check if the transaction was meant for them and then use that information while choosing a key to sign a transaction. * Move notaryIdentityKey to NotaryService * Address comments * Fixes after rebase --- .../kotlin/net/corda/core/flows/NotaryFlow.kt | 17 +++++++++++--- .../kotlin/net/corda/core/node/ServiceHub.kt | 14 ----------- .../corda/core/node/services/NotaryService.kt | 8 ++++--- .../net/corda/docs/CustomNotaryTutorial.kt | 8 ++++--- .../net/corda/node/internal/AbstractNode.kt | 23 ++++++++++++------- .../BFTNonValidatingNotaryService.kt | 18 ++++++++++----- .../node/services/transactions/BFTSMaRt.kt | 6 +++-- .../transactions/NonValidatingNotaryFlow.kt | 5 ++-- .../RaftNonValidatingNotaryService.kt | 3 ++- .../RaftValidatingNotaryService.kt | 3 ++- .../transactions/SimpleNotaryService.kt | 3 ++- .../transactions/ValidatingNotaryFlow.kt | 6 +++-- .../transactions/ValidatingNotaryService.kt | 3 ++- .../node/messaging/TwoPartyTradeFlowTests.kt | 3 ++- .../transactions/NotaryServiceTests.kt | 2 +- .../ValidatingNotaryServiceTests.kt | 2 +- .../node/testing/MockServiceHubInternal.kt | 2 -- .../kotlin/net/corda/testing/node/MockNode.kt | 6 ++--- .../net/corda/testing/node/MockServices.kt | 1 - 19 files changed, 76 insertions(+), 57 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt index 27d05add24..e2a2ba1f62 100644 --- a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt @@ -13,6 +13,7 @@ import net.corda.core.node.services.NotaryService import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.node.services.UniquenessProvider import net.corda.core.serialization.CordaSerializable +import net.corda.core.transactions.FilteredTransaction import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.UntrustworthyData @@ -71,7 +72,7 @@ class NotaryFlow { val tx: Any = if (stx.isNotaryChangeTransaction()) { stx.notaryChangeTx } else { - stx.buildFilteredTransaction(Predicate { it is StateRef || it is TimeWindow }) + stx.buildFilteredTransaction(Predicate { it is StateRef || it is TimeWindow || it == notaryParty }) } sendAndReceiveWithRetry(notaryParty, tx) } @@ -118,7 +119,8 @@ class NotaryFlow { @Suspendable override fun call(): Void? { - val (id, inputs, timeWindow) = receiveAndVerifyTx() + val (id, inputs, timeWindow, notary) = receiveAndVerifyTx() + checkNotary(notary) service.validateTimeWindow(timeWindow) service.commitInputStates(inputs, id, otherSide) signAndSendResponse(id) @@ -132,6 +134,13 @@ class NotaryFlow { @Suspendable abstract fun receiveAndVerifyTx(): TransactionParts + // Check if transaction is intended to be signed by this notary. + @Suspendable + protected fun checkNotary(notary: Party?) { + if (notary !in serviceHub.myInfo.legalIdentities) + throw NotaryException(NotaryError.WrongNotary) + } + @Suspendable private fun signAndSendResponse(txId: SecureHash) { val signature = service.sign(txId) @@ -144,7 +153,7 @@ class NotaryFlow { * The minimum amount of information needed to notarise a transaction. Note that this does not include * any sensitive transaction details. */ -data class TransactionParts(val id: SecureHash, val inputs: List, val timestamp: TimeWindow?) +data class TransactionParts(val id: SecureHash, val inputs: List, val timestamp: TimeWindow?, val notary: Party?) class NotaryException(val error: NotaryError) : FlowException("Error response from Notary - $error") @@ -160,4 +169,6 @@ sealed class NotaryError { data class TransactionInvalid(val cause: Throwable) : NotaryError() { override fun toString() = cause.toString() } + + object WrongNotary: NotaryError() } diff --git a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt index d5688c1fdf..725e7ce44a 100644 --- a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt @@ -133,20 +133,6 @@ interface ServiceHub : ServicesForResolution { private val legalIdentityKey: PublicKey get() = this.myInfo.legalIdentitiesAndCerts.first().owningKey - /** - * Helper property to shorten code for fetching the the [PublicKey] portion of the - * Node's Notary signing identity. It is required that the Node hosts a notary service, - * otherwise an [IllegalArgumentException] will be thrown. - * Typical use is during signing in flows and for unit test signing. - * When this [PublicKey] is passed into the signing methods below, or on the KeyManagementService - * the matching [java.security.PrivateKey] will be looked up internally and used to sign. - * If the key is actually a [net.corda.core.crypto.CompositeKey], the first leaf key hosted on this node - * will be used to create the signature. - */ - // TODO Remove that from ServiceHub, we could take that information from a transaction notary field and figure out what key to use from that. - // But, it's separate PR. - val notaryIdentityKey: PublicKey - // Helper method to construct an initial partially signed transaction from a [TransactionBuilder]. private fun signInitialTransaction(builder: TransactionBuilder, publicKey: PublicKey, signatureMetadata: SignatureMetadata): SignedTransaction { return builder.toSignedTransaction(keyManagementService, publicKey, signatureMetadata) diff --git a/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt b/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt index 03b6803124..c5a4b6449e 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt @@ -13,9 +13,11 @@ import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.serialize import net.corda.core.utilities.loggerFor import org.slf4j.Logger +import java.security.PublicKey abstract class NotaryService : SingletonSerializeAsToken() { abstract val services: ServiceHub + abstract val notaryIdentityKey: PublicKey abstract fun start() abstract fun stop() @@ -70,11 +72,11 @@ abstract class TrustedAuthorityNotaryService : NotaryService() { } fun sign(bits: ByteArray): DigitalSignature.WithKey { - return services.keyManagementService.sign(bits, services.notaryIdentityKey) + return services.keyManagementService.sign(bits, notaryIdentityKey) } fun sign(txId: SecureHash): TransactionSignature { - val signableData = SignableData(txId, SignatureMetadata(services.myInfo.platformVersion, Crypto.findSignatureScheme(services.notaryIdentityKey).schemeNumberID)) - return services.keyManagementService.sign(signableData, services.notaryIdentityKey) + val signableData = SignableData(txId, SignatureMetadata(services.myInfo.platformVersion, Crypto.findSignatureScheme(notaryIdentityKey).schemeNumberID)) + return services.keyManagementService.sign(signableData, notaryIdentityKey) } } \ No newline at end of file diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt index 5b46131e95..170b945d10 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt @@ -10,11 +10,12 @@ import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.transactions.SignedTransaction import net.corda.node.services.transactions.PersistentUniquenessProvider +import java.security.PublicKey import java.security.SignatureException // START 1 @CordaService -class MyCustomValidatingNotaryService(override val services: ServiceHub) : TrustedAuthorityNotaryService() { +class MyCustomValidatingNotaryService(override val services: ServiceHub, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { override val timeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider = PersistentUniquenessProvider() @@ -35,9 +36,10 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary override fun receiveAndVerifyTx(): TransactionParts { try { val stx = subFlow(ReceiveTransactionFlow(otherSide, checkSufficientSignatures = false)) + checkNotary(stx.notary) checkSignatures(stx) val wtx = stx.tx - return TransactionParts(wtx.id, wtx.inputs, wtx.timeWindow) + return TransactionParts(wtx.id, wtx.inputs, wtx.timeWindow, wtx.notary) } catch (e: Exception) { throw when (e) { is TransactionVerificationException, @@ -49,7 +51,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary private fun checkSignatures(stx: SignedTransaction) { try { - stx.verifySignaturesExcept(serviceHub.notaryIdentityKey) + stx.verifySignaturesExcept(service.notaryIdentityKey) } catch (e: SignatureException) { throw NotaryException(NotaryError.TransactionInvalid(e)) } diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index b4fbfcb6c5..4588efa7ed 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -255,9 +255,16 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, */ fun installCordaService(serviceClass: Class): T { serviceClass.requireAnnotation() - val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true } val service = try { - constructor.newInstance(services) + if (NotaryService::class.java.isAssignableFrom(serviceClass)) { + check(myNotaryIdentity != null) { "Trying to install a notary service but no notary identity specified" } + val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java, PublicKey::class.java).apply { isAccessible = true } + constructor.newInstance(services, myNotaryIdentity!!.owningKey) + } + else { + val constructor = serviceClass.getDeclaredConstructor(ServiceHub::class.java).apply { isAccessible = true } + constructor.newInstance(services) + } } catch (e: InvocationTargetException) { throw ServiceInstantiationException(e.cause) } @@ -576,12 +583,13 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, } open protected fun makeCoreNotaryService(type: ServiceType): NotaryService? { + check(myNotaryIdentity != null) { "No notary identity initialized when creating a notary service" } return when (type) { - SimpleNotaryService.type -> SimpleNotaryService(services) - ValidatingNotaryService.type -> ValidatingNotaryService(services) - RaftNonValidatingNotaryService.type -> RaftNonValidatingNotaryService(services) - RaftValidatingNotaryService.type -> RaftValidatingNotaryService(services) - BFTNonValidatingNotaryService.type -> BFTNonValidatingNotaryService(services) + SimpleNotaryService.type -> SimpleNotaryService(services, myNotaryIdentity!!.owningKey) + ValidatingNotaryService.type -> ValidatingNotaryService(services, myNotaryIdentity!!.owningKey) + RaftNonValidatingNotaryService.type -> RaftNonValidatingNotaryService(services, myNotaryIdentity!!.owningKey) + RaftValidatingNotaryService.type -> RaftValidatingNotaryService(services, myNotaryIdentity!!.owningKey) + BFTNonValidatingNotaryService.type -> BFTNonValidatingNotaryService(services, myNotaryIdentity!!.owningKey) else -> null } } @@ -713,7 +721,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, override val myInfo: NodeInfo get() = info override val database: CordaPersistence get() = this@AbstractNode.database override val configuration: NodeConfiguration get() = this@AbstractNode.configuration - override val notaryIdentityKey: PublicKey get() = myNotaryIdentity?.owningKey ?: throw IllegalArgumentException("Node doesn't have notary identity key") override fun cordaService(type: Class): T { require(type.isAnnotationPresent(CordaService::class.java)) { "${type.name} is not a Corda service" } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt index 26970dec91..bf98b2ff3a 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt @@ -6,6 +6,7 @@ import net.corda.core.contracts.StateRef import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic +import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryException import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party @@ -20,6 +21,7 @@ import net.corda.core.utilities.* import net.corda.node.services.api.ServiceHubInternal import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.NODE_DATABASE_PREFIX +import java.security.PublicKey import javax.persistence.Entity import kotlin.concurrent.thread @@ -28,7 +30,9 @@ import kotlin.concurrent.thread * * A transaction is notarised when the consensus is reached by the cluster on its uniqueness, and time-window validity. */ -class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, cluster: BFTSMaRt.Cluster = distributedCluster) : NotaryService() { +class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, + override val notaryIdentityKey: PublicKey, + cluster: BFTSMaRt.Cluster = distributedCluster) : NotaryService() { companion object { val type = SimpleNotaryService.type.getSubType("bft") private val log = loggerFor() @@ -51,7 +55,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c thread(name = "BFT SMaRt replica $replicaId init", isDaemon = true) { configHandle.use { val timeWindowChecker = TimeWindowChecker(services.clock) - val replica = Replica(it, replicaId, { createMap() }, services, timeWindowChecker) + val replica = Replica(it, replicaId, { createMap() }, services, notaryIdentityKey, timeWindowChecker) replicaHolder.set(replica) log.info("BFT SMaRt replica $replicaId is running.") } @@ -100,8 +104,8 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c toPersistentEntityKey = { PersistentStateRef(it.txhash.toString(), it.index) }, fromPersistentEntity = { //TODO null check will become obsolete after making DB/JPA columns not nullable - var txId = it.id.txId ?: throw IllegalStateException("DB returned null SecureHash transactionId") - var index = it.id.index ?: throw IllegalStateException("DB returned null SecureHash index") + val txId = it.id.txId ?: throw IllegalStateException("DB returned null SecureHash transactionId") + val index = it.id.index ?: throw IllegalStateException("DB returned null SecureHash index") Pair(StateRef(txhash = SecureHash.parse(txId), index = index), UniquenessProvider.ConsumingTx( id = SecureHash.parse(it.consumingTxHash), @@ -126,7 +130,8 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c replicaId: Int, createMap: () -> AppendOnlyPersistentMap, services: ServiceHubInternal, - timeWindowChecker: TimeWindowChecker) : BFTSMaRt.Replica(config, replicaId, createMap, services, timeWindowChecker) { + notaryIdentityKey: PublicKey, + timeWindowChecker: TimeWindowChecker) : BFTSMaRt.Replica(config, replicaId, createMap, services, notaryIdentityKey, timeWindowChecker) { override fun executeCommand(command: ByteArray): ByteArray { val request = command.deserialize() @@ -139,8 +144,9 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, c return try { val id = ftx.id val inputs = ftx.inputs - + val notary = ftx.notary validateTimeWindow(ftx.timeWindow) + if (notary !in services.myInfo.legalIdentities) throw NotaryException(NotaryError.WrongNotary) commitInputStates(inputs, id, callerIdentity) log.debug { "Inputs committed successfully, signing $id" } BFTSMaRt.ReplicaResponse.Signature(sign(ftx)) diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRt.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRt.kt index 072a07bd04..c85eb7d4da 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRt.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTSMaRt.kt @@ -36,6 +36,7 @@ import net.corda.node.services.transactions.BFTSMaRt.Client import net.corda.node.services.transactions.BFTSMaRt.Replica import net.corda.node.utilities.AppendOnlyPersistentMap import java.nio.file.Path +import java.security.PublicKey import java.util.* /** @@ -176,6 +177,7 @@ object BFTSMaRt { createMap: () -> AppendOnlyPersistentMap, protected val services: ServiceHubInternal, + protected val notaryIdentityKey: PublicKey, private val timeWindowChecker: TimeWindowChecker) : DefaultRecoverable() { companion object { private val log = loggerFor() @@ -248,11 +250,11 @@ object BFTSMaRt { } protected fun sign(bytes: ByteArray): DigitalSignature.WithKey { - return services.database.transaction { services.keyManagementService.sign(bytes, services.notaryIdentityKey) } + return services.database.transaction { services.keyManagementService.sign(bytes, notaryIdentityKey) } } protected fun sign(filteredTransaction: FilteredTransaction): TransactionSignature { - return services.database.transaction { services.createSignature(filteredTransaction, services.notaryIdentityKey) } + return services.database.transaction { services.createSignature(filteredTransaction, notaryIdentityKey) } } // TODO: diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt index 9abef4b38f..6ebf61de1e 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt @@ -27,9 +27,10 @@ class NonValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryS it.verify() it.checkAllComponentsVisible(ComponentGroupEnum.INPUTS_GROUP) it.checkAllComponentsVisible(ComponentGroupEnum.TIMEWINDOW_GROUP) - TransactionParts(it.id, it.inputs, it.timeWindow) + val notary = it.notary + TransactionParts(it.id, it.inputs, it.timeWindow, notary) } - is NotaryChangeWireTransaction -> TransactionParts(it.id, it.inputs, null) + is NotaryChangeWireTransaction -> TransactionParts(it.id, it.inputs, null, it.notary) else -> { throw IllegalArgumentException("Received unexpected transaction type: ${it::class.java.simpleName}," + "expected either ${FilteredTransaction::class.java.simpleName} or ${NotaryChangeWireTransaction::class.java.simpleName}") diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt index ce2c4289c9..850f8182c8 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt @@ -5,9 +5,10 @@ import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.node.services.api.ServiceHubInternal +import java.security.PublicKey /** A non-validating notary service operated by a group of mutually trusting parties, uses the Raft algorithm to achieve consensus. */ -class RaftNonValidatingNotaryService(override val services: ServiceHubInternal) : TrustedAuthorityNotaryService() { +class RaftNonValidatingNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { companion object { val type = SimpleNotaryService.type.getSubType("raft") } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt index 7267067997..26fbd333b3 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt @@ -5,9 +5,10 @@ import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.node.services.api.ServiceHubInternal +import java.security.PublicKey /** A validating notary service operated by a group of mutually trusting parties, uses the Raft algorithm to achieve consensus. */ -class RaftValidatingNotaryService(override val services: ServiceHubInternal) : TrustedAuthorityNotaryService() { +class RaftValidatingNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { companion object { val type = ValidatingNotaryService.type.getSubType("raft") } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt index 6b5c4ef26f..0df32048b3 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt @@ -6,9 +6,10 @@ import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.nodeapi.ServiceType import net.corda.node.services.api.ServiceHubInternal +import java.security.PublicKey /** A simple Notary service that does not perform transaction validation */ -class SimpleNotaryService(override val services: ServiceHubInternal) : TrustedAuthorityNotaryService() { +class SimpleNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { companion object { val type = ServiceType.notary.getSubType("simple") } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt index 5c968695c4..a7ee9f1228 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt @@ -24,9 +24,11 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ override fun receiveAndVerifyTx(): TransactionParts { try { val stx = subFlow(ReceiveTransactionFlow(otherSide, checkSufficientSignatures = false)) + val notary = stx.notary + checkNotary(notary) checkSignatures(stx) val wtx = stx.tx - return TransactionParts(wtx.id, wtx.inputs, wtx.timeWindow) + return TransactionParts(wtx.id, wtx.inputs, wtx.timeWindow, notary!!) } catch (e: Exception) { throw when (e) { is TransactionVerificationException, @@ -38,7 +40,7 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ private fun checkSignatures(stx: SignedTransaction) { try { - stx.verifySignaturesExcept(serviceHub.notaryIdentityKey) + stx.verifySignaturesExcept(service.notaryIdentityKey) } catch(e: SignatureException) { throw NotaryException(NotaryError.TransactionInvalid(e)) } diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt index bdb72bb3ef..76a0c83674 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt @@ -6,9 +6,10 @@ import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.nodeapi.ServiceType import net.corda.node.services.api.ServiceHubInternal +import java.security.PublicKey /** A Notary service that validates the transaction chain of the submitted transaction before committing it */ -class ValidatingNotaryService(override val services: ServiceHubInternal) : TrustedAuthorityNotaryService() { +class ValidatingNotaryService(override val services: ServiceHubInternal, override val notaryIdentityKey: PublicKey) : TrustedAuthorityNotaryService() { companion object { val type = ServiceType.notary.getSubType("validating") } diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index fd05f8e9f7..55afe46acb 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -646,7 +646,8 @@ class TwoPartyTradeFlowTests { val sigs = mutableListOf() val nodeKey = node.info.chooseIdentity().owningKey sigs.add(node.services.keyManagementService.sign(SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(nodeKey).schemeNumberID)), nodeKey)) - sigs.add(notaryNode.services.keyManagementService.sign(SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(notaryNode.services.notaryIdentityKey).schemeNumberID)), notaryNode.services.notaryIdentityKey)) + sigs.add(notaryNode.services.keyManagementService.sign(SignableData(id, SignatureMetadata(1, + Crypto.findSignatureScheme(notaryNode.info.legalIdentities[1].owningKey).schemeNumberID)), notaryNode.info.legalIdentities[1].owningKey)) extraSigningNodes.forEach { currentNode -> sigs.add(currentNode.services.keyManagementService.sign( SignableData(id, SignatureMetadata(1, Crypto.findSignatureScheme(currentNode.info.chooseIdentity().owningKey).schemeNumberID)), diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt index 2f021beacd..6b4fdb6899 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt @@ -161,7 +161,7 @@ class NotaryServiceTests { fun issueState(node: StartedNode<*>): StateAndRef<*> { val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0)) val signedByNode = node.services.signInitialTransaction(tx) - val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) + val stx = notaryNode.services.addSignature(signedByNode, notary.owningKey) node.services.recordTransactions(stx) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) } diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt index 1a29ad0811..2bdd835486 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt @@ -104,7 +104,7 @@ class ValidatingNotaryServiceTests { fun issueState(node: StartedNode<*>): StateAndRef<*> { val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.chooseIdentity().ref(0)) val signedByNode = node.services.signInitialTransaction(tx) - val stx = notaryNode.services.addSignature(signedByNode, notaryNode.services.notaryIdentityKey) + val stx = notaryNode.services.addSignature(signedByNode, notary.owningKey) node.services.recordTransactions(stx) return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0)) } diff --git a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt index ce5db3b6ad..93d60bcf25 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/node/testing/MockServiceHubInternal.kt @@ -68,8 +68,6 @@ open class MockServiceHubInternal( get() = overrideClock ?: throw UnsupportedOperationException() override val myInfo: NodeInfo get() = NodeInfo(listOf(MOCK_HOST_AND_PORT), listOf(DUMMY_IDENTITY_1), 1, serial = 1L) // Required to get a dummy platformVersion when required for tests. - override val notaryIdentityKey: PublicKey - get() = throw IllegalStateException("No notary identity in MockServiceHubInternal") override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) override val rpcFlows: List>> get() = throw UnsupportedOperationException() diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index d5887474f0..dfffb71f61 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -257,11 +257,9 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, override fun makeCoreNotaryService(type: ServiceType): NotaryService? { if (type != BFTNonValidatingNotaryService.type) return super.makeCoreNotaryService(type) - return BFTNonValidatingNotaryService(services, object : BFTSMaRt.Cluster { + return BFTNonValidatingNotaryService(services, myNotaryIdentity!!.owningKey, object : BFTSMaRt.Cluster { override fun waitUntilAllReplicasHaveInitialized() { - val clusterNodes = mockNet.nodes.filter { - services.notaryIdentityKey in it.info.legalIdentitiesAndCerts.map { it.owningKey } - } + val clusterNodes = mockNet.nodes.filter { myNotaryIdentity!!.owningKey in it.started!!.info.legalIdentities.map { it.owningKey } } if (clusterNodes.size != configuration.notaryClusterAddresses.size) { throw IllegalStateException("Unable to enumerate all nodes in BFT cluster.") } diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt index 1d23868243..bb2ccf5c05 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt @@ -156,7 +156,6 @@ open class MockServices(vararg val keys: KeyPair) : ServiceHub { val identity = getTestPartyAndCertificate(MEGA_CORP.name, key.public) return NodeInfo(emptyList(), listOf(identity), 1, serial = 1L) } - override val notaryIdentityKey: PublicKey get() = throw UnsupportedOperationException() override val transactionVerifierService: TransactionVerifierService get() = InMemoryTransactionVerifierService(2) lateinit var hibernatePersister: HibernateObserver From c93b0284ef950dd17a7dd19e171d4659c5273985 Mon Sep 17 00:00:00 2001 From: Katelyn Baker Date: Thu, 21 Sep 2017 09:05:32 +0100 Subject: [PATCH 019/230] CORDA-593 - Strip web front end from the SIMM demo (#1574) * CORDA-593 - Strip web front end from simm-demo Also, pre cutting V1 remove the documentation references to SIMM, the plan being once V1 is cut we can spend a little time thinking about how we want to prevent the SIMM back end as a useful, teachable, demo * CORDA-593 Fix the integration tests --- docs/source/changelog.rst | 6 + docs/source/cordapp-overview.rst | 11 +- docs/source/running-the-demos.rst | 86 +- samples/simm-valuation-demo/README.md | 4 - samples/simm-valuation-demo/build.gradle | 37 - .../net/corda/vega/plugin/SimmPlugin.kt | 4 +- .../resources/simmvaluationweb/.npmignore | 0 .../vega/bank-c/portfolio/history/aggregated | 501 - .../api/vega/bank-c/portfolio/valuations | 3 - .../simmvaluationweb/api/vega/bank-c/trades | 251 - .../simmvaluationweb/api/vega/business-date | 3 - .../vega/intesa/portfolio/history/aggregated | 1000 - .../api/vega/intesa/portfolio/valuations | 90 - .../simmvaluationweb/api/vega/intesa/trades | 251 - .../simmvaluationweb/api/vega/whoami | 14 - .../resources/simmvaluationweb/app/Deal.js | 101 - .../simmvaluationweb/app/Deal.js.map | 1 - .../simmvaluationweb/app/app.component.css | 37 - .../simmvaluationweb/app/app.component.html | 50 - .../simmvaluationweb/app/app.component.js | 73 - .../simmvaluationweb/app/app.component.js.map | 1 - .../app/app.component.spec.js | 13 - .../app/app.component.spec.js.map | 1 - .../simmvaluationweb/app/app.routes.js | 17 - .../simmvaluationweb/app/app.routes.js.map | 1 - .../create-trade/create-trade.component.css | 19 - .../create-trade/create-trade.component.html | 53 - .../create-trade/create-trade.component.js | 67 - .../create-trade.component.js.map | 1 - .../create-trade.component.spec.js | 9 - .../create-trade.component.spec.js.map | 1 - .../app/create-trade/index.js | 6 - .../app/create-trade/index.js.map | 1 - .../app/create-trade/shared/index.js | 1 - .../app/create-trade/shared/index.js.map | 1 - .../simmvaluationweb/app/environment.js | 6 - .../simmvaluationweb/app/environment.js.map | 1 - .../app/http-wrapper.service.js | 115 - .../app/http-wrapper.service.js.map | 1 - .../app/http-wrapper.service.spec.js | 13 - .../app/http-wrapper.service.spec.js.map | 1 - .../resources/simmvaluationweb/app/index.js | 7 - .../simmvaluationweb/app/index.js.map | 1 - .../simmvaluationweb/app/irs.service.js | 43 - .../simmvaluationweb/app/irs.service.js.map | 1 - .../simmvaluationweb/app/irs.service.spec.js | 13 - .../app/irs.service.spec.js.map | 1 - .../simmvaluationweb/app/model/CommonModel.js | 31 - .../app/model/CommonModel.js.map | 1 - .../app/model/FixedLegModel.js | 23 - .../app/model/FixedLegModel.js.map | 1 - .../app/model/FloatingLegModel.js | 34 - .../app/model/FloatingLegModel.js.map | 1 - .../simmvaluationweb/app/node.service.js | 51 - .../simmvaluationweb/app/node.service.js.map | 1 - .../simmvaluationweb/app/node.service.spec.js | 13 - .../app/node.service.spec.js.map | 1 - .../simmvaluationweb/app/portfolio/index.js | 6 - .../app/portfolio/index.js.map | 1 - .../app/portfolio/portfolio.component.css | 1 - .../app/portfolio/portfolio.component.html | 95 - .../app/portfolio/portfolio.component.js | 466 - .../app/portfolio/portfolio.component.js.map | 1 - .../app/portfolio/portfolio.component.spec.js | 3 - .../portfolio/portfolio.component.spec.js.map | 1 - .../simmvaluationweb/app/shared/index.js | 1 - .../simmvaluationweb/app/shared/index.js.map | 1 - .../simmvaluationweb/app/valuations/index.js | 6 - .../app/valuations/index.js.map | 1 - .../app/valuations/valuations.component.css | 17 - .../app/valuations/valuations.component.html | 336 - .../app/valuations/valuations.component.js | 101 - .../valuations/valuations.component.js.map | 1 - .../valuations/valuations.component.spec.js | 7 - .../valuations.component.spec.js.map | 1 - .../simmvaluationweb/app/view-trade/index.js | 6 - .../app/view-trade/index.js.map | 1 - .../app/view-trade/shared/index.js | 1 - .../app/view-trade/shared/index.js.map | 1 - .../app/view-trade/view-trade.component.css | 0 .../app/view-trade/view-trade.component.html | 206 - .../app/view-trade/view-trade.component.js | 66 - .../view-trade/view-trade.component.js.map | 1 - .../view-trade/view-trade.component.spec.js | 9 - .../view-trade.component.spec.js.map | 1 - .../app/viewmodel/CommonViewModel.js | 39 - .../app/viewmodel/CommonViewModel.js.map | 1 - .../app/viewmodel/DealViewModel.js | 14 - .../app/viewmodel/DealViewModel.js.map | 1 - .../app/viewmodel/FixedLegViewModel.js | 20 - .../app/viewmodel/FixedLegViewModel.js.map | 1 - .../app/viewmodel/FloatingLegViewModel.js | 28 - .../app/viewmodel/FloatingLegViewModel.js.map | 1 - .../assets/images/checkbox.png | Bin 16080 -> 0 bytes .../assets/images/opengamma-logo.png | Bin 49212 -> 0 bytes .../simmvaluationweb/assets/images/r3logo.png | Bin 2310 -> 0 bytes .../resources/simmvaluationweb/favicon.ico | Bin 5430 -> 0 bytes .../resources/simmvaluationweb/index.html | 47 - .../simmvaluationweb/libs/highstock.js | 7553 -------- .../simmvaluationweb/libs/jquery.min.js | 1636 -- .../simmvaluationweb/libs/spinners.css | 51 - .../main/resources/simmvaluationweb/main.js | 19 - .../resources/simmvaluationweb/main.js.map | 1 - .../simmvaluationweb/system-config.js | 85 - .../simmvaluationweb/system-config.js.map | 1 - .../@angular/common/bundles/common.umd.js | 4773 ----- .../@angular/common/bundles/common.umd.min.js | 4 - .../vendor/@angular/common/esm/index.js | 14 - .../vendor/@angular/common/esm/index.js.map | 1 - .../common/esm/src/common_directives.js | 56 - .../common/esm/src/common_directives.js.map | 1 - .../@angular/common/esm/src/directives.js | 21 - .../@angular/common/esm/src/directives.js.map | 1 - .../esm/src/directives/core_directives.js | 69 - .../esm/src/directives/core_directives.js.map | 1 - .../common/esm/src/directives/ng_class.js | 119 - .../common/esm/src/directives/ng_class.js.map | 1 - .../common/esm/src/directives/ng_for.js | 126 - .../common/esm/src/directives/ng_for.js.map | 1 - .../common/esm/src/directives/ng_if.js | 36 - .../common/esm/src/directives/ng_if.js.map | 1 - .../common/esm/src/directives/ng_plural.js | 76 - .../esm/src/directives/ng_plural.js.map | 1 - .../common/esm/src/directives/ng_style.js | 49 - .../common/esm/src/directives/ng_style.js.map | 1 - .../common/esm/src/directives/ng_switch.js | 154 - .../esm/src/directives/ng_switch.js.map | 1 - .../esm/src/directives/ng_template_outlet.js | 50 - .../src/directives/ng_template_outlet.js.map | 1 - .../@angular/common/esm/src/facade/async.js | 144 - .../common/esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../common/esm/src/facade/collection.js | 350 - .../common/esm/src/facade/collection.js.map | 1 - .../esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../common/esm/src/facade/exceptions.js | 49 - .../common/esm/src/facade/exceptions.js.map | 1 - .../@angular/common/esm/src/facade/intl.js | 179 - .../common/esm/src/facade/intl.js.map | 1 - .../@angular/common/esm/src/facade/lang.js | 375 - .../common/esm/src/facade/lang.js.map | 1 - .../@angular/common/esm/src/facade/promise.js | 47 - .../common/esm/src/facade/promise.js.map | 1 - .../common/esm/src/forms-deprecated.js | 41 - .../common/esm/src/forms-deprecated.js.map | 1 - .../esm/src/forms-deprecated/directives.js | 75 - .../src/forms-deprecated/directives.js.map | 1 - .../directives/abstract_control_directive.js | 30 - .../abstract_control_directive.js.map | 1 - .../directives/checkbox_value_accessor.js | 41 - .../directives/checkbox_value_accessor.js.map | 1 - .../directives/control_container.js | 26 - .../directives/control_container.js.map | 1 - .../directives/control_value_accessor.js | 17 - .../directives/control_value_accessor.js.map | 1 - .../directives/default_value_accessor.js | 47 - .../directives/default_value_accessor.js.map | 1 - .../directives/form_interface.js | 8 - .../directives/form_interface.js.map | 1 - .../forms-deprecated/directives/ng_control.js | 27 - .../directives/ng_control.js.map | 1 - .../directives/ng_control_group.js | 56 - .../directives/ng_control_group.js.map | 1 - .../directives/ng_control_name.js | 71 - .../directives/ng_control_name.js.map | 1 - .../directives/ng_control_status.js | 52 - .../directives/ng_control_status.js.map | 1 - .../forms-deprecated/directives/ng_form.js | 115 - .../directives/ng_form.js.map | 1 - .../directives/ng_form_control.js | 68 - .../directives/ng_form_control.js.map | 1 - .../directives/ng_form_model.js | 114 - .../directives/ng_form_model.js.map | 1 - .../forms-deprecated/directives/ng_model.js | 70 - .../directives/ng_model.js.map | 1 - .../directives/normalize_validator.js | 24 - .../directives/normalize_validator.js.map | 1 - .../directives/number_value_accessor.js | 48 - .../directives/number_value_accessor.js.map | 1 - .../radio_control_value_accessor.js | 110 - .../radio_control_value_accessor.js.map | 1 - .../select_control_value_accessor.js | 125 - .../select_control_value_accessor.js.map | 1 - .../select_multiple_control_value_accessor.js | 162 - ...ect_multiple_control_value_accessor.js.map | 1 - .../src/forms-deprecated/directives/shared.js | 102 - .../forms-deprecated/directives/shared.js.map | 1 - .../forms-deprecated/directives/validators.js | 106 - .../directives/validators.js.map | 1 - .../esm/src/forms-deprecated/form_builder.js | 69 - .../src/forms-deprecated/form_builder.js.map | 1 - .../common/esm/src/forms-deprecated/model.js | 435 - .../esm/src/forms-deprecated/model.js.map | 1 - .../esm/src/forms-deprecated/validators.js | 143 - .../src/forms-deprecated/validators.js.map | 1 - .../@angular/common/esm/src/localization.js | 24 - .../common/esm/src/localization.js.map | 1 - .../@angular/common/esm/src/location.js | 13 - .../@angular/common/esm/src/location.js.map | 1 - .../src/location/hash_location_strategy.js | 68 - .../location/hash_location_strategy.js.map | 1 - .../common/esm/src/location/location.js | 147 - .../common/esm/src/location/location.js.map | 1 - .../esm/src/location/location_strategy.js | 60 - .../esm/src/location/location_strategy.js.map | 1 - .../src/location/path_location_strategy.js | 60 - .../location/path_location_strategy.js.map | 1 - .../esm/src/location/platform_location.js | 39 - .../esm/src/location/platform_location.js.map | 1 - .../vendor/@angular/common/esm/src/pipes.js | 24 - .../@angular/common/esm/src/pipes.js.map | 1 - .../common/esm/src/pipes/async_pipe.js | 109 - .../common/esm/src/pipes/async_pipe.js.map | 1 - .../common/esm/src/pipes/common_pipes.js | 41 - .../common/esm/src/pipes/common_pipes.js.map | 1 - .../common/esm/src/pipes/date_pipe.js | 58 - .../common/esm/src/pipes/date_pipe.js.map | 1 - .../common/esm/src/pipes/i18n_plural_pipe.js | 35 - .../esm/src/pipes/i18n_plural_pipe.js.map | 1 - .../common/esm/src/pipes/i18n_select_pipe.js | 25 - .../esm/src/pipes/i18n_select_pipe.js.map | 1 - .../pipes/invalid_pipe_argument_exception.js | 15 - .../invalid_pipe_argument_exception.js.map | 1 - .../common/esm/src/pipes/json_pipe.js | 17 - .../common/esm/src/pipes/json_pipe.js.map | 1 - .../common/esm/src/pipes/lowercase_pipe.js | 25 - .../esm/src/pipes/lowercase_pipe.js.map | 1 - .../common/esm/src/pipes/number_pipe.js | 75 - .../common/esm/src/pipes/number_pipe.js.map | 1 - .../common/esm/src/pipes/replace_pipe.js | 48 - .../common/esm/src/pipes/replace_pipe.js.map | 1 - .../common/esm/src/pipes/slice_pipe.js | 30 - .../common/esm/src/pipes/slice_pipe.js.map | 1 - .../common/esm/src/pipes/uppercase_pipe.js | 25 - .../esm/src/pipes/uppercase_pipe.js.map | 1 - .../vendor/@angular/common/esm/testing.js | 9 - .../vendor/@angular/common/esm/testing.js.map | 1 - .../common/esm/testing/location_mock.js | 99 - .../common/esm/testing/location_mock.js.map | 1 - .../vendor/@angular/common/index.js | 19 - .../vendor/@angular/common/index.js.map | 1 - .../@angular/common/src/common_directives.js | 57 - .../common/src/common_directives.js.map | 1 - .../vendor/@angular/common/src/directives.js | 33 - .../@angular/common/src/directives.js.map | 1 - .../common/src/directives/core_directives.js | 70 - .../src/directives/core_directives.js.map | 1 - .../common/src/directives/ng_class.js | 134 - .../common/src/directives/ng_class.js.map | 1 - .../@angular/common/src/directives/ng_for.js | 169 - .../common/src/directives/ng_for.js.map | 1 - .../@angular/common/src/directives/ng_if.js | 43 - .../common/src/directives/ng_if.js.map | 1 - .../common/src/directives/ng_plural.js | 86 - .../common/src/directives/ng_plural.js.map | 1 - .../common/src/directives/ng_style.js | 57 - .../common/src/directives/ng_style.js.map | 1 - .../common/src/directives/ng_switch.js | 175 - .../common/src/directives/ng_switch.js.map | 1 - .../src/directives/ng_template_outlet.js | 61 - .../src/directives/ng_template_outlet.js.map | 1 - .../@angular/common/src/facade/async.js | 167 - .../@angular/common/src/facade/async.js.map | 1 - .../src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../@angular/common/src/facade/collection.js | 375 - .../common/src/facade/collection.js.map | 1 - .../common/src/facade/exception_handler.js | 140 - .../src/facade/exception_handler.js.map | 1 - .../@angular/common/src/facade/exceptions.js | 89 - .../common/src/facade/exceptions.js.map | 1 - .../vendor/@angular/common/src/facade/intl.js | 189 - .../@angular/common/src/facade/intl.js.map | 1 - .../vendor/@angular/common/src/facade/lang.js | 465 - .../@angular/common/src/facade/lang.js.map | 1 - .../@angular/common/src/facade/promise.js | 55 - .../@angular/common/src/facade/promise.js.map | 1 - .../@angular/common/src/forms-deprecated.js | 71 - .../common/src/forms-deprecated.js.map | 1 - .../common/src/forms-deprecated/directives.js | 97 - .../src/forms-deprecated/directives.js.map | 1 - .../directives/abstract_control_directive.js | 71 - .../abstract_control_directive.js.map | 1 - .../directives/checkbox_value_accessor.js | 44 - .../directives/checkbox_value_accessor.js.map | 1 - .../directives/control_container.js | 46 - .../directives/control_container.js.map | 1 - .../directives/control_value_accessor.js | 18 - .../directives/control_value_accessor.js.map | 1 - .../directives/default_value_accessor.js | 50 - .../directives/default_value_accessor.js.map | 1 - .../directives/form_interface.js | 9 - .../directives/form_interface.js.map | 1 - .../forms-deprecated/directives/ng_control.js | 44 - .../directives/ng_control.js.map | 1 - .../directives/ng_control_group.js | 85 - .../directives/ng_control_group.js.map | 1 - .../directives/ng_control_name.js | 100 - .../directives/ng_control_name.js.map | 1 - .../directives/ng_control_status.js | 79 - .../directives/ng_control_status.js.map | 1 - .../forms-deprecated/directives/ng_form.js | 145 - .../directives/ng_form.js.map | 1 - .../directives/ng_form_control.js | 93 - .../directives/ng_form_control.js.map | 1 - .../directives/ng_form_model.js | 136 - .../directives/ng_form_model.js.map | 1 - .../forms-deprecated/directives/ng_model.js | 95 - .../directives/ng_model.js.map | 1 - .../directives/normalize_validator.js | 27 - .../directives/normalize_validator.js.map | 1 - .../directives/number_value_accessor.js | 51 - .../directives/number_value_accessor.js.map | 1 - .../radio_control_value_accessor.js | 119 - .../radio_control_value_accessor.js.map | 1 - .../select_control_value_accessor.js | 140 - .../select_control_value_accessor.js.map | 1 - .../select_multiple_control_value_accessor.js | 181 - ...ect_multiple_control_value_accessor.js.map | 1 - .../src/forms-deprecated/directives/shared.js | 110 - .../forms-deprecated/directives/shared.js.map | 1 - .../forms-deprecated/directives/validators.js | 117 - .../directives/validators.js.map | 1 - .../src/forms-deprecated/form_builder.js | 81 - .../src/forms-deprecated/form_builder.js.map | 1 - .../common/src/forms-deprecated/model.js | 525 - .../common/src/forms-deprecated/model.js.map | 1 - .../common/src/forms-deprecated/validators.js | 148 - .../src/forms-deprecated/validators.js.map | 1 - .../@angular/common/src/localization.js | 30 - .../@angular/common/src/localization.js.map | 1 - .../vendor/@angular/common/src/location.js | 17 - .../@angular/common/src/location.js.map | 1 - .../src/location/hash_location_strategy.js | 78 - .../location/hash_location_strategy.js.map | 1 - .../@angular/common/src/location/location.js | 157 - .../common/src/location/location.js.map | 1 - .../common/src/location/location_strategy.js | 65 - .../src/location/location_strategy.js.map | 1 - .../src/location/path_location_strategy.js | 70 - .../location/path_location_strategy.js.map | 1 - .../common/src/location/platform_location.js | 56 - .../src/location/platform_location.js.map | 1 - .../vendor/@angular/common/src/pipes.js | 38 - .../vendor/@angular/common/src/pipes.js.map | 1 - .../@angular/common/src/pipes/async_pipe.js | 119 - .../common/src/pipes/async_pipe.js.map | 1 - .../@angular/common/src/pipes/common_pipes.js | 47 - .../common/src/pipes/common_pipes.js.map | 1 - .../@angular/common/src/pipes/date_pipe.js | 64 - .../common/src/pipes/date_pipe.js.map | 1 - .../common/src/pipes/i18n_plural_pipe.js | 38 - .../common/src/pipes/i18n_plural_pipe.js.map | 1 - .../common/src/pipes/i18n_select_pipe.js | 30 - .../common/src/pipes/i18n_select_pipe.js.map | 1 - .../pipes/invalid_pipe_argument_exception.js | 24 - .../invalid_pipe_argument_exception.js.map | 1 - .../@angular/common/src/pipes/json_pipe.js | 22 - .../common/src/pipes/json_pipe.js.map | 1 - .../common/src/pipes/lowercase_pipe.js | 30 - .../common/src/pipes/lowercase_pipe.js.map | 1 - .../@angular/common/src/pipes/number_pipe.js | 95 - .../common/src/pipes/number_pipe.js.map | 1 - .../@angular/common/src/pipes/replace_pipe.js | 53 - .../common/src/pipes/replace_pipe.js.map | 1 - .../@angular/common/src/pipes/slice_pipe.js | 36 - .../common/src/pipes/slice_pipe.js.map | 1 - .../common/src/pipes/uppercase_pipe.js | 30 - .../common/src/pipes/uppercase_pipe.js.map | 1 - .../vendor/@angular/common/testing.js | 11 - .../vendor/@angular/common/testing.js.map | 1 - .../@angular/common/testing/location_mock.js | 108 - .../common/testing/location_mock.js.map | 1 - .../@angular/compiler/bundles/compiler.umd.js | 16030 ---------------- .../compiler/bundles/compiler.umd.min.js | 15 - .../vendor/@angular/compiler/compiler.js | 49 - .../vendor/@angular/compiler/compiler.js.map | 1 - .../vendor/@angular/compiler/core_private.js | 73 - .../@angular/compiler/core_private.js.map | 1 - .../vendor/@angular/compiler/esm/compiler.js | 17 - .../@angular/compiler/esm/compiler.js.map | 1 - .../@angular/compiler/esm/core_private.js | 72 - .../@angular/compiler/esm/core_private.js.map | 1 - .../vendor/@angular/compiler/esm/index.js | 9 - .../vendor/@angular/compiler/esm/index.js.map | 1 - .../@angular/compiler/esm/private_export.js | 54 - .../compiler/esm/private_export.js.map | 1 - .../esm/src/animation/animation_ast.js | 107 - .../esm/src/animation/animation_ast.js.map | 1 - .../esm/src/animation/animation_compiler.js | 273 - .../src/animation/animation_compiler.js.map | 1 - .../esm/src/animation/animation_parser.js | 460 - .../esm/src/animation/animation_parser.js.map | 1 - .../esm/src/animation/styles_collection.js | 58 - .../src/animation/styles_collection.js.map | 1 - .../@angular/compiler/esm/src/assertions.js | 45 - .../compiler/esm/src/assertions.js.map | 1 - .../vendor/@angular/compiler/esm/src/chars.js | 78 - .../@angular/compiler/esm/src/chars.js.map | 1 - .../compiler/esm/src/compile_metadata.js | 747 - .../compiler/esm/src/compile_metadata.js.map | 1 - .../@angular/compiler/esm/src/compiler.js | 52 - .../@angular/compiler/esm/src/compiler.js.map | 1 - .../@angular/compiler/esm/src/config.js | 51 - .../@angular/compiler/esm/src/config.js.map | 1 - .../esm/src/directive_lifecycle_reflector.js | 36 - .../src/directive_lifecycle_reflector.js.map | 1 - .../compiler/esm/src/directive_normalizer.js | 237 - .../esm/src/directive_normalizer.js.map | 1 - .../compiler/esm/src/directive_resolver.js | 129 - .../esm/src/directive_resolver.js.map | 1 - .../compiler/esm/src/expression_parser/ast.js | 372 - .../esm/src/expression_parser/ast.js.map | 1 - .../esm/src/expression_parser/lexer.js | 361 - .../esm/src/expression_parser/lexer.js.map | 1 - .../esm/src/expression_parser/parser.js | 647 - .../esm/src/expression_parser/parser.js.map | 1 - .../@angular/compiler/esm/src/facade/async.js | 144 - .../compiler/esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../compiler/esm/src/facade/collection.js | 350 - .../compiler/esm/src/facade/collection.js.map | 1 - .../esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../compiler/esm/src/facade/exceptions.js | 49 - .../compiler/esm/src/facade/exceptions.js.map | 1 - .../@angular/compiler/esm/src/facade/lang.js | 375 - .../compiler/esm/src/facade/lang.js.map | 1 - .../@angular/compiler/esm/src/facade/math.js | 11 - .../compiler/esm/src/facade/math.js.map | 1 - .../compiler/esm/src/facade/promise.js | 47 - .../compiler/esm/src/facade/promise.js.map | 1 - .../@angular/compiler/esm/src/html_ast.js | 76 - .../@angular/compiler/esm/src/html_ast.js.map | 1 - .../@angular/compiler/esm/src/html_lexer.js | 636 - .../compiler/esm/src/html_lexer.js.map | 1 - .../@angular/compiler/esm/src/html_parser.js | 354 - .../compiler/esm/src/html_parser.js.map | 1 - .../@angular/compiler/esm/src/html_tags.js | 377 - .../compiler/esm/src/html_tags.js.map | 1 - .../compiler/esm/src/i18n/expander.js | 93 - .../compiler/esm/src/i18n/expander.js.map | 1 - .../compiler/esm/src/i18n/i18n_html_parser.js | 268 - .../esm/src/i18n/i18n_html_parser.js.map | 1 - .../@angular/compiler/esm/src/i18n/message.js | 31 - .../compiler/esm/src/i18n/message.js.map | 1 - .../esm/src/i18n/message_extractor.js | 161 - .../esm/src/i18n/message_extractor.js.map | 1 - .../@angular/compiler/esm/src/i18n/shared.js | 186 - .../compiler/esm/src/i18n/shared.js.map | 1 - .../compiler/esm/src/i18n/xmb_serializer.js | 97 - .../esm/src/i18n/xmb_serializer.js.map | 1 - .../@angular/compiler/esm/src/identifiers.js | 201 - .../compiler/esm/src/identifiers.js.map | 1 - .../compiler/esm/src/interpolation_config.js | 12 - .../esm/src/interpolation_config.js.map | 1 - .../compiler/esm/src/metadata_resolver.js | 480 - .../compiler/esm/src/metadata_resolver.js.map | 1 - .../compiler/esm/src/offline_compiler.js | 145 - .../compiler/esm/src/offline_compiler.js.map | 1 - .../esm/src/output/abstract_emitter.js | 390 - .../esm/src/output/abstract_emitter.js.map | 1 - .../esm/src/output/abstract_js_emitter.js | 161 - .../esm/src/output/abstract_js_emitter.js.map | 1 - .../compiler/esm/src/output/dart_emitter.js | 373 - .../esm/src/output/dart_emitter.js.map | 1 - .../esm/src/output/interpretive_view.js | 88 - .../esm/src/output/interpretive_view.js.map | 1 - .../compiler/esm/src/output/output_ast.js | 788 - .../compiler/esm/src/output/output_ast.js.map | 1 - .../esm/src/output/output_interpreter.js | 405 - .../esm/src/output/output_interpreter.js.map | 1 - .../compiler/esm/src/output/output_jit.js | 44 - .../compiler/esm/src/output/output_jit.js.map | 1 - .../compiler/esm/src/output/path_util.js | 35 - .../compiler/esm/src/output/path_util.js.map | 1 - .../compiler/esm/src/output/ts_emitter.js | 296 - .../compiler/esm/src/output/ts_emitter.js.map | 1 - .../@angular/compiler/esm/src/parse_util.js | 77 - .../compiler/esm/src/parse_util.js.map | 1 - .../compiler/esm/src/pipe_resolver.js | 41 - .../compiler/esm/src/pipe_resolver.js.map | 1 - .../compiler/esm/src/provider_parser.js | 349 - .../compiler/esm/src/provider_parser.js.map | 1 - .../compiler/esm/src/runtime_compiler.js | 234 - .../compiler/esm/src/runtime_compiler.js.map | 1 - .../src/schema/dom_element_schema_registry.js | 311 - .../schema/dom_element_schema_registry.js.map | 1 - .../esm/src/schema/dom_security_schema.js | 55 - .../esm/src/schema/dom_security_schema.js.map | 1 - .../esm/src/schema/element_schema_registry.js | 10 - .../src/schema/element_schema_registry.js.map | 1 - .../@angular/compiler/esm/src/selector.js | 352 - .../@angular/compiler/esm/src/selector.js.map | 1 - .../@angular/compiler/esm/src/shadow_css.js | 498 - .../compiler/esm/src/shadow_css.js.map | 1 - .../compiler/esm/src/style_compiler.js | 93 - .../compiler/esm/src/style_compiler.js.map | 1 - .../compiler/esm/src/style_url_resolver.js | 42 - .../esm/src/style_url_resolver.js.map | 1 - .../@angular/compiler/esm/src/template_ast.js | 255 - .../compiler/esm/src/template_ast.js.map | 1 - .../compiler/esm/src/template_parser.js | 798 - .../compiler/esm/src/template_parser.js.map | 1 - .../compiler/esm/src/template_preparser.js | 86 - .../esm/src/template_preparser.js.map | 1 - .../@angular/compiler/esm/src/url_resolver.js | 315 - .../compiler/esm/src/url_resolver.js.map | 1 - .../vendor/@angular/compiler/esm/src/util.js | 73 - .../@angular/compiler/esm/src/util.js.map | 1 - .../esm/src/view_compiler/compile_binding.js | 14 - .../src/view_compiler/compile_binding.js.map | 1 - .../esm/src/view_compiler/compile_element.js | 386 - .../src/view_compiler/compile_element.js.map | 1 - .../esm/src/view_compiler/compile_method.js | 67 - .../src/view_compiler/compile_method.js.map | 1 - .../esm/src/view_compiler/compile_pipe.js | 97 - .../esm/src/view_compiler/compile_pipe.js.map | 1 - .../esm/src/view_compiler/compile_query.js | 114 - .../src/view_compiler/compile_query.js.map | 1 - .../esm/src/view_compiler/compile_view.js | 163 - .../esm/src/view_compiler/compile_view.js.map | 1 - .../esm/src/view_compiler/constants.js | 82 - .../esm/src/view_compiler/constants.js.map | 1 - .../esm/src/view_compiler/event_binder.js | 135 - .../esm/src/view_compiler/event_binder.js.map | 1 - .../src/view_compiler/expression_converter.js | 235 - .../view_compiler/expression_converter.js.map | 1 - .../esm/src/view_compiler/lifecycle_binder.js | 64 - .../src/view_compiler/lifecycle_binder.js.map | 1 - .../esm/src/view_compiler/property_binder.js | 213 - .../src/view_compiler/property_binder.js.map | 1 - .../compiler/esm/src/view_compiler/util.js | 90 - .../esm/src/view_compiler/util.js.map | 1 - .../esm/src/view_compiler/view_binder.js | 81 - .../esm/src/view_compiler/view_binder.js.map | 1 - .../esm/src/view_compiler/view_builder.js | 503 - .../esm/src/view_compiler/view_builder.js.map | 1 - .../esm/src/view_compiler/view_compiler.js | 53 - .../src/view_compiler/view_compiler.js.map | 1 - .../compiler/esm/src/view_resolver.js | 54 - .../compiler/esm/src/view_resolver.js.map | 1 - .../vendor/@angular/compiler/esm/src/xhr.js | 16 - .../@angular/compiler/esm/src/xhr.js.map | 1 - .../vendor/@angular/compiler/esm/testing.js | 12 - .../@angular/compiler/esm/testing.js.map | 1 - .../esm/testing/directive_resolver_mock.js | 76 - .../testing/directive_resolver_mock.js.map | 1 - .../esm/testing/schema_registry_mock.js | 27 - .../esm/testing/schema_registry_mock.js.map | 1 - .../esm/testing/test_component_builder.js | 123 - .../esm/testing/test_component_builder.js.map | 1 - .../esm/testing/view_resolver_mock.js | 132 - .../esm/testing/view_resolver_mock.js.map | 1 - .../vendor/@angular/compiler/index.js | 13 - .../vendor/@angular/compiler/index.js.map | 1 - .../@angular/compiler/private_export.js | 55 - .../@angular/compiler/private_export.js.map | 1 - .../compiler/src/animation/animation_ast.js | 150 - .../src/animation/animation_ast.js.map | 1 - .../src/animation/animation_compiler.js | 293 - .../src/animation/animation_compiler.js.map | 1 - .../src/animation/animation_parser.js | 475 - .../src/animation/animation_parser.js.map | 1 - .../src/animation/styles_collection.js | 63 - .../src/animation/styles_collection.js.map | 1 - .../@angular/compiler/src/assertions.js | 48 - .../@angular/compiler/src/assertions.js.map | 1 - .../vendor/@angular/compiler/src/chars.js | 83 - .../vendor/@angular/compiler/src/chars.js.map | 1 - .../@angular/compiler/src/compile_metadata.js | 896 - .../compiler/src/compile_metadata.js.map | 1 - .../vendor/@angular/compiler/src/compiler.js | 63 - .../@angular/compiler/src/compiler.js.map | 1 - .../vendor/@angular/compiler/src/config.js | 93 - .../@angular/compiler/src/config.js.map | 1 - .../src/directive_lifecycle_reflector.js | 38 - .../src/directive_lifecycle_reflector.js.map | 1 - .../compiler/src/directive_normalizer.js | 251 - .../compiler/src/directive_normalizer.js.map | 1 - .../compiler/src/directive_resolver.js | 133 - .../compiler/src/directive_resolver.js.map | 1 - .../compiler/src/expression_parser/ast.js | 494 - .../compiler/src/expression_parser/ast.js.map | 1 - .../compiler/src/expression_parser/lexer.js | 379 - .../src/expression_parser/lexer.js.map | 1 - .../compiler/src/expression_parser/parser.js | 679 - .../src/expression_parser/parser.js.map | 1 - .../@angular/compiler/src/facade/async.js | 167 - .../@angular/compiler/src/facade/async.js.map | 1 - .../src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../compiler/src/facade/collection.js | 375 - .../compiler/src/facade/collection.js.map | 1 - .../compiler/src/facade/exception_handler.js | 140 - .../src/facade/exception_handler.js.map | 1 - .../compiler/src/facade/exceptions.js | 89 - .../compiler/src/facade/exceptions.js.map | 1 - .../@angular/compiler/src/facade/lang.js | 465 - .../@angular/compiler/src/facade/lang.js.map | 1 - .../@angular/compiler/src/facade/math.js | 12 - .../@angular/compiler/src/facade/math.js.map | 1 - .../@angular/compiler/src/facade/promise.js | 55 - .../compiler/src/facade/promise.js.map | 1 - .../vendor/@angular/compiler/src/html_ast.js | 91 - .../@angular/compiler/src/html_ast.js.map | 1 - .../@angular/compiler/src/html_lexer.js | 660 - .../@angular/compiler/src/html_lexer.js.map | 1 - .../@angular/compiler/src/html_parser.js | 371 - .../@angular/compiler/src/html_parser.js.map | 1 - .../vendor/@angular/compiler/src/html_tags.js | 386 - .../@angular/compiler/src/html_tags.js.map | 1 - .../@angular/compiler/src/i18n/expander.js | 98 - .../compiler/src/i18n/expander.js.map | 1 - .../compiler/src/i18n/i18n_html_parser.js | 279 - .../compiler/src/i18n/i18n_html_parser.js.map | 1 - .../@angular/compiler/src/i18n/message.js | 36 - .../@angular/compiler/src/i18n/message.js.map | 1 - .../compiler/src/i18n/message_extractor.js | 173 - .../src/i18n/message_extractor.js.map | 1 - .../@angular/compiler/src/i18n/shared.js | 213 - .../@angular/compiler/src/i18n/shared.js.map | 1 - .../compiler/src/i18n/xmb_serializer.js | 110 - .../compiler/src/i18n/xmb_serializer.js.map | 1 - .../@angular/compiler/src/identifiers.js | 207 - .../@angular/compiler/src/identifiers.js.map | 1 - .../compiler/src/interpolation_config.js | 13 - .../compiler/src/interpolation_config.js.map | 1 - .../compiler/src/metadata_resolver.js | 506 - .../compiler/src/metadata_resolver.js.map | 1 - .../@angular/compiler/src/offline_compiler.js | 155 - .../compiler/src/offline_compiler.js.map | 1 - .../compiler/src/output/abstract_emitter.js | 418 - .../src/output/abstract_emitter.js.map | 1 - .../src/output/abstract_js_emitter.js | 171 - .../src/output/abstract_js_emitter.js.map | 1 - .../compiler/src/output/dart_emitter.js | 388 - .../compiler/src/output/dart_emitter.js.map | 1 - .../compiler/src/output/interpretive_view.js | 100 - .../src/output/interpretive_view.js.map | 1 - .../compiler/src/output/output_ast.js | 986 - .../compiler/src/output/output_ast.js.map | 1 - .../compiler/src/output/output_interpreter.js | 457 - .../src/output/output_interpreter.js.map | 1 - .../compiler/src/output/output_jit.js | 53 - .../compiler/src/output/output_jit.js.map | 1 - .../@angular/compiler/src/output/path_util.js | 43 - .../compiler/src/output/path_util.js.map | 1 - .../compiler/src/output/ts_emitter.js | 312 - .../compiler/src/output/ts_emitter.js.map | 1 - .../@angular/compiler/src/parse_util.js | 87 - .../@angular/compiler/src/parse_util.js.map | 1 - .../@angular/compiler/src/pipe_resolver.js | 45 - .../compiler/src/pipe_resolver.js.map | 1 - .../@angular/compiler/src/provider_parser.js | 383 - .../compiler/src/provider_parser.js.map | 1 - .../@angular/compiler/src/runtime_compiler.js | 255 - .../compiler/src/runtime_compiler.js.map | 1 - .../src/schema/dom_element_schema_registry.js | 321 - .../schema/dom_element_schema_registry.js.map | 1 - .../src/schema/dom_security_schema.js | 58 - .../src/schema/dom_security_schema.js.map | 1 - .../src/schema/element_schema_registry.js | 15 - .../src/schema/element_schema_registry.js.map | 1 - .../vendor/@angular/compiler/src/selector.js | 365 - .../@angular/compiler/src/selector.js.map | 1 - .../@angular/compiler/src/shadow_css.js | 507 - .../@angular/compiler/src/shadow_css.js.map | 1 - .../@angular/compiler/src/style_compiler.js | 104 - .../compiler/src/style_compiler.js.map | 1 - .../compiler/src/style_url_resolver.js | 49 - .../compiler/src/style_url_resolver.js.map | 1 - .../@angular/compiler/src/template_ast.js | 288 - .../@angular/compiler/src/template_ast.js.map | 1 - .../@angular/compiler/src/template_parser.js | 834 - .../compiler/src/template_parser.js.map | 1 - .../compiler/src/template_preparser.js | 90 - .../compiler/src/template_preparser.js.map | 1 - .../@angular/compiler/src/url_resolver.js | 322 - .../@angular/compiler/src/url_resolver.js.map | 1 - .../vendor/@angular/compiler/src/util.js | 87 - .../vendor/@angular/compiler/src/util.js.map | 1 - .../src/view_compiler/compile_binding.js | 17 - .../src/view_compiler/compile_binding.js.map | 1 - .../src/view_compiler/compile_element.js | 410 - .../src/view_compiler/compile_element.js.map | 1 - .../src/view_compiler/compile_method.js | 71 - .../src/view_compiler/compile_method.js.map | 1 - .../src/view_compiler/compile_pipe.js | 106 - .../src/view_compiler/compile_pipe.js.map | 1 - .../src/view_compiler/compile_query.js | 120 - .../src/view_compiler/compile_query.js.map | 1 - .../src/view_compiler/compile_view.js | 168 - .../src/view_compiler/compile_view.js.map | 1 - .../compiler/src/view_compiler/constants.js | 119 - .../src/view_compiler/constants.js.map | 1 - .../src/view_compiler/event_binder.js | 141 - .../src/view_compiler/event_binder.js.map | 1 - .../src/view_compiler/expression_converter.js | 244 - .../view_compiler/expression_converter.js.map | 1 - .../src/view_compiler/lifecycle_binder.js | 70 - .../src/view_compiler/lifecycle_binder.js.map | 1 - .../src/view_compiler/property_binder.js | 218 - .../src/view_compiler/property_binder.js.map | 1 - .../compiler/src/view_compiler/util.js | 97 - .../compiler/src/view_compiler/util.js.map | 1 - .../compiler/src/view_compiler/view_binder.js | 84 - .../src/view_compiler/view_binder.js.map | 1 - .../src/view_compiler/view_builder.js | 512 - .../src/view_compiler/view_builder.js.map | 1 - .../src/view_compiler/view_compiler.js | 60 - .../src/view_compiler/view_compiler.js.map | 1 - .../@angular/compiler/src/view_resolver.js | 58 - .../compiler/src/view_resolver.js.map | 1 - .../vendor/@angular/compiler/src/xhr.js | 21 - .../vendor/@angular/compiler/src/xhr.js.map | 1 - .../vendor/@angular/compiler/testing.js | 16 - .../vendor/@angular/compiler/testing.js.map | 1 - .../testing/directive_resolver_mock.js | 89 - .../testing/directive_resolver_mock.js.map | 1 - .../compiler/testing/schema_registry_mock.js | 30 - .../testing/schema_registry_mock.js.map | 1 - .../testing/test_component_builder.js | 137 - .../testing/test_component_builder.js.map | 1 - .../compiler/testing/view_resolver_mock.js | 145 - .../testing/view_resolver_mock.js.map | 1 - .../vendor/@angular/core/bundles/core.umd.js | 12541 ------------ .../@angular/core/bundles/core.umd.min.js | 6 - .../vendor/@angular/core/esm/index.js | 34 - .../vendor/@angular/core/esm/index.js.map | 1 - .../@angular/core/esm/private_export.js | 109 - .../@angular/core/esm/private_export.js.map | 1 - .../animation/active_animation_players_map.js | 54 - .../active_animation_players_map.js.map | 1 - .../esm/src/animation/animation_constants.js | 12 - .../src/animation/animation_constants.js.map | 1 - .../esm/src/animation/animation_driver.js | 16 - .../esm/src/animation/animation_driver.js.map | 1 - .../src/animation/animation_group_player.js | 67 - .../animation/animation_group_player.js.map | 1 - .../esm/src/animation/animation_keyframe.js | 14 - .../src/animation/animation_keyframe.js.map | 1 - .../esm/src/animation/animation_player.js | 40 - .../esm/src/animation/animation_player.js.map | 1 - .../animation/animation_sequence_player.js | 71 - .../animation_sequence_player.js.map | 1 - .../esm/src/animation/animation_style_util.js | 98 - .../src/animation/animation_style_util.js.map | 1 - .../esm/src/animation/animation_styles.js | 13 - .../esm/src/animation/animation_styles.js.map | 1 - .../core/esm/src/animation/metadata.js | 616 - .../core/esm/src/animation/metadata.js.map | 1 - .../esm/src/application_common_providers.js | 32 - .../src/application_common_providers.js.map | 1 - .../@angular/core/esm/src/application_ref.js | 409 - .../core/esm/src/application_ref.js.map | 1 - .../core/esm/src/application_tokens.js | 55 - .../core/esm/src/application_tokens.js.map | 1 - .../@angular/core/esm/src/change_detection.js | 14 - .../core/esm/src/change_detection.js.map | 1 - .../src/change_detection/change_detection.js | 32 - .../change_detection/change_detection.js.map | 1 - .../change_detection/change_detection_util.js | 78 - .../change_detection_util.js.map | 1 - .../change_detection/change_detector_ref.js | 13 - .../change_detector_ref.js.map | 1 - .../esm/src/change_detection/constants.js | 83 - .../esm/src/change_detection/constants.js.map | 1 - .../differs/default_iterable_differ.js | 640 - .../differs/default_iterable_differ.js.map | 1 - .../differs/default_keyvalue_differ.js | 355 - .../differs/default_keyvalue_differ.js.map | 1 - .../differs/iterable_differs.js | 76 - .../differs/iterable_differs.js.map | 1 - .../differs/keyvalue_differs.js | 76 - .../differs/keyvalue_differs.js.map | 1 - .../src/change_detection/pipe_transform.js | 8 - .../change_detection/pipe_transform.js.map | 1 - .../vendor/@angular/core/esm/src/console.js | 22 - .../@angular/core/esm/src/console.js.map | 1 - .../@angular/core/esm/src/debug/debug_node.js | 169 - .../core/esm/src/debug/debug_node.js.map | 1 - .../core/esm/src/debug/debug_renderer.js | 130 - .../core/esm/src/debug/debug_renderer.js.map | 1 - .../vendor/@angular/core/esm/src/di.js | 24 - .../vendor/@angular/core/esm/src/di.js.map | 1 - .../@angular/core/esm/src/di/decorators.js | 46 - .../core/esm/src/di/decorators.js.map | 1 - .../@angular/core/esm/src/di/forward_ref.js | 51 - .../core/esm/src/di/forward_ref.js.map | 1 - .../@angular/core/esm/src/di/injector.js | 42 - .../@angular/core/esm/src/di/injector.js.map | 1 - .../@angular/core/esm/src/di/metadata.js | 250 - .../@angular/core/esm/src/di/metadata.js.map | 1 - .../@angular/core/esm/src/di/opaque_token.js | 37 - .../core/esm/src/di/opaque_token.js.map | 1 - .../@angular/core/esm/src/di/provider.js | 253 - .../@angular/core/esm/src/di/provider.js.map | 1 - .../@angular/core/esm/src/di/provider_util.js | 15 - .../core/esm/src/di/provider_util.js.map | 1 - .../core/esm/src/di/reflective_exceptions.js | 244 - .../esm/src/di/reflective_exceptions.js.map | 1 - .../core/esm/src/di/reflective_injector.js | 800 - .../esm/src/di/reflective_injector.js.map | 1 - .../core/esm/src/di/reflective_key.js | 73 - .../core/esm/src/di/reflective_key.js.map | 1 - .../core/esm/src/di/reflective_provider.js | 230 - .../esm/src/di/reflective_provider.js.map | 1 - .../@angular/core/esm/src/facade/async.js | 144 - .../@angular/core/esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../core/esm/src/facade/collection.js | 350 - .../core/esm/src/facade/collection.js.map | 1 - .../core/esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../core/esm/src/facade/exceptions.js | 49 - .../core/esm/src/facade/exceptions.js.map | 1 - .../@angular/core/esm/src/facade/lang.js | 375 - .../@angular/core/esm/src/facade/lang.js.map | 1 - .../@angular/core/esm/src/facade/math.js | 11 - .../@angular/core/esm/src/facade/math.js.map | 1 - .../@angular/core/esm/src/facade/promise.js | 47 - .../core/esm/src/facade/promise.js.map | 1 - .../vendor/@angular/core/esm/src/linker.js | 21 - .../@angular/core/esm/src/linker.js.map | 1 - .../@angular/core/esm/src/linker/compiler.js | 39 - .../core/esm/src/linker/compiler.js.map | 1 - .../core/esm/src/linker/component_factory.js | 94 - .../esm/src/linker/component_factory.js.map | 1 - .../src/linker/component_factory_resolver.js | 47 - .../linker/component_factory_resolver.js.map | 1 - .../core/esm/src/linker/component_resolver.js | 42 - .../esm/src/linker/component_resolver.js.map | 1 - .../core/esm/src/linker/debug_context.js | 83 - .../core/esm/src/linker/debug_context.js.map | 1 - .../src/linker/dynamic_component_loader.js | 51 - .../linker/dynamic_component_loader.js.map | 1 - .../@angular/core/esm/src/linker/element.js | 81 - .../core/esm/src/linker/element.js.map | 1 - .../core/esm/src/linker/element_injector.js | 27 - .../esm/src/linker/element_injector.js.map | 1 - .../core/esm/src/linker/element_ref.js | 28 - .../core/esm/src/linker/element_ref.js.map | 1 - .../core/esm/src/linker/exceptions.js | 74 - .../core/esm/src/linker/exceptions.js.map | 1 - .../core/esm/src/linker/query_list.js | 88 - .../core/esm/src/linker/query_list.js.map | 1 - .../src/linker/systemjs_component_resolver.js | 51 - .../linker/systemjs_component_resolver.js.map | 1 - .../core/esm/src/linker/template_ref.js | 54 - .../core/esm/src/linker/template_ref.js.map | 1 - .../@angular/core/esm/src/linker/view.js | 370 - .../@angular/core/esm/src/linker/view.js.map | 1 - .../core/esm/src/linker/view_container_ref.js | 114 - .../esm/src/linker/view_container_ref.js.map | 1 - .../@angular/core/esm/src/linker/view_ref.js | 96 - .../core/esm/src/linker/view_ref.js.map | 1 - .../@angular/core/esm/src/linker/view_type.js | 20 - .../core/esm/src/linker/view_type.js.map | 1 - .../core/esm/src/linker/view_utils.js | 341 - .../core/esm/src/linker/view_utils.js.map | 1 - .../vendor/@angular/core/esm/src/metadata.js | 1020 - .../@angular/core/esm/src/metadata.js.map | 1 - .../@angular/core/esm/src/metadata/di.js | 445 - .../@angular/core/esm/src/metadata/di.js.map | 1 - .../core/esm/src/metadata/directives.js | 847 - .../core/esm/src/metadata/directives.js.map | 1 - .../core/esm/src/metadata/lifecycle_hooks.js | 486 - .../esm/src/metadata/lifecycle_hooks.js.map | 1 - .../@angular/core/esm/src/metadata/view.js | 83 - .../core/esm/src/metadata/view.js.map | 1 - .../core/esm/src/platform_common_providers.js | 27 - .../esm/src/platform_common_providers.js.map | 1 - .../esm/src/platform_directives_and_pipes.js | 62 - .../src/platform_directives_and_pipes.js.map | 1 - .../@angular/core/esm/src/profile/profile.js | 79 - .../core/esm/src/profile/profile.js.map | 1 - .../@angular/core/esm/src/profile/wtf_impl.js | 35 - .../core/esm/src/profile/wtf_impl.js.map | 1 - .../@angular/core/esm/src/profile/wtf_init.js | 12 - .../core/esm/src/profile/wtf_init.js.map | 1 - .../platform_reflection_capabilities.js | 8 - .../platform_reflection_capabilities.js.map | 1 - .../core/esm/src/reflection/reflection.js | 16 - .../core/esm/src/reflection/reflection.js.map | 1 - .../src/reflection/reflection_capabilities.js | 204 - .../reflection/reflection_capabilities.js.map | 1 - .../core/esm/src/reflection/reflector.js | 162 - .../core/esm/src/reflection/reflector.js.map | 1 - .../esm/src/reflection/reflector_reader.js | 14 - .../src/reflection/reflector_reader.js.map | 1 - .../@angular/core/esm/src/reflection/types.js | 8 - .../core/esm/src/reflection/types.js.map | 1 - .../vendor/@angular/core/esm/src/render.js | 10 - .../@angular/core/esm/src/render.js.map | 1 - .../@angular/core/esm/src/render/api.js | 49 - .../@angular/core/esm/src/render/api.js.map | 1 - .../vendor/@angular/core/esm/src/security.js | 34 - .../@angular/core/esm/src/security.js.map | 1 - .../core/esm/src/testability/testability.js | 139 - .../esm/src/testability/testability.js.map | 1 - .../vendor/@angular/core/esm/src/util.js | 10 - .../vendor/@angular/core/esm/src/util.js.map | 1 - .../@angular/core/esm/src/util/decorators.js | 252 - .../core/esm/src/util/decorators.js.map | 1 - .../vendor/@angular/core/esm/src/zone.js | 10 - .../vendor/@angular/core/esm/src/zone.js.map | 1 - .../@angular/core/esm/src/zone/ng_zone.js | 222 - .../@angular/core/esm/src/zone/ng_zone.js.map | 1 - .../core/esm/src/zone/ng_zone_impl.js | 86 - .../core/esm/src/zone/ng_zone_impl.js.map | 1 - .../vendor/@angular/core/esm/testing.js | 14 - .../vendor/@angular/core/esm/testing.js.map | 1 - .../vendor/@angular/core/esm/testing/async.js | 58 - .../@angular/core/esm/testing/async.js.map | 1 - .../core/esm/testing/async_test_completer.js | 20 - .../esm/testing/async_test_completer.js.map | 1 - .../core/esm/testing/component_fixture.js | 142 - .../core/esm/testing/component_fixture.js.map | 1 - .../@angular/core/esm/testing/fake_async.js | 90 - .../core/esm/testing/fake_async.js.map | 1 - .../esm/testing/test_component_builder.js | 131 - .../esm/testing/test_component_builder.js.map | 1 - .../core/esm/testing/test_injector.js | 174 - .../core/esm/testing/test_injector.js.map | 1 - .../@angular/core/esm/testing/testing.js | 116 - .../@angular/core/esm/testing/testing.js.map | 1 - .../vendor/@angular/core/index.js | 68 - .../vendor/@angular/core/index.js.map | 1 - .../vendor/@angular/core/private_export.js | 110 - .../@angular/core/private_export.js.map | 1 - .../animation/active_animation_players_map.js | 61 - .../active_animation_players_map.js.map | 1 - .../core/src/animation/animation_constants.js | 13 - .../src/animation/animation_constants.js.map | 1 - .../core/src/animation/animation_driver.js | 32 - .../src/animation/animation_driver.js.map | 1 - .../src/animation/animation_group_player.js | 71 - .../animation/animation_group_player.js.map | 1 - .../core/src/animation/animation_keyframe.js | 17 - .../src/animation/animation_keyframe.js.map | 1 - .../core/src/animation/animation_player.js | 52 - .../src/animation/animation_player.js.map | 1 - .../animation/animation_sequence_player.js | 76 - .../animation_sequence_player.js.map | 1 - .../src/animation/animation_style_util.js | 106 - .../src/animation/animation_style_util.js.map | 1 - .../core/src/animation/animation_styles.js | 16 - .../src/animation/animation_styles.js.map | 1 - .../@angular/core/src/animation/metadata.js | 678 - .../core/src/animation/metadata.js.map | 1 - .../core/src/application_common_providers.js | 33 - .../src/application_common_providers.js.map | 1 - .../@angular/core/src/application_ref.js | 482 - .../@angular/core/src/application_ref.js.map | 1 - .../@angular/core/src/application_tokens.js | 56 - .../core/src/application_tokens.js.map | 1 - .../@angular/core/src/change_detection.js | 24 - .../@angular/core/src/change_detection.js.map | 1 - .../src/change_detection/change_detection.js | 51 - .../change_detection/change_detection.js.map | 1 - .../change_detection/change_detection_util.js | 87 - .../change_detection_util.js.map | 1 - .../change_detection/change_detector_ref.js | 18 - .../change_detector_ref.js.map | 1 - .../core/src/change_detection/constants.js | 85 - .../src/change_detection/constants.js.map | 1 - .../differs/default_iterable_differ.js | 667 - .../differs/default_iterable_differ.js.map | 1 - .../differs/default_keyvalue_differ.js | 367 - .../differs/default_keyvalue_differ.js.map | 1 - .../differs/iterable_differs.js | 79 - .../differs/iterable_differs.js.map | 1 - .../differs/keyvalue_differs.js | 79 - .../differs/keyvalue_differs.js.map | 1 - .../src/change_detection/pipe_transform.js | 9 - .../change_detection/pipe_transform.js.map | 1 - .../vendor/@angular/core/src/console.js | 27 - .../vendor/@angular/core/src/console.js.map | 1 - .../@angular/core/src/debug/debug_node.js | 215 - .../@angular/core/src/debug/debug_node.js.map | 1 - .../@angular/core/src/debug/debug_renderer.js | 135 - .../core/src/debug/debug_renderer.js.map | 1 - .../vendor/@angular/core/src/di.js | 53 - .../vendor/@angular/core/src/di.js.map | 1 - .../vendor/@angular/core/src/di/decorators.js | 47 - .../@angular/core/src/di/decorators.js.map | 1 - .../@angular/core/src/di/forward_ref.js | 54 - .../@angular/core/src/di/forward_ref.js.map | 1 - .../vendor/@angular/core/src/di/injector.js | 47 - .../@angular/core/src/di/injector.js.map | 1 - .../vendor/@angular/core/src/di/metadata.js | 279 - .../@angular/core/src/di/metadata.js.map | 1 - .../@angular/core/src/di/opaque_token.js | 40 - .../@angular/core/src/di/opaque_token.js.map | 1 - .../vendor/@angular/core/src/di/provider.js | 291 - .../@angular/core/src/di/provider.js.map | 1 - .../@angular/core/src/di/provider_util.js | 18 - .../@angular/core/src/di/provider_util.js.map | 1 - .../core/src/di/reflective_exceptions.js | 290 - .../core/src/di/reflective_exceptions.js.map | 1 - .../core/src/di/reflective_injector.js | 838 - .../core/src/di/reflective_injector.js.map | 1 - .../@angular/core/src/di/reflective_key.js | 90 - .../core/src/di/reflective_key.js.map | 1 - .../core/src/di/reflective_provider.js | 246 - .../core/src/di/reflective_provider.js.map | 1 - .../vendor/@angular/core/src/facade/async.js | 167 - .../@angular/core/src/facade/async.js.map | 1 - .../core/src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../@angular/core/src/facade/collection.js | 375 - .../core/src/facade/collection.js.map | 1 - .../core/src/facade/exception_handler.js | 140 - .../core/src/facade/exception_handler.js.map | 1 - .../@angular/core/src/facade/exceptions.js | 89 - .../core/src/facade/exceptions.js.map | 1 - .../vendor/@angular/core/src/facade/lang.js | 465 - .../@angular/core/src/facade/lang.js.map | 1 - .../vendor/@angular/core/src/facade/math.js | 12 - .../@angular/core/src/facade/math.js.map | 1 - .../@angular/core/src/facade/promise.js | 55 - .../@angular/core/src/facade/promise.js.map | 1 - .../vendor/@angular/core/src/linker.js | 38 - .../vendor/@angular/core/src/linker.js.map | 1 - .../@angular/core/src/linker/compiler.js | 44 - .../@angular/core/src/linker/compiler.js.map | 1 - .../core/src/linker/component_factory.js | 163 - .../core/src/linker/component_factory.js.map | 1 - .../src/linker/component_factory_resolver.js | 65 - .../linker/component_factory_resolver.js.map | 1 - .../core/src/linker/component_resolver.js | 58 - .../core/src/linker/component_resolver.js.map | 1 - .../@angular/core/src/linker/debug_context.js | 125 - .../core/src/linker/debug_context.js.map | 1 - .../src/linker/dynamic_component_loader.js | 66 - .../linker/dynamic_component_loader.js.map | 1 - .../@angular/core/src/linker/element.js | 100 - .../@angular/core/src/linker/element.js.map | 1 - .../core/src/linker/element_injector.js | 37 - .../core/src/linker/element_injector.js.map | 1 - .../@angular/core/src/linker/element_ref.js | 31 - .../core/src/linker/element_ref.js.map | 1 - .../@angular/core/src/linker/exceptions.js | 89 - .../core/src/linker/exceptions.js.map | 1 - .../@angular/core/src/linker/query_list.js | 111 - .../core/src/linker/query_list.js.map | 1 - .../src/linker/systemjs_component_resolver.js | 59 - .../linker/systemjs_component_resolver.js.map | 1 - .../@angular/core/src/linker/template_ref.js | 75 - .../core/src/linker/template_ref.js.map | 1 - .../vendor/@angular/core/src/linker/view.js | 406 - .../@angular/core/src/linker/view.js.map | 1 - .../core/src/linker/view_container_ref.js | 161 - .../core/src/linker/view_container_ref.js.map | 1 - .../@angular/core/src/linker/view_ref.js | 142 - .../@angular/core/src/linker/view_ref.js.map | 1 - .../@angular/core/src/linker/view_type.js | 21 - .../@angular/core/src/linker/view_type.js.map | 1 - .../@angular/core/src/linker/view_utils.js | 361 - .../core/src/linker/view_utils.js.map | 1 - .../vendor/@angular/core/src/metadata.js | 1045 - .../vendor/@angular/core/src/metadata.js.map | 1 - .../vendor/@angular/core/src/metadata/di.js | 502 - .../@angular/core/src/metadata/di.js.map | 1 - .../@angular/core/src/metadata/directives.js | 901 - .../core/src/metadata/directives.js.map | 1 - .../core/src/metadata/lifecycle_hooks.js | 519 - .../core/src/metadata/lifecycle_hooks.js.map | 1 - .../vendor/@angular/core/src/metadata/view.js | 87 - .../@angular/core/src/metadata/view.js.map | 1 - .../core/src/platform_common_providers.js | 28 - .../core/src/platform_common_providers.js.map | 1 - .../core/src/platform_directives_and_pipes.js | 63 - .../src/platform_directives_and_pipes.js.map | 1 - .../@angular/core/src/profile/profile.js | 80 - .../@angular/core/src/profile/profile.js.map | 1 - .../@angular/core/src/profile/wtf_impl.js | 42 - .../@angular/core/src/profile/wtf_impl.js.map | 1 - .../@angular/core/src/profile/wtf_init.js | 14 - .../@angular/core/src/profile/wtf_init.js.map | 1 - .../platform_reflection_capabilities.js | 9 - .../platform_reflection_capabilities.js.map | 1 - .../core/src/reflection/reflection.js | 19 - .../core/src/reflection/reflection.js.map | 1 - .../src/reflection/reflection_capabilities.js | 238 - .../reflection/reflection_capabilities.js.map | 1 - .../@angular/core/src/reflection/reflector.js | 174 - .../core/src/reflection/reflector.js.map | 1 - .../core/src/reflection/reflector_reader.js | 19 - .../src/reflection/reflector_reader.js.map | 1 - .../@angular/core/src/reflection/types.js | 9 - .../@angular/core/src/reflection/types.js.map | 1 - .../vendor/@angular/core/src/render.js | 14 - .../vendor/@angular/core/src/render.js.map | 1 - .../vendor/@angular/core/src/render/api.js | 88 - .../@angular/core/src/render/api.js.map | 1 - .../vendor/@angular/core/src/security.js | 39 - .../vendor/@angular/core/src/security.js.map | 1 - .../core/src/testability/testability.js | 151 - .../core/src/testability/testability.js.map | 1 - .../vendor/@angular/core/src/util.js | 12 - .../vendor/@angular/core/src/util.js.map | 1 - .../@angular/core/src/util/decorators.js | 266 - .../@angular/core/src/util/decorators.js.map | 1 - .../vendor/@angular/core/src/zone.js | 13 - .../vendor/@angular/core/src/zone.js.map | 1 - .../vendor/@angular/core/src/zone/ng_zone.js | 257 - .../@angular/core/src/zone/ng_zone.js.map | 1 - .../@angular/core/src/zone/ng_zone_impl.js | 93 - .../core/src/zone/ng_zone_impl.js.map | 1 - .../vendor/@angular/core/testing.js | 18 - .../vendor/@angular/core/testing.js.map | 1 - .../vendor/@angular/core/testing/async.js | 60 - .../vendor/@angular/core/testing/async.js.map | 1 - .../core/testing/async_test_completer.js | 27 - .../core/testing/async_test_completer.js.map | 1 - .../core/testing/component_fixture.js | 149 - .../core/testing/component_fixture.js.map | 1 - .../@angular/core/testing/fake_async.js | 100 - .../@angular/core/testing/fake_async.js.map | 1 - .../core/testing/test_component_builder.js | 140 - .../testing/test_component_builder.js.map | 1 - .../@angular/core/testing/test_injector.js | 186 - .../core/testing/test_injector.js.map | 1 - .../vendor/@angular/core/testing/testing.js | 124 - .../@angular/core/testing/testing.js.map | 1 - .../@angular/forms/bundles/forms.umd.js | 3086 --- .../@angular/forms/bundles/forms.umd.min.js | 3 - .../vendor/@angular/forms/esm/index.js | 9 - .../vendor/@angular/forms/esm/index.js.map | 1 - .../@angular/forms/esm/src/directives.js | 72 - .../@angular/forms/esm/src/directives.js.map | 1 - .../directives/abstract_control_directive.js | 36 - .../abstract_control_directive.js.map | 1 - .../abstract_form_group_directive.js | 31 - .../abstract_form_group_directive.js.map | 1 - .../src/directives/checkbox_value_accessor.js | 41 - .../directives/checkbox_value_accessor.js.map | 1 - .../esm/src/directives/control_container.js | 26 - .../src/directives/control_container.js.map | 1 - .../src/directives/control_value_accessor.js | 17 - .../directives/control_value_accessor.js.map | 1 - .../src/directives/default_value_accessor.js | 47 - .../directives/default_value_accessor.js.map | 1 - .../esm/src/directives/form_interface.js | 8 - .../esm/src/directives/form_interface.js.map | 1 - .../forms/esm/src/directives/ng_control.js | 27 - .../esm/src/directives/ng_control.js.map | 1 - .../esm/src/directives/ng_control_status.js | 52 - .../src/directives/ng_control_status.js.map | 1 - .../forms/esm/src/directives/ng_form.js | 99 - .../forms/esm/src/directives/ng_form.js.map | 1 - .../forms/esm/src/directives/ng_model.js | 108 - .../forms/esm/src/directives/ng_model.js.map | 1 - .../esm/src/directives/ng_model_group.js | 39 - .../esm/src/directives/ng_model_group.js.map | 1 - .../esm/src/directives/normalize_validator.js | 24 - .../src/directives/normalize_validator.js.map | 1 - .../src/directives/number_value_accessor.js | 48 - .../directives/number_value_accessor.js.map | 1 - .../radio_control_value_accessor.js | 118 - .../radio_control_value_accessor.js.map | 1 - .../reactive_directives/form_array_name.js | 46 - .../form_array_name.js.map | 1 - .../form_control_directive.js | 68 - .../form_control_directive.js.map | 1 - .../reactive_directives/form_control_name.js | 70 - .../form_control_name.js.map | 1 - .../form_group_directive.js | 111 - .../form_group_directive.js.map | 1 - .../reactive_directives/form_group_name.js | 39 - .../form_group_name.js.map | 1 - .../select_control_value_accessor.js | 125 - .../select_control_value_accessor.js.map | 1 - .../select_multiple_control_value_accessor.js | 162 - ...ect_multiple_control_value_accessor.js.map | 1 - .../forms/esm/src/directives/shared.js | 102 - .../forms/esm/src/directives/shared.js.map | 1 - .../forms/esm/src/directives/validators.js | 106 - .../esm/src/directives/validators.js.map | 1 - .../@angular/forms/esm/src/facade/async.js | 144 - .../forms/esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../forms/esm/src/facade/collection.js | 350 - .../forms/esm/src/facade/collection.js.map | 1 - .../forms/esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../forms/esm/src/facade/exceptions.js | 49 - .../forms/esm/src/facade/exceptions.js.map | 1 - .../@angular/forms/esm/src/facade/lang.js | 375 - .../@angular/forms/esm/src/facade/lang.js.map | 1 - .../@angular/forms/esm/src/facade/promise.js | 47 - .../forms/esm/src/facade/promise.js.map | 1 - .../@angular/forms/esm/src/form_builder.js | 69 - .../forms/esm/src/form_builder.js.map | 1 - .../@angular/forms/esm/src/form_providers.js | 61 - .../forms/esm/src/form_providers.js.map | 1 - .../vendor/@angular/forms/esm/src/forms.js | 43 - .../@angular/forms/esm/src/forms.js.map | 1 - .../vendor/@angular/forms/esm/src/model.js | 453 - .../@angular/forms/esm/src/model.js.map | 1 - .../@angular/forms/esm/src/validators.js | 143 - .../@angular/forms/esm/src/validators.js.map | 1 - .../vendor/@angular/forms/index.js | 13 - .../vendor/@angular/forms/index.js.map | 1 - .../vendor/@angular/forms/src/directives.js | 95 - .../@angular/forms/src/directives.js.map | 1 - .../directives/abstract_control_directive.js | 85 - .../abstract_control_directive.js.map | 1 - .../abstract_form_group_directive.js | 63 - .../abstract_form_group_directive.js.map | 1 - .../src/directives/checkbox_value_accessor.js | 44 - .../directives/checkbox_value_accessor.js.map | 1 - .../forms/src/directives/control_container.js | 46 - .../src/directives/control_container.js.map | 1 - .../src/directives/control_value_accessor.js | 18 - .../directives/control_value_accessor.js.map | 1 - .../src/directives/default_value_accessor.js | 50 - .../directives/default_value_accessor.js.map | 1 - .../forms/src/directives/form_interface.js | 9 - .../src/directives/form_interface.js.map | 1 - .../forms/src/directives/ng_control.js | 44 - .../forms/src/directives/ng_control.js.map | 1 - .../forms/src/directives/ng_control_status.js | 79 - .../src/directives/ng_control_status.js.map | 1 - .../@angular/forms/src/directives/ng_form.js | 133 - .../forms/src/directives/ng_form.js.map | 1 - .../@angular/forms/src/directives/ng_model.js | 133 - .../forms/src/directives/ng_model.js.map | 1 - .../forms/src/directives/ng_model_group.js | 48 - .../src/directives/ng_model_group.js.map | 1 - .../src/directives/normalize_validator.js | 27 - .../src/directives/normalize_validator.js.map | 1 - .../src/directives/number_value_accessor.js | 51 - .../directives/number_value_accessor.js.map | 1 - .../radio_control_value_accessor.js | 122 - .../radio_control_value_accessor.js.map | 1 - .../reactive_directives/form_array_name.js | 75 - .../form_array_name.js.map | 1 - .../form_control_directive.js | 93 - .../form_control_directive.js.map | 1 - .../reactive_directives/form_control_name.js | 99 - .../form_control_name.js.map | 1 - .../form_group_directive.js | 135 - .../form_group_directive.js.map | 1 - .../reactive_directives/form_group_name.js | 48 - .../form_group_name.js.map | 1 - .../select_control_value_accessor.js | 140 - .../select_control_value_accessor.js.map | 1 - .../select_multiple_control_value_accessor.js | 181 - ...ect_multiple_control_value_accessor.js.map | 1 - .../@angular/forms/src/directives/shared.js | 110 - .../forms/src/directives/shared.js.map | 1 - .../forms/src/directives/validators.js | 117 - .../forms/src/directives/validators.js.map | 1 - .../vendor/@angular/forms/src/facade/async.js | 167 - .../@angular/forms/src/facade/async.js.map | 1 - .../src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../@angular/forms/src/facade/collection.js | 375 - .../forms/src/facade/collection.js.map | 1 - .../forms/src/facade/exception_handler.js | 140 - .../forms/src/facade/exception_handler.js.map | 1 - .../@angular/forms/src/facade/exceptions.js | 89 - .../forms/src/facade/exceptions.js.map | 1 - .../vendor/@angular/forms/src/facade/lang.js | 465 - .../@angular/forms/src/facade/lang.js.map | 1 - .../@angular/forms/src/facade/promise.js | 55 - .../@angular/forms/src/facade/promise.js.map | 1 - .../vendor/@angular/forms/src/form_builder.js | 81 - .../@angular/forms/src/form_builder.js.map | 1 - .../@angular/forms/src/form_providers.js | 64 - .../@angular/forms/src/form_providers.js.map | 1 - .../vendor/@angular/forms/src/forms.js | 78 - .../vendor/@angular/forms/src/forms.js.map | 1 - .../vendor/@angular/forms/src/model.js | 544 - .../vendor/@angular/forms/src/model.js.map | 1 - .../vendor/@angular/forms/src/validators.js | 148 - .../@angular/forms/src/validators.js.map | 1 - .../vendor/@angular/http/bundles/http.umd.js | 2143 --- .../@angular/http/bundles/http.umd.min.js | 2 - .../vendor/@angular/http/esm/http.js | 322 - .../vendor/@angular/http/esm/http.js.map | 1 - .../vendor/@angular/http/esm/index.js | 9 - .../vendor/@angular/http/esm/index.js.map | 1 - .../http/esm/src/backends/browser_jsonp.js | 49 - .../esm/src/backends/browser_jsonp.js.map | 1 - .../http/esm/src/backends/browser_xhr.js | 20 - .../http/esm/src/backends/browser_xhr.js.map | 1 - .../http/esm/src/backends/jsonp_backend.js | 130 - .../esm/src/backends/jsonp_backend.js.map | 1 - .../http/esm/src/backends/xhr_backend.js | 171 - .../http/esm/src/backends/xhr_backend.js.map | 1 - .../http/esm/src/base_request_options.js | 103 - .../http/esm/src/base_request_options.js.map | 1 - .../http/esm/src/base_response_options.js | 97 - .../http/esm/src/base_response_options.js.map | 1 - .../vendor/@angular/http/esm/src/enums.js | 64 - .../vendor/@angular/http/esm/src/enums.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../http/esm/src/facade/collection.js | 350 - .../http/esm/src/facade/collection.js.map | 1 - .../http/esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../http/esm/src/facade/exceptions.js | 49 - .../http/esm/src/facade/exceptions.js.map | 1 - .../@angular/http/esm/src/facade/lang.js | 375 - .../@angular/http/esm/src/facade/lang.js.map | 1 - .../vendor/@angular/http/esm/src/headers.js | 134 - .../@angular/http/esm/src/headers.js.map | 1 - .../vendor/@angular/http/esm/src/http.js | 153 - .../vendor/@angular/http/esm/src/http.js.map | 1 - .../@angular/http/esm/src/http_utils.js | 33 - .../@angular/http/esm/src/http_utils.js.map | 1 - .../@angular/http/esm/src/interfaces.js | 32 - .../@angular/http/esm/src/interfaces.js.map | 1 - .../@angular/http/esm/src/static_request.js | 166 - .../http/esm/src/static_request.js.map | 1 - .../@angular/http/esm/src/static_response.js | 74 - .../http/esm/src/static_response.js.map | 1 - .../http/esm/src/url_search_params.js | 176 - .../http/esm/src/url_search_params.js.map | 1 - .../vendor/@angular/http/esm/testing.js | 9 - .../vendor/@angular/http/esm/testing.js.map | 1 - .../@angular/http/esm/testing/mock_backend.js | 131 - .../http/esm/testing/mock_backend.js.map | 1 - .../vendor/@angular/http/http.js | 347 - .../vendor/@angular/http/http.js.map | 1 - .../vendor/@angular/http/index.js | 13 - .../vendor/@angular/http/index.js.map | 1 - .../http/src/backends/browser_jsonp.js | 54 - .../http/src/backends/browser_jsonp.js.map | 1 - .../@angular/http/src/backends/browser_xhr.js | 23 - .../http/src/backends/browser_xhr.js.map | 1 - .../http/src/backends/jsonp_backend.js | 153 - .../http/src/backends/jsonp_backend.js.map | 1 - .../@angular/http/src/backends/xhr_backend.js | 181 - .../http/src/backends/xhr_backend.js.map | 1 - .../@angular/http/src/base_request_options.js | 115 - .../http/src/base_request_options.js.map | 1 - .../http/src/base_response_options.js | 109 - .../http/src/base_response_options.js.map | 1 - .../vendor/@angular/http/src/enums.js | 65 - .../vendor/@angular/http/src/enums.js.map | 1 - .../http/src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../@angular/http/src/facade/collection.js | 375 - .../http/src/facade/collection.js.map | 1 - .../http/src/facade/exception_handler.js | 140 - .../http/src/facade/exception_handler.js.map | 1 - .../@angular/http/src/facade/exceptions.js | 89 - .../http/src/facade/exceptions.js.map | 1 - .../vendor/@angular/http/src/facade/lang.js | 465 - .../@angular/http/src/facade/lang.js.map | 1 - .../vendor/@angular/http/src/headers.js | 144 - .../vendor/@angular/http/src/headers.js.map | 1 - .../vendor/@angular/http/src/http.js | 164 - .../vendor/@angular/http/src/http.js.map | 1 - .../vendor/@angular/http/src/http_utils.js | 37 - .../@angular/http/src/http_utils.js.map | 1 - .../vendor/@angular/http/src/interfaces.js | 45 - .../@angular/http/src/interfaces.js.map | 1 - .../@angular/http/src/static_request.js | 169 - .../@angular/http/src/static_request.js.map | 1 - .../@angular/http/src/static_response.js | 77 - .../@angular/http/src/static_response.js.map | 1 - .../@angular/http/src/url_search_params.js | 190 - .../http/src/url_search_params.js.map | 1 - .../vendor/@angular/http/testing.js | 13 - .../vendor/@angular/http/testing.js.map | 1 - .../@angular/http/testing/mock_backend.js | 137 - .../@angular/http/testing/mock_backend.js.map | 1 - .../bundles/platform-browser-dynamic.umd.js | 547 - .../platform-browser-dynamic.umd.min.js | 1 - .../platform-browser-dynamic/core_private.js | 12 - .../core_private.js.map | 1 - .../esm/core_private.js | 11 - .../esm/core_private.js.map | 1 - .../platform-browser-dynamic/esm/index.js | 155 - .../platform-browser-dynamic/esm/index.js.map | 1 - .../esm/platform_browser_private.js | 10 - .../esm/platform_browser_private.js.map | 1 - .../esm/private_export_testing.js | 12 - .../esm/private_export_testing.js.map | 1 - .../esm/src/facade/async.js | 144 - .../esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../esm/src/facade/collection.js | 350 - .../esm/src/facade/collection.js.map | 1 - .../esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../esm/src/facade/exceptions.js | 49 - .../esm/src/facade/exceptions.js.map | 1 - .../esm/src/facade/lang.js | 375 - .../esm/src/facade/lang.js.map | 1 - .../esm/src/facade/promise.js | 47 - .../esm/src/facade/promise.js.map | 1 - .../esm/src/xhr/xhr_cache.js | 36 - .../esm/src/xhr/xhr_cache.js.map | 1 - .../esm/src/xhr/xhr_impl.js | 41 - .../esm/src/xhr/xhr_impl.js.map | 1 - .../platform-browser-dynamic/esm/testing.js | 35 - .../esm/testing.js.map | 1 - .../testing/dom_test_component_renderer.js | 35 - .../dom_test_component_renderer.js.map | 1 - .../platform-browser-dynamic/index.js | 159 - .../platform-browser-dynamic/index.js.map | 1 - .../platform_browser_private.js | 11 - .../platform_browser_private.js.map | 1 - .../private_export_testing.js | 13 - .../private_export_testing.js.map | 1 - .../src/facade/async.js | 167 - .../src/facade/async.js.map | 1 - .../src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../src/facade/collection.js | 375 - .../src/facade/collection.js.map | 1 - .../src/facade/exception_handler.js | 140 - .../src/facade/exception_handler.js.map | 1 - .../src/facade/exceptions.js | 89 - .../src/facade/exceptions.js.map | 1 - .../src/facade/lang.js | 465 - .../src/facade/lang.js.map | 1 - .../src/facade/promise.js | 55 - .../src/facade/promise.js.map | 1 - .../src/xhr/xhr_cache.js | 45 - .../src/xhr/xhr_cache.js.map | 1 - .../src/xhr/xhr_impl.js | 53 - .../src/xhr/xhr_impl.js.map | 1 - .../platform-browser-dynamic/testing.js | 39 - .../platform-browser-dynamic/testing.js.map | 1 - .../testing/dom_test_component_renderer.js | 44 - .../dom_test_component_renderer.js.map | 1 - .../bundles/platform-browser.umd.js | 4801 ----- .../bundles/platform-browser.umd.min.js | 5 - .../@angular/platform-browser/core_private.js | 35 - .../platform-browser/core_private.js.map | 1 - .../platform-browser/esm/core_private.js | 34 - .../platform-browser/esm/core_private.js.map | 1 - .../@angular/platform-browser/esm/index.js | 27 - .../platform-browser/esm/index.js.map | 1 - .../platform-browser/esm/private_export.js | 24 - .../esm/private_export.js.map | 1 - .../platform-browser/esm/src/browser.js | 96 - .../platform-browser/esm/src/browser.js.map | 1 - .../esm/src/browser/browser_adapter.js | 445 - .../esm/src/browser/browser_adapter.js.map | 1 - .../src/browser/generic_browser_adapter.js | 66 - .../browser/generic_browser_adapter.js.map | 1 - .../location/browser_platform_location.js | 61 - .../location/browser_platform_location.js.map | 1 - .../esm/src/browser/location/history.js | 11 - .../esm/src/browser/location/history.js.map | 1 - .../esm/src/browser/testability.js | 77 - .../esm/src/browser/testability.js.map | 1 - .../platform-browser/esm/src/browser/title.js | 31 - .../esm/src/browser/title.js.map | 1 - .../esm/src/browser/tools/common_tools.js | 79 - .../esm/src/browser/tools/common_tools.js.map | 1 - .../esm/src/browser/tools/tools.js | 36 - .../esm/src/browser/tools/tools.js.map | 1 - .../platform-browser/esm/src/dom/debug/by.js | 49 - .../esm/src/dom/debug/by.js.map | 1 - .../esm/src/dom/debug/ng_probe.js | 42 - .../esm/src/dom/debug/ng_probe.js.map | 1 - .../esm/src/dom/dom_adapter.js | 40 - .../esm/src/dom/dom_adapter.js.map | 1 - .../esm/src/dom/dom_animate_player.js | 8 - .../esm/src/dom/dom_animate_player.js.map | 1 - .../esm/src/dom/dom_renderer.js | 279 - .../esm/src/dom/dom_renderer.js.map | 1 - .../esm/src/dom/dom_tokens.js | 18 - .../esm/src/dom/dom_tokens.js.map | 1 - .../esm/src/dom/events/dom_events.js | 31 - .../esm/src/dom/events/dom_events.js.map | 1 - .../esm/src/dom/events/event_manager.js | 61 - .../esm/src/dom/events/event_manager.js.map | 1 - .../esm/src/dom/events/hammer_common.js | 56 - .../esm/src/dom/events/hammer_common.js.map | 1 - .../esm/src/dom/events/hammer_gestures.js | 74 - .../esm/src/dom/events/hammer_gestures.js.map | 1 - .../esm/src/dom/events/key_events.js | 105 - .../esm/src/dom/events/key_events.js.map | 1 - .../esm/src/dom/shared_styles_host.js | 69 - .../esm/src/dom/shared_styles_host.js.map | 1 - .../platform-browser/esm/src/dom/util.js | 17 - .../platform-browser/esm/src/dom/util.js.map | 1 - .../esm/src/dom/web_animations_driver.js | 131 - .../esm/src/dom/web_animations_driver.js.map | 1 - .../esm/src/dom/web_animations_player.js | 49 - .../esm/src/dom/web_animations_player.js.map | 1 - .../platform-browser/esm/src/facade/async.js | 144 - .../esm/src/facade/async.js.map | 1 - .../esm/src/facade/base_wrapped_exception.js | 24 - .../src/facade/base_wrapped_exception.js.map | 1 - .../esm/src/facade/browser.js | 24 - .../esm/src/facade/browser.js.map | 1 - .../esm/src/facade/collection.js | 350 - .../esm/src/facade/collection.js.map | 1 - .../esm/src/facade/exception_handler.js | 131 - .../esm/src/facade/exception_handler.js.map | 1 - .../esm/src/facade/exceptions.js | 49 - .../esm/src/facade/exceptions.js.map | 1 - .../platform-browser/esm/src/facade/lang.js | 375 - .../esm/src/facade/lang.js.map | 1 - .../esm/src/facade/promise.js | 47 - .../esm/src/facade/promise.js.map | 1 - .../src/security/dom_sanitization_service.js | 127 - .../security/dom_sanitization_service.js.map | 1 - .../esm/src/security/html_sanitizer.js | 244 - .../esm/src/security/html_sanitizer.js.map | 1 - .../esm/src/security/style_sanitizer.js | 91 - .../esm/src/security/style_sanitizer.js.map | 1 - .../esm/src/security/url_sanitizer.js | 54 - .../esm/src/security/url_sanitizer.js.map | 1 - .../esm/src/web_workers/shared/api.js | 10 - .../esm/src/web_workers/shared/api.js.map | 1 - .../shared/client_message_broker.js | 163 - .../shared/client_message_broker.js.map | 1 - .../esm/src/web_workers/shared/message_bus.js | 18 - .../src/web_workers/shared/message_bus.js.map | 1 - .../src/web_workers/shared/messaging_api.js | 15 - .../web_workers/shared/messaging_api.js.map | 1 - .../web_workers/shared/post_message_bus.js | 140 - .../shared/post_message_bus.js.map | 1 - .../src/web_workers/shared/render_store.js | 47 - .../web_workers/shared/render_store.js.map | 1 - .../web_workers/shared/serialized_types.js | 23 - .../shared/serialized_types.js.map | 1 - .../esm/src/web_workers/shared/serializer.js | 117 - .../src/web_workers/shared/serializer.js.map | 1 - .../shared/service_message_broker.js | 97 - .../shared/service_message_broker.js.map | 1 - .../src/web_workers/ui/event_dispatcher.js | 111 - .../web_workers/ui/event_dispatcher.js.map | 1 - .../src/web_workers/ui/event_serializer.js | 60 - .../web_workers/ui/event_serializer.js.map | 1 - .../src/web_workers/ui/location_providers.js | 26 - .../web_workers/ui/location_providers.js.map | 1 - .../src/web_workers/ui/platform_location.js | 56 - .../web_workers/ui/platform_location.js.map | 1 - .../esm/src/web_workers/ui/renderer.js | 129 - .../esm/src/web_workers/ui/renderer.js.map | 1 - .../web_workers/worker/event_deserializer.js | 13 - .../worker/event_deserializer.js.map | 1 - .../web_workers/worker/location_providers.js | 27 - .../worker/location_providers.js.map | 1 - .../web_workers/worker/platform_location.js | 118 - .../worker/platform_location.js.map | 1 - .../esm/src/web_workers/worker/renderer.js | 234 - .../src/web_workers/worker/renderer.js.map | 1 - .../src/web_workers/worker/worker_adapter.js | 199 - .../web_workers/worker/worker_adapter.js.map | 1 - .../platform-browser/esm/src/worker_app.js | 75 - .../esm/src/worker_app.js.map | 1 - .../platform-browser/esm/src/worker_render.js | 154 - .../esm/src/worker_render.js.map | 1 - .../@angular/platform-browser/esm/testing.js | 9 - .../platform-browser/esm/testing.js.map | 1 - .../platform-browser/esm/testing/browser.js | 45 - .../esm/testing/browser.js.map | 1 - .../esm/testing/browser_util.js | 106 - .../esm/testing/browser_util.js.map | 1 - .../platform-browser/esm/testing/e2e_util.js | 26 - .../esm/testing/e2e_util.js.map | 1 - .../platform-browser/esm/testing_e2e.js | 9 - .../platform-browser/esm/testing_e2e.js.map | 1 - .../vendor/@angular/platform-browser/index.js | 53 - .../@angular/platform-browser/index.js.map | 1 - .../platform-browser/private_export.js | 25 - .../platform-browser/private_export.js.map | 1 - .../@angular/platform-browser/src/browser.js | 98 - .../platform-browser/src/browser.js.map | 1 - .../src/browser/browser_adapter.js | 471 - .../src/browser/browser_adapter.js.map | 1 - .../src/browser/generic_browser_adapter.js | 76 - .../browser/generic_browser_adapter.js.map | 1 - .../location/browser_platform_location.js | 86 - .../location/browser_platform_location.js.map | 1 - .../src/browser/location/history.js | 13 - .../src/browser/location/history.js.map | 1 - .../src/browser/testability.js | 84 - .../src/browser/testability.js.map | 1 - .../platform-browser/src/browser/title.js | 36 - .../platform-browser/src/browser/title.js.map | 1 - .../src/browser/tools/common_tools.js | 86 - .../src/browser/tools/common_tools.js.map | 1 - .../src/browser/tools/tools.js | 39 - .../src/browser/tools/tools.js.map | 1 - .../platform-browser/src/dom/debug/by.js | 54 - .../platform-browser/src/dom/debug/by.js.map | 1 - .../src/dom/debug/ng_probe.js | 44 - .../src/dom/debug/ng_probe.js.map | 1 - .../platform-browser/src/dom/dom_adapter.js | 50 - .../src/dom/dom_adapter.js.map | 1 - .../src/dom/dom_animate_player.js | 9 - .../src/dom/dom_animate_player.js.map | 1 - .../platform-browser/src/dom/dom_renderer.js | 292 - .../src/dom/dom_renderer.js.map | 1 - .../platform-browser/src/dom/dom_tokens.js | 19 - .../src/dom/dom_tokens.js.map | 1 - .../src/dom/events/dom_events.js | 43 - .../src/dom/events/dom_events.js.map | 1 - .../src/dom/events/event_manager.js | 69 - .../src/dom/events/event_manager.js.map | 1 - .../src/dom/events/hammer_common.js | 65 - .../src/dom/events/hammer_common.js.map | 1 - .../src/dom/events/hammer_gestures.js | 86 - .../src/dom/events/hammer_gestures.js.map | 1 - .../src/dom/events/key_events.js | 114 - .../src/dom/events/key_events.js.map | 1 - .../src/dom/shared_styles_host.js | 82 - .../src/dom/shared_styles_host.js.map | 1 - .../@angular/platform-browser/src/dom/util.js | 20 - .../platform-browser/src/dom/util.js.map | 1 - .../src/dom/web_animations_driver.js | 136 - .../src/dom/web_animations_driver.js.map | 1 - .../src/dom/web_animations_player.js | 53 - .../src/dom/web_animations_player.js.map | 1 - .../platform-browser/src/facade/async.js | 167 - .../platform-browser/src/facade/async.js.map | 1 - .../src/facade/base_wrapped_exception.js | 57 - .../src/facade/base_wrapped_exception.js.map | 1 - .../platform-browser/src/facade/browser.js | 25 - .../src/facade/browser.js.map | 1 - .../platform-browser/src/facade/collection.js | 375 - .../src/facade/collection.js.map | 1 - .../src/facade/exception_handler.js | 140 - .../src/facade/exception_handler.js.map | 1 - .../platform-browser/src/facade/exceptions.js | 89 - .../src/facade/exceptions.js.map | 1 - .../platform-browser/src/facade/lang.js | 465 - .../platform-browser/src/facade/lang.js.map | 1 - .../platform-browser/src/facade/promise.js | 55 - .../src/facade/promise.js.map | 1 - .../src/security/dom_sanitization_service.js | 169 - .../security/dom_sanitization_service.js.map | 1 - .../src/security/html_sanitizer.js | 257 - .../src/security/html_sanitizer.js.map | 1 - .../src/security/style_sanitizer.js | 93 - .../src/security/style_sanitizer.js.map | 1 - .../src/security/url_sanitizer.js | 57 - .../src/security/url_sanitizer.js.map | 1 - .../src/web_workers/shared/api.js | 11 - .../src/web_workers/shared/api.js.map | 1 - .../shared/client_message_broker.js | 191 - .../shared/client_message_broker.js.map | 1 - .../src/web_workers/shared/message_bus.js | 23 - .../src/web_workers/shared/message_bus.js.map | 1 - .../src/web_workers/shared/messaging_api.js | 16 - .../web_workers/shared/messaging_api.js.map | 1 - .../web_workers/shared/post_message_bus.js | 154 - .../shared/post_message_bus.js.map | 1 - .../src/web_workers/shared/render_store.js | 50 - .../web_workers/shared/render_store.js.map | 1 - .../web_workers/shared/serialized_types.js | 26 - .../shared/serialized_types.js.map | 1 - .../src/web_workers/shared/serializer.js | 126 - .../src/web_workers/shared/serializer.js.map | 1 - .../shared/service_message_broker.js | 123 - .../shared/service_message_broker.js.map | 1 - .../src/web_workers/ui/event_dispatcher.js | 114 - .../web_workers/ui/event_dispatcher.js.map | 1 - .../src/web_workers/ui/event_serializer.js | 66 - .../web_workers/ui/event_serializer.js.map | 1 - .../src/web_workers/ui/location_providers.js | 27 - .../web_workers/ui/location_providers.js.map | 1 - .../src/web_workers/ui/platform_location.js | 59 - .../web_workers/ui/platform_location.js.map | 1 - .../src/web_workers/ui/renderer.js | 138 - .../src/web_workers/ui/renderer.js.map | 1 - .../web_workers/worker/event_deserializer.js | 15 - .../worker/event_deserializer.js.map | 1 - .../web_workers/worker/location_providers.js | 28 - .../worker/location_providers.js.map | 1 - .../web_workers/worker/platform_location.js | 141 - .../worker/platform_location.js.map | 1 - .../src/web_workers/worker/renderer.js | 248 - .../src/web_workers/worker/renderer.js.map | 1 - .../src/web_workers/worker/worker_adapter.js | 215 - .../web_workers/worker/worker_adapter.js.map | 1 - .../platform-browser/src/worker_app.js | 78 - .../platform-browser/src/worker_app.js.map | 1 - .../platform-browser/src/worker_render.js | 160 - .../platform-browser/src/worker_render.js.map | 1 - .../@angular/platform-browser/testing.js | 13 - .../@angular/platform-browser/testing.js.map | 1 - .../platform-browser/testing/browser.js | 46 - .../platform-browser/testing/browser.js.map | 1 - .../platform-browser/testing/browser_util.js | 153 - .../testing/browser_util.js.map | 1 - .../platform-browser/testing/e2e_util.js | 28 - .../platform-browser/testing/e2e_util.js.map | 1 - .../@angular/platform-browser/testing_e2e.js | 13 - .../platform-browser/testing_e2e.js.map | 1 - .../@angular/router/bundles/router.umd.js | 2611 --- .../@angular/router/bundles/router.umd.min.js | 3 - .../vendor/@angular/router/esm/index.js | 24 - .../vendor/@angular/router/esm/index.js.map | 1 - .../router/esm/src/apply_redirects.js | 252 - .../router/esm/src/apply_redirects.js.map | 1 - .../router/esm/src/common_router_providers.js | 87 - .../esm/src/common_router_providers.js.map | 1 - .../vendor/@angular/router/esm/src/config.js | 33 - .../@angular/router/esm/src/config.js.map | 1 - .../router/esm/src/create_router_state.js | 46 - .../router/esm/src/create_router_state.js.map | 1 - .../router/esm/src/create_url_tree.js | 224 - .../router/esm/src/create_url_tree.js.map | 1 - .../router/esm/src/directives/router_link.js | 107 - .../esm/src/directives/router_link.js.map | 1 - .../esm/src/directives/router_link_active.js | 69 - .../src/directives/router_link_active.js.map | 1 - .../esm/src/directives/router_outlet.js | 75 - .../esm/src/directives/router_outlet.js.map | 1 - .../@angular/router/esm/src/interfaces.js | 8 - .../@angular/router/esm/src/interfaces.js.map | 1 - .../@angular/router/esm/src/recognize.js | 248 - .../@angular/router/esm/src/recognize.js.map | 1 - .../vendor/@angular/router/esm/src/resolve.js | 39 - .../@angular/router/esm/src/resolve.js.map | 1 - .../vendor/@angular/router/esm/src/router.js | 623 - .../@angular/router/esm/src/router.js.map | 1 - .../router/esm/src/router_outlet_map.js | 18 - .../router/esm/src/router_outlet_map.js.map | 1 - .../router/esm/src/router_providers.js | 36 - .../router/esm/src/router_providers.js.map | 1 - .../@angular/router/esm/src/router_state.js | 204 - .../router/esm/src/router_state.js.map | 1 - .../vendor/@angular/router/esm/src/shared.js | 15 - .../@angular/router/esm/src/shared.js.map | 1 - .../@angular/router/esm/src/url_tree.js | 407 - .../@angular/router/esm/src/url_tree.js.map | 1 - .../router/esm/src/utils/collection.js | 71 - .../router/esm/src/utils/collection.js.map | 1 - .../@angular/router/esm/src/utils/tree.js | 76 - .../@angular/router/esm/src/utils/tree.js.map | 1 - .../vendor/@angular/router/index.js | 46 - .../vendor/@angular/router/index.js.map | 1 - .../@angular/router/src/apply_redirects.js | 265 - .../router/src/apply_redirects.js.map | 1 - .../router/src/common_router_providers.js | 91 - .../router/src/common_router_providers.js.map | 1 - .../vendor/@angular/router/src/config.js | 35 - .../vendor/@angular/router/src/config.js.map | 1 - .../router/src/create_router_state.js | 49 - .../router/src/create_router_state.js.map | 1 - .../@angular/router/src/create_url_tree.js | 228 - .../router/src/create_url_tree.js.map | 1 - .../router/src/directives/router_link.js | 120 - .../router/src/directives/router_link.js.map | 1 - .../src/directives/router_link_active.js | 82 - .../src/directives/router_link_active.js.map | 1 - .../router/src/directives/router_outlet.js | 90 - .../src/directives/router_outlet.js.map | 1 - .../vendor/@angular/router/src/interfaces.js | 9 - .../@angular/router/src/interfaces.js.map | 1 - .../vendor/@angular/router/src/recognize.js | 270 - .../@angular/router/src/recognize.js.map | 1 - .../vendor/@angular/router/src/resolve.js | 41 - .../vendor/@angular/router/src/resolve.js.map | 1 - .../vendor/@angular/router/src/router.js | 666 - .../vendor/@angular/router/src/router.js.map | 1 - .../@angular/router/src/router_outlet_map.js | 21 - .../router/src/router_outlet_map.js.map | 1 - .../@angular/router/src/router_providers.js | 39 - .../router/src/router_providers.js.map | 1 - .../@angular/router/src/router_state.js | 232 - .../@angular/router/src/router_state.js.map | 1 - .../vendor/@angular/router/src/shared.js | 16 - .../vendor/@angular/router/src/shared.js.map | 1 - .../vendor/@angular/router/src/url_tree.js | 437 - .../@angular/router/src/url_tree.js.map | 1 - .../@angular/router/src/utils/collection.js | 80 - .../router/src/utils/collection.js.map | 1 - .../vendor/@angular/router/src/utils/tree.js | 92 - .../@angular/router/src/utils/tree.js.map | 1 - .../bootstrap/dist/css/bootstrap-theme.css | 587 - .../dist/css/bootstrap-theme.min.css | 6 - .../vendor/bootstrap/dist/css/bootstrap.css | 6757 ------- .../bootstrap/dist/css/bootstrap.min.css | 6 - .../fonts/glyphicons-halflings-regular.eot | Bin 20127 -> 0 bytes .../fonts/glyphicons-halflings-regular.svg | 288 - .../fonts/glyphicons-halflings-regular.ttf | Bin 45404 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 23424 -> 0 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 18028 -> 0 bytes .../vendor/es6-shim/es6-shim.js | 3777 ---- .../font-awesome/css/font-awesome.min.css | 4 - .../vendor/font-awesome/fonts/FontAwesome.otf | Bin 134808 -> 0 bytes .../fonts/fontawesome-webfont.eot | Bin 165742 -> 0 bytes .../fonts/fontawesome-webfont.svg | 2671 --- .../fonts/fontawesome-webfont.ttf | Bin 165548 -> 0 bytes .../fonts/fontawesome-webfont.woff | Bin 98024 -> 0 bytes .../fonts/fontawesome-webfont.woff2 | Bin 77160 -> 0 bytes .../vendor/highcharts/highstock.js | 452 - .../vendor/jquery/dist/jquery.min.js | 4 - .../simmvaluationweb/vendor/moment/moment.js | 4463 ----- .../ng2-bootstrap/bundles/ng2-bootstrap.js | 5379 ------ .../bundles/ng2-bootstrap.min.js | 7 - .../ng2-bootstrap/components/accordion.js | 8 - .../accordion/accordion-group.component.js | 78 - .../accordion/accordion.component.js | 56 - .../vendor/ng2-bootstrap/components/alert.js | 3 - .../components/alert/alert.component.js | 65 - .../ng2-bootstrap/components/buttons.js | 8 - .../buttons/button-checkbox.directive.js | 93 - .../buttons/button-radio.directive.js | 90 - .../ng2-bootstrap/components/carousel.js | 8 - .../components/carousel/carousel.component.js | 189 - .../components/carousel/slide.component.js | 51 - .../ng2-bootstrap/components/collapse.js | 3 - .../components/collapse/collapse.directive.js | 171 - .../vendor/ng2-bootstrap/components/common.js | 42 - .../ng2-bootstrap/components/datepicker.js | 16 - .../components/datepicker/date-formatter.js | 11 - .../datepicker/datepicker-inner.component.js | 342 - .../datepicker/datepicker-popup.component.js | 169 - .../datepicker/datepicker.component.js | 167 - .../datepicker/daypicker.component.js | 126 - .../datepicker/monthpicker.component.js | 64 - .../datepicker/yearpicker.component.js | 67 - .../ng2-bootstrap/components/dropdown.js | 11 - .../dropdown/dropdown-menu.directive.js | 38 - .../dropdown/dropdown-toggle.directive.js | 71 - .../components/dropdown/dropdown.directive.js | 166 - .../components/dropdown/dropdown.service.js | 69 - .../vendor/ng2-bootstrap/components/modal.js | 12 - .../modal/modal-backdrop.component.js | 60 - .../components/modal/modal-options.class.js | 21 - .../components/modal/modal.component.js | 338 - .../components/ng2-bootstrap-config.js | 27 - .../ng2-bootstrap/components/pagination.js | 8 - .../components/pagination/pager.component.js | 53 - .../pagination/pagination.component.js | 271 - .../ng2-bootstrap/components/position.js | 151 - .../ng2-bootstrap/components/progressbar.js | 11 - .../components/progressbar/bar.component.js | 72 - .../progressbar/progress.directive.js | 69 - .../progressbar/progressbar.component.js | 43 - .../vendor/ng2-bootstrap/components/rating.js | 3 - .../components/rating/rating.component.js | 146 - .../vendor/ng2-bootstrap/components/tabs.js | 11 - .../components/tabs/tab-heading.directive.js | 23 - .../components/tabs/tab.directive.js | 91 - .../components/tabs/tabset.component.js | 140 - .../ng2-bootstrap/components/timepicker.js | 3 - .../timepicker/timepicker.component.js | 350 - .../ng2-bootstrap/components/tooltip.js | 8 - .../tooltip/tooltip-container.component.js | 56 - .../tooltip/tooltip-options.class.js | 22 - .../components/tooltip/tooltip.directive.js | 111 - .../ng2-bootstrap/components/typeahead.js | 10 - .../components/typeahead/latin-map.js | 827 - .../typeahead-container.component.js | 142 - .../typeahead/typeahead-options.class.js | 8 - .../components/typeahead/typeahead-utils.js | 42 - .../typeahead/typeahead.directive.js | 358 - .../utils/components-helper.service.js | 85 - .../components/utils/utils.class.js | 22 - .../vendor/ng2-bootstrap/gulpfile.js | 9 - .../vendor/ng2-bootstrap/ng2-bootstrap.js | 62 - .../node_modules/moment/ender.js | 1 - .../node_modules/moment/locale/af.js | 73 - .../node_modules/moment/locale/ar-ma.js | 60 - .../node_modules/moment/locale/ar-sa.js | 104 - .../node_modules/moment/locale/ar-tn.js | 58 - .../node_modules/moment/locale/ar.js | 137 - .../node_modules/moment/locale/az.js | 105 - .../node_modules/moment/locale/be.js | 134 - .../node_modules/moment/locale/bg.js | 90 - .../node_modules/moment/locale/bn.js | 119 - .../node_modules/moment/locale/bo.js | 119 - .../node_modules/moment/locale/br.js | 108 - .../node_modules/moment/locale/bs.js | 143 - .../node_modules/moment/locale/ca.js | 81 - .../node_modules/moment/locale/cs.js | 172 - .../node_modules/moment/locale/cv.js | 63 - .../node_modules/moment/locale/cy.js | 80 - .../node_modules/moment/locale/da.js | 60 - .../node_modules/moment/locale/de-at.js | 79 - .../node_modules/moment/locale/de.js | 78 - .../node_modules/moment/locale/dv.js | 99 - .../node_modules/moment/locale/el.js | 98 - .../node_modules/moment/locale/en-au.js | 66 - .../node_modules/moment/locale/en-ca.js | 63 - .../node_modules/moment/locale/en-gb.js | 67 - .../node_modules/moment/locale/en-ie.js | 67 - .../node_modules/moment/locale/en-nz.js | 66 - .../node_modules/moment/locale/eo.js | 73 - .../node_modules/moment/locale/es-do.js | 80 - .../node_modules/moment/locale/es.js | 81 - .../node_modules/moment/locale/et.js | 80 - .../node_modules/moment/locale/eu.js | 66 - .../node_modules/moment/locale/fa.js | 106 - .../node_modules/moment/locale/fi.js | 107 - .../node_modules/moment/locale/fo.js | 60 - .../node_modules/moment/locale/fr-ca.js | 60 - .../node_modules/moment/locale/fr-ch.js | 64 - .../node_modules/moment/locale/fr.js | 64 - .../node_modules/moment/locale/fy.js | 73 - .../node_modules/moment/locale/gd.js | 76 - .../node_modules/moment/locale/gl.js | 77 - .../node_modules/moment/locale/he.js | 99 - .../node_modules/moment/locale/hi.js | 124 - .../node_modules/moment/locale/hr.js | 145 - .../node_modules/moment/locale/hu.js | 109 - .../node_modules/moment/locale/hy-am.js | 95 - .../node_modules/moment/locale/id.js | 83 - .../node_modules/moment/locale/is.js | 127 - .../node_modules/moment/locale/it.js | 70 - .../node_modules/moment/locale/ja.js | 76 - .../node_modules/moment/locale/jv.js | 83 - .../node_modules/moment/locale/ka.js | 89 - .../node_modules/moment/locale/kk.js | 87 - .../node_modules/moment/locale/km.js | 58 - .../node_modules/moment/locale/ko.js | 68 - .../node_modules/moment/locale/ky.js | 88 - .../node_modules/moment/locale/lb.js | 136 - .../node_modules/moment/locale/lo.js | 70 - .../node_modules/moment/locale/lt.js | 117 - .../node_modules/moment/locale/lv.js | 97 - .../node_modules/moment/locale/me.js | 111 - .../node_modules/moment/locale/mk.js | 90 - .../node_modules/moment/locale/ml.js | 81 - .../node_modules/moment/locale/mr.js | 159 - .../node_modules/moment/locale/ms-my.js | 83 - .../node_modules/moment/locale/ms.js | 82 - .../node_modules/moment/locale/my.js | 93 - .../node_modules/moment/locale/nb.js | 63 - .../node_modules/moment/locale/ne.js | 123 - .../node_modules/moment/locale/nl.js | 73 - .../node_modules/moment/locale/nn.js | 60 - .../node_modules/moment/locale/pa-in.js | 124 - .../node_modules/moment/locale/pl.js | 105 - .../node_modules/moment/locale/pt-br.js | 61 - .../node_modules/moment/locale/pt.js | 65 - .../node_modules/moment/locale/ro.js | 75 - .../node_modules/moment/locale/ru.js | 183 - .../node_modules/moment/locale/se.js | 61 - .../node_modules/moment/locale/si.js | 71 - .../node_modules/moment/locale/sk.js | 150 - .../node_modules/moment/locale/sl.js | 162 - .../node_modules/moment/locale/sq.js | 70 - .../node_modules/moment/locale/sr-cyrl.js | 110 - .../node_modules/moment/locale/sr.js | 110 - .../node_modules/moment/locale/ss.js | 89 - .../node_modules/moment/locale/sv.js | 69 - .../node_modules/moment/locale/sw.js | 59 - .../node_modules/moment/locale/ta.js | 129 - .../node_modules/moment/locale/te.js | 89 - .../node_modules/moment/locale/th.js | 67 - .../node_modules/moment/locale/tl-ph.js | 62 - .../node_modules/moment/locale/tlh.js | 120 - .../node_modules/moment/locale/tr.js | 90 - .../node_modules/moment/locale/tzl.js | 91 - .../node_modules/moment/locale/tzm-latn.js | 58 - .../node_modules/moment/locale/tzm.js | 58 - .../node_modules/moment/locale/uk.js | 146 - .../node_modules/moment/locale/uz.js | 58 - .../node_modules/moment/locale/vi.js | 79 - .../node_modules/moment/locale/x-pseudo.js | 68 - .../node_modules/moment/locale/zh-cn.js | 127 - .../node_modules/moment/locale/zh-tw.js | 104 - .../node_modules/moment/min/locales.js | 8104 -------- .../node_modules/moment/min/locales.min.js | 253 - .../moment/min/moment-with-locales.js | 11954 ------------ .../moment/min/moment-with-locales.min.js | 673 - .../node_modules/moment/min/moment.min.js | 492 - .../node_modules/moment/moment.js | 4195 ---- .../node_modules/moment/package.js | 11 - .../moment/src/lib/create/check-overflow.js | 34 - .../moment/src/lib/create/date-from-array.js | 21 - .../moment/src/lib/create/from-anything.js | 108 - .../moment/src/lib/create/from-array.js | 136 - .../moment/src/lib/create/from-object.js | 16 - .../src/lib/create/from-string-and-array.js | 50 - .../src/lib/create/from-string-and-format.js | 107 - .../moment/src/lib/create/from-string.js | 120 - .../moment/src/lib/create/local.js | 5 - .../moment/src/lib/create/parsing-flags.js | 24 - .../node_modules/moment/src/lib/create/utc.js | 5 - .../moment/src/lib/create/valid.js | 42 - .../moment/src/lib/duration/abs.js | 18 - .../moment/src/lib/duration/add-subtract.js | 21 - .../moment/src/lib/duration/as.js | 55 - .../moment/src/lib/duration/bubble.js | 61 - .../moment/src/lib/duration/constructor.js | 41 - .../moment/src/lib/duration/create.js | 118 - .../moment/src/lib/duration/duration.js | 16 - .../moment/src/lib/duration/get.js | 25 - .../moment/src/lib/duration/humanize.js | 76 - .../moment/src/lib/duration/iso-string.js | 52 - .../moment/src/lib/duration/prototype.js | 48 - .../moment/src/lib/format/format.js | 91 - .../moment/src/lib/locale/base-config.js | 44 - .../moment/src/lib/locale/calendar.js | 15 - .../moment/src/lib/locale/constructor.js | 5 - .../node_modules/moment/src/lib/locale/en.js | 15 - .../moment/src/lib/locale/formats.js | 23 - .../moment/src/lib/locale/invalid.js | 5 - .../moment/src/lib/locale/lists.js | 92 - .../moment/src/lib/locale/locale.js | 39 - .../moment/src/lib/locale/locales.js | 171 - .../moment/src/lib/locale/ordinal.js | 7 - .../moment/src/lib/locale/pre-post-format.js | 3 - .../moment/src/lib/locale/prototype.js | 69 - .../moment/src/lib/locale/relative.js | 29 - .../node_modules/moment/src/lib/locale/set.js | 46 - .../moment/src/lib/moment/add-subtract.js | 55 - .../moment/src/lib/moment/calendar.js | 26 - .../moment/src/lib/moment/clone.js | 5 - .../moment/src/lib/moment/compare.js | 59 - .../moment/src/lib/moment/constructor.js | 74 - .../moment/src/lib/moment/creation-data.js | 9 - .../moment/src/lib/moment/diff.js | 62 - .../moment/src/lib/moment/format.js | 32 - .../moment/src/lib/moment/from.js | 17 - .../moment/src/lib/moment/get-set.js | 55 - .../moment/src/lib/moment/locale.js | 34 - .../moment/src/lib/moment/min-max.js | 63 - .../moment/src/lib/moment/moment.js | 28 - .../node_modules/moment/src/lib/moment/now.js | 3 - .../moment/src/lib/moment/prototype.js | 149 - .../moment/src/lib/moment/start-end-of.js | 59 - .../moment/src/lib/moment/to-type.js | 34 - .../node_modules/moment/src/lib/moment/to.js | 17 - .../moment/src/lib/moment/valid.js | 15 - .../moment/src/lib/parse/regex.js | 54 - .../moment/src/lib/parse/token.js | 32 - .../moment/src/lib/units/aliases.js | 30 - .../moment/src/lib/units/constants.js | 9 - .../moment/src/lib/units/day-of-month.js | 36 - .../moment/src/lib/units/day-of-week.js | 360 - .../moment/src/lib/units/day-of-year.js | 36 - .../node_modules/moment/src/lib/units/hour.js | 138 - .../moment/src/lib/units/millisecond.js | 69 - .../moment/src/lib/units/minute.js | 29 - .../moment/src/lib/units/month.js | 274 - .../moment/src/lib/units/offset.js | 219 - .../moment/src/lib/units/priorities.js | 16 - .../moment/src/lib/units/quarter.js | 32 - .../moment/src/lib/units/second.js | 29 - .../moment/src/lib/units/timestamp.js | 20 - .../moment/src/lib/units/timezone.js | 16 - .../moment/src/lib/units/units.js | 20 - .../src/lib/units/week-calendar-utils.js | 65 - .../moment/src/lib/units/week-year.js | 107 - .../node_modules/moment/src/lib/units/week.js | 67 - .../node_modules/moment/src/lib/units/year.js | 75 - .../moment/src/lib/utils/abs-ceil.js | 7 - .../moment/src/lib/utils/abs-floor.js | 8 - .../moment/src/lib/utils/abs-round.js | 7 - .../moment/src/lib/utils/compare-arrays.js | 16 - .../moment/src/lib/utils/defaults.js | 10 - .../moment/src/lib/utils/deprecate.js | 40 - .../moment/src/lib/utils/extend.js | 19 - .../moment/src/lib/utils/has-own-prop.js | 3 - .../moment/src/lib/utils/hooks.js | 13 - .../moment/src/lib/utils/index-of.js | 18 - .../moment/src/lib/utils/is-array.js | 3 - .../moment/src/lib/utils/is-date.js | 3 - .../moment/src/lib/utils/is-function.js | 3 - .../moment/src/lib/utils/is-object-empty.js | 8 - .../moment/src/lib/utils/is-object.js | 3 - .../moment/src/lib/utils/is-undefined.js | 3 - .../node_modules/moment/src/lib/utils/keys.js | 19 - .../node_modules/moment/src/lib/utils/map.js | 7 - .../node_modules/moment/src/lib/utils/some.js | 19 - .../moment/src/lib/utils/to-int.js | 12 - .../moment/src/lib/utils/zero-fill.js | 7 - .../node_modules/moment/src/locale/af.js | 63 - .../node_modules/moment/src/locale/ar-ma.js | 51 - .../node_modules/moment/src/locale/ar-sa.js | 95 - .../node_modules/moment/src/locale/ar-tn.js | 49 - .../node_modules/moment/src/locale/ar.js | 128 - .../node_modules/moment/src/locale/az.js | 96 - .../node_modules/moment/src/locale/be.js | 125 - .../node_modules/moment/src/locale/bg.js | 81 - .../node_modules/moment/src/locale/bn.js | 110 - .../node_modules/moment/src/locale/bo.js | 110 - .../node_modules/moment/src/locale/br.js | 99 - .../node_modules/moment/src/locale/bs.js | 134 - .../node_modules/moment/src/locale/ca.js | 72 - .../node_modules/moment/src/locale/cs.js | 163 - .../node_modules/moment/src/locale/cv.js | 53 - .../node_modules/moment/src/locale/cy.js | 71 - .../node_modules/moment/src/locale/da.js | 51 - .../node_modules/moment/src/locale/de-at.js | 69 - .../node_modules/moment/src/locale/de.js | 68 - .../node_modules/moment/src/locale/dv.js | 89 - .../node_modules/moment/src/locale/el.js | 86 - .../node_modules/moment/src/locale/en-au.js | 57 - .../node_modules/moment/src/locale/en-ca.js | 53 - .../node_modules/moment/src/locale/en-gb.js | 58 - .../node_modules/moment/src/locale/en-ie.js | 58 - .../node_modules/moment/src/locale/en-nz.js | 56 - .../node_modules/moment/src/locale/eo.js | 64 - .../node_modules/moment/src/locale/es-do.js | 71 - .../node_modules/moment/src/locale/es.js | 72 - .../node_modules/moment/src/locale/et.js | 71 - .../node_modules/moment/src/locale/eu.js | 57 - .../node_modules/moment/src/locale/fa.js | 97 - .../node_modules/moment/src/locale/fi.js | 98 - .../node_modules/moment/src/locale/fo.js | 51 - .../node_modules/moment/src/locale/fr-ca.js | 51 - .../node_modules/moment/src/locale/fr-ch.js | 55 - .../node_modules/moment/src/locale/fr.js | 55 - .../node_modules/moment/src/locale/fy.js | 64 - .../node_modules/moment/src/locale/gd.js | 67 - .../node_modules/moment/src/locale/gl.js | 68 - .../node_modules/moment/src/locale/he.js | 90 - .../node_modules/moment/src/locale/hi.js | 115 - .../node_modules/moment/src/locale/hr.js | 136 - .../node_modules/moment/src/locale/hu.js | 100 - .../node_modules/moment/src/locale/hy-am.js | 86 - .../node_modules/moment/src/locale/id.js | 74 - .../node_modules/moment/src/locale/is.js | 118 - .../node_modules/moment/src/locale/it.js | 61 - .../node_modules/moment/src/locale/ja.js | 67 - .../node_modules/moment/src/locale/jv.js | 73 - .../node_modules/moment/src/locale/ka.js | 80 - .../node_modules/moment/src/locale/kk.js | 77 - .../node_modules/moment/src/locale/km.js | 49 - .../node_modules/moment/src/locale/ko.js | 59 - .../node_modules/moment/src/locale/ky.js | 78 - .../node_modules/moment/src/locale/lb.js | 127 - .../node_modules/moment/src/locale/lo.js | 61 - .../node_modules/moment/src/locale/lt.js | 108 - .../node_modules/moment/src/locale/lv.js | 88 - .../node_modules/moment/src/locale/me.js | 101 - .../node_modules/moment/src/locale/mk.js | 81 - .../node_modules/moment/src/locale/ml.js | 72 - .../node_modules/moment/src/locale/mr.js | 150 - .../node_modules/moment/src/locale/ms-my.js | 74 - .../node_modules/moment/src/locale/ms.js | 73 - .../node_modules/moment/src/locale/my.js | 84 - .../node_modules/moment/src/locale/nb.js | 54 - .../node_modules/moment/src/locale/ne.js | 114 - .../node_modules/moment/src/locale/nl.js | 64 - .../node_modules/moment/src/locale/nn.js | 51 - .../node_modules/moment/src/locale/pa-in.js | 115 - .../node_modules/moment/src/locale/pl.js | 95 - .../node_modules/moment/src/locale/pt-br.js | 52 - .../node_modules/moment/src/locale/pt.js | 56 - .../node_modules/moment/src/locale/ro.js | 66 - .../node_modules/moment/src/locale/ru.js | 173 - .../node_modules/moment/src/locale/se.js | 51 - .../node_modules/moment/src/locale/si.js | 61 - .../node_modules/moment/src/locale/sk.js | 141 - .../node_modules/moment/src/locale/sl.js | 152 - .../node_modules/moment/src/locale/sq.js | 61 - .../node_modules/moment/src/locale/sr-cyrl.js | 101 - .../node_modules/moment/src/locale/sr.js | 101 - .../node_modules/moment/src/locale/ss.js | 80 - .../node_modules/moment/src/locale/sv.js | 60 - .../node_modules/moment/src/locale/sw.js | 50 - .../node_modules/moment/src/locale/ta.js | 120 - .../node_modules/moment/src/locale/te.js | 79 - .../node_modules/moment/src/locale/th.js | 57 - .../node_modules/moment/src/locale/tl-ph.js | 53 - .../node_modules/moment/src/locale/tlh.js | 110 - .../node_modules/moment/src/locale/tr.js | 81 - .../node_modules/moment/src/locale/tzl.js | 82 - .../moment/src/locale/tzm-latn.js | 49 - .../node_modules/moment/src/locale/tzm.js | 49 - .../node_modules/moment/src/locale/uk.js | 137 - .../node_modules/moment/src/locale/uz.js | 49 - .../node_modules/moment/src/locale/vi.js | 70 - .../moment/src/locale/x-pseudo.js | 58 - .../node_modules/moment/src/locale/zh-cn.js | 118 - .../node_modules/moment/src/locale/zh-tw.js | 94 - .../node_modules/moment/src/moment.js | 82 - .../vendor/ng2-bootstrap/protractor.conf.js | 7 - .../vendor/ng2-bootstrap/spec-bundle.js | 64 - .../vendor/ng2-bootstrap/typedoc.js | 17 - .../vendor/ng2-popover/Popover.js | 184 - .../vendor/ng2-popover/PopoverContent.js | 228 - .../vendor/ng2-popover/index.js | 10 - .../vendor/ng2-select/bundles/ng2-select.js | 673 - .../ng2-select/bundles/ng2-select.min.js | 2 - .../ng2-select/components/css/ng2-select.css | 273 - .../vendor/ng2-select/components/select.js | 3 - .../ng2-select/components/select/common.js | 5 - .../ng2-select/components/select/off-click.js | 44 - .../components/select/select-interfaces.js | 1 - .../components/select/select-item.js | 40 - .../components/select/select-pipes.js | 48 - .../ng2-select/components/select/select.js | 502 - .../vendor/ng2-select/gulpfile.js | 9 - .../vendor/ng2-select/ng2-select.js | 13 - .../vendor/ng2-table/bundles/ng2-table.js | 318 - .../vendor/ng2-table/bundles/ng2-table.min.js | 2 - .../components/ng-table-directives.js | 6 - .../table/ng-table-filtering.directive.js | 64 - .../table/ng-table-paging.directive.js | 56 - .../table/ng-table-sorting.directive.js | 73 - .../components/table/ng-table.component.js | 91 - .../vendor/ng2-table/gulpfile.js | 9 - .../vendor/ng2-table/ng2-table.js | 22 - .../vendor/reflect-metadata/Reflect.js | 962 - .../vendor/reflect-metadata/Reflect.js.map | 1 - .../vendor/reflect-metadata/Reflect.ts | 1538 -- .../reflect-metadata/reflect-metadata.d.ts | 489 - .../vendor/reflect-metadata/temp/Reflect.js | 964 - .../reflect-metadata/temp/Reflect.js.map | 1 - .../reflect-metadata/temp/test/harness.js | 36 - .../reflect-metadata/temp/test/harness.js.map | 1 - .../temp/test/reflect/reflect-decorate.js | 208 - .../temp/test/reflect/reflect-decorate.js.map | 1 - .../test/reflect/reflect-definemetadata.js | 17 - .../reflect/reflect-definemetadata.js.map | 1 - .../test/reflect/reflect-deletemetadata.js | 38 - .../reflect/reflect-deletemetadata.js.map | 1 - .../temp/test/reflect/reflect-getmetadata.js | 51 - .../test/reflect/reflect-getmetadata.js.map | 1 - .../test/reflect/reflect-getmetadatakeys.js | 98 - .../reflect/reflect-getmetadatakeys.js.map | 1 - .../test/reflect/reflect-getownmetadata.js | 51 - .../reflect/reflect-getownmetadata.js.map | 1 - .../reflect/reflect-getownmetadatakeys.js | 78 - .../reflect/reflect-getownmetadatakeys.js.map | 1 - .../temp/test/reflect/reflect-hasmetadata.js | 51 - .../test/reflect/reflect-hasmetadata.js.map | 1 - .../test/reflect/reflect-hasownmetadata.js | 51 - .../reflect/reflect-hasownmetadata.js.map | 1 - .../temp/test/reflect/reflect-metadata.js | 36 - .../temp/test/reflect/reflect-metadata.js.map | 1 - .../vendor/reflect-metadata/temp/test/run.js | 5 - .../reflect-metadata/temp/test/run.js.map | 1 - .../vendor/reflect-metadata/temp/test/spec.js | 14 - .../reflect-metadata/temp/test/spec.js.map | 1 - .../vendor/reflect-metadata/test/harness.ts | 40 - .../test/reflect/reflect-decorate.ts | 208 - .../test/reflect/reflect-definemetadata.ts | 17 - .../test/reflect/reflect-deletemetadata.ts | 38 - .../test/reflect/reflect-getmetadata.ts | 51 - .../test/reflect/reflect-getmetadatakeys.ts | 98 - .../test/reflect/reflect-getownmetadata.ts | 51 - .../reflect/reflect-getownmetadatakeys.ts | 78 - .../test/reflect/reflect-hasmetadata.ts | 51 - .../test/reflect/reflect-hasownmetadata.ts | 51 - .../test/reflect/reflect-metadata.ts | 38 - .../vendor/reflect-metadata/test/run.ts | 5 - .../vendor/reflect-metadata/test/spec.ts | 10 - .../vendor/reflect-metadata/typings.d.ts | 15 - .../vendor/reflect-metadata/typings/node.d.ts | 13 - .../vendor/rxjs/AsyncSubject.js | 53 - .../vendor/rxjs/AsyncSubject.js.map | 1 - .../vendor/rxjs/BehaviorSubject.js | 54 - .../vendor/rxjs/BehaviorSubject.js.map | 1 - .../vendor/rxjs/InnerSubscriber.js | 36 - .../vendor/rxjs/InnerSubscriber.js.map | 1 - .../vendor/rxjs/Notification.js | 126 - .../vendor/rxjs/Notification.js.map | 1 - .../vendor/rxjs/Observable.js | 135 - .../vendor/rxjs/Observable.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Observer.js | 8 - .../vendor/rxjs/Observer.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Operator.js | 12 - .../vendor/rxjs/Operator.js.map | 1 - .../vendor/rxjs/OuterSubscriber.js | 30 - .../vendor/rxjs/OuterSubscriber.js.map | 1 - .../vendor/rxjs/ReplaySubject.js | 79 - .../vendor/rxjs/ReplaySubject.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Rx.DOM.js | 24 - .../vendor/rxjs/Rx.DOM.js.map | 1 - .../vendor/rxjs/Rx.KitchenSink.js | 33 - .../vendor/rxjs/Rx.KitchenSink.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Rx.js | 186 - .../simmvaluationweb/vendor/rxjs/Rx.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Scheduler.js | 2 - .../vendor/rxjs/Scheduler.js.map | 1 - .../simmvaluationweb/vendor/rxjs/Subject.js | 206 - .../vendor/rxjs/Subject.js.map | 1 - .../vendor/rxjs/SubjectSubscription.js | 40 - .../vendor/rxjs/SubjectSubscription.js.map | 1 - .../vendor/rxjs/Subscriber.js | 251 - .../vendor/rxjs/Subscriber.js.map | 1 - .../vendor/rxjs/Subscription.js | 150 - .../vendor/rxjs/Subscription.js.map | 1 - .../rxjs/add/observable/bindCallback.js | 5 - .../rxjs/add/observable/bindCallback.js.map | 1 - .../rxjs/add/observable/bindNodeCallback.js | 5 - .../add/observable/bindNodeCallback.js.map | 1 - .../rxjs/add/observable/combineLatest.js | 5 - .../rxjs/add/observable/combineLatest.js.map | 1 - .../vendor/rxjs/add/observable/concat.js | 5 - .../vendor/rxjs/add/observable/concat.js.map | 1 - .../vendor/rxjs/add/observable/defer.js | 5 - .../vendor/rxjs/add/observable/defer.js.map | 1 - .../vendor/rxjs/add/observable/dom/ajax.js | 5 - .../rxjs/add/observable/dom/ajax.js.map | 1 - .../rxjs/add/observable/dom/webSocket.js | 5 - .../rxjs/add/observable/dom/webSocket.js.map | 1 - .../vendor/rxjs/add/observable/empty.js | 5 - .../vendor/rxjs/add/observable/empty.js.map | 1 - .../vendor/rxjs/add/observable/forkJoin.js | 5 - .../rxjs/add/observable/forkJoin.js.map | 1 - .../vendor/rxjs/add/observable/from.js | 5 - .../vendor/rxjs/add/observable/from.js.map | 1 - .../vendor/rxjs/add/observable/fromEvent.js | 5 - .../rxjs/add/observable/fromEvent.js.map | 1 - .../rxjs/add/observable/fromEventPattern.js | 5 - .../add/observable/fromEventPattern.js.map | 1 - .../vendor/rxjs/add/observable/fromPromise.js | 5 - .../rxjs/add/observable/fromPromise.js.map | 1 - .../vendor/rxjs/add/observable/if.js | 5 - .../vendor/rxjs/add/observable/if.js.map | 1 - .../vendor/rxjs/add/observable/interval.js | 5 - .../rxjs/add/observable/interval.js.map | 1 - .../vendor/rxjs/add/observable/merge.js | 5 - .../vendor/rxjs/add/observable/merge.js.map | 1 - .../vendor/rxjs/add/observable/never.js | 5 - .../vendor/rxjs/add/observable/never.js.map | 1 - .../vendor/rxjs/add/observable/of.js | 5 - .../vendor/rxjs/add/observable/of.js.map | 1 - .../vendor/rxjs/add/observable/race.js | 5 - .../vendor/rxjs/add/observable/race.js.map | 1 - .../vendor/rxjs/add/observable/range.js | 5 - .../vendor/rxjs/add/observable/range.js.map | 1 - .../vendor/rxjs/add/observable/throw.js | 5 - .../vendor/rxjs/add/observable/throw.js.map | 1 - .../vendor/rxjs/add/observable/timer.js | 5 - .../vendor/rxjs/add/observable/timer.js.map | 1 - .../vendor/rxjs/add/observable/using.js | 5 - .../vendor/rxjs/add/observable/using.js.map | 1 - .../vendor/rxjs/add/observable/zip.js | 5 - .../vendor/rxjs/add/observable/zip.js.map | 1 - .../vendor/rxjs/add/operator/audit.js | 5 - .../vendor/rxjs/add/operator/audit.js.map | 1 - .../vendor/rxjs/add/operator/auditTime.js | 5 - .../vendor/rxjs/add/operator/auditTime.js.map | 1 - .../vendor/rxjs/add/operator/buffer.js | 5 - .../vendor/rxjs/add/operator/buffer.js.map | 1 - .../vendor/rxjs/add/operator/bufferCount.js | 5 - .../rxjs/add/operator/bufferCount.js.map | 1 - .../vendor/rxjs/add/operator/bufferTime.js | 5 - .../rxjs/add/operator/bufferTime.js.map | 1 - .../vendor/rxjs/add/operator/bufferToggle.js | 5 - .../rxjs/add/operator/bufferToggle.js.map | 1 - .../vendor/rxjs/add/operator/bufferWhen.js | 5 - .../rxjs/add/operator/bufferWhen.js.map | 1 - .../vendor/rxjs/add/operator/cache.js | 5 - .../vendor/rxjs/add/operator/cache.js.map | 1 - .../vendor/rxjs/add/operator/catch.js | 5 - .../vendor/rxjs/add/operator/catch.js.map | 1 - .../vendor/rxjs/add/operator/combineAll.js | 5 - .../rxjs/add/operator/combineAll.js.map | 1 - .../vendor/rxjs/add/operator/combineLatest.js | 5 - .../rxjs/add/operator/combineLatest.js.map | 1 - .../vendor/rxjs/add/operator/concat.js | 5 - .../vendor/rxjs/add/operator/concat.js.map | 1 - .../vendor/rxjs/add/operator/concatAll.js | 5 - .../vendor/rxjs/add/operator/concatAll.js.map | 1 - .../vendor/rxjs/add/operator/concatMap.js | 5 - .../vendor/rxjs/add/operator/concatMap.js.map | 1 - .../vendor/rxjs/add/operator/concatMapTo.js | 5 - .../rxjs/add/operator/concatMapTo.js.map | 1 - .../vendor/rxjs/add/operator/count.js | 5 - .../vendor/rxjs/add/operator/count.js.map | 1 - .../vendor/rxjs/add/operator/debounce.js | 5 - .../vendor/rxjs/add/operator/debounce.js.map | 1 - .../vendor/rxjs/add/operator/debounceTime.js | 5 - .../rxjs/add/operator/debounceTime.js.map | 1 - .../rxjs/add/operator/defaultIfEmpty.js | 5 - .../rxjs/add/operator/defaultIfEmpty.js.map | 1 - .../vendor/rxjs/add/operator/delay.js | 5 - .../vendor/rxjs/add/operator/delay.js.map | 1 - .../vendor/rxjs/add/operator/delayWhen.js | 5 - .../vendor/rxjs/add/operator/delayWhen.js.map | 1 - .../vendor/rxjs/add/operator/dematerialize.js | 5 - .../rxjs/add/operator/dematerialize.js.map | 1 - .../vendor/rxjs/add/operator/distinct.js | 5 - .../vendor/rxjs/add/operator/distinct.js.map | 1 - .../vendor/rxjs/add/operator/distinctKey.js | 5 - .../rxjs/add/operator/distinctKey.js.map | 1 - .../rxjs/add/operator/distinctUntilChanged.js | 5 - .../add/operator/distinctUntilChanged.js.map | 1 - .../add/operator/distinctUntilKeyChanged.js | 5 - .../operator/distinctUntilKeyChanged.js.map | 1 - .../vendor/rxjs/add/operator/do.js | 5 - .../vendor/rxjs/add/operator/do.js.map | 1 - .../vendor/rxjs/add/operator/elementAt.js | 5 - .../vendor/rxjs/add/operator/elementAt.js.map | 1 - .../vendor/rxjs/add/operator/every.js | 5 - .../vendor/rxjs/add/operator/every.js.map | 1 - .../vendor/rxjs/add/operator/exhaust.js | 5 - .../vendor/rxjs/add/operator/exhaust.js.map | 1 - .../vendor/rxjs/add/operator/exhaustMap.js | 5 - .../rxjs/add/operator/exhaustMap.js.map | 1 - .../vendor/rxjs/add/operator/expand.js | 5 - .../vendor/rxjs/add/operator/expand.js.map | 1 - .../vendor/rxjs/add/operator/filter.js | 5 - .../vendor/rxjs/add/operator/filter.js.map | 1 - .../vendor/rxjs/add/operator/finally.js | 5 - .../vendor/rxjs/add/operator/finally.js.map | 1 - .../vendor/rxjs/add/operator/find.js | 5 - .../vendor/rxjs/add/operator/find.js.map | 1 - .../vendor/rxjs/add/operator/findIndex.js | 5 - .../vendor/rxjs/add/operator/findIndex.js.map | 1 - .../vendor/rxjs/add/operator/first.js | 5 - .../vendor/rxjs/add/operator/first.js.map | 1 - .../vendor/rxjs/add/operator/groupBy.js | 5 - .../vendor/rxjs/add/operator/groupBy.js.map | 1 - .../rxjs/add/operator/ignoreElements.js | 5 - .../rxjs/add/operator/ignoreElements.js.map | 1 - .../vendor/rxjs/add/operator/isEmpty.js | 5 - .../vendor/rxjs/add/operator/isEmpty.js.map | 1 - .../vendor/rxjs/add/operator/last.js | 5 - .../vendor/rxjs/add/operator/last.js.map | 1 - .../vendor/rxjs/add/operator/let.js | 6 - .../vendor/rxjs/add/operator/let.js.map | 1 - .../vendor/rxjs/add/operator/map.js | 5 - .../vendor/rxjs/add/operator/map.js.map | 1 - .../vendor/rxjs/add/operator/mapTo.js | 5 - .../vendor/rxjs/add/operator/mapTo.js.map | 1 - .../vendor/rxjs/add/operator/materialize.js | 5 - .../rxjs/add/operator/materialize.js.map | 1 - .../vendor/rxjs/add/operator/max.js | 5 - .../vendor/rxjs/add/operator/max.js.map | 1 - .../vendor/rxjs/add/operator/merge.js | 5 - .../vendor/rxjs/add/operator/merge.js.map | 1 - .../vendor/rxjs/add/operator/mergeAll.js | 5 - .../vendor/rxjs/add/operator/mergeAll.js.map | 1 - .../vendor/rxjs/add/operator/mergeMap.js | 6 - .../vendor/rxjs/add/operator/mergeMap.js.map | 1 - .../vendor/rxjs/add/operator/mergeMapTo.js | 6 - .../rxjs/add/operator/mergeMapTo.js.map | 1 - .../vendor/rxjs/add/operator/mergeScan.js | 5 - .../vendor/rxjs/add/operator/mergeScan.js.map | 1 - .../vendor/rxjs/add/operator/min.js | 5 - .../vendor/rxjs/add/operator/min.js.map | 1 - .../vendor/rxjs/add/operator/multicast.js | 5 - .../vendor/rxjs/add/operator/multicast.js.map | 1 - .../vendor/rxjs/add/operator/observeOn.js | 5 - .../vendor/rxjs/add/operator/observeOn.js.map | 1 - .../vendor/rxjs/add/operator/pairwise.js | 5 - .../vendor/rxjs/add/operator/pairwise.js.map | 1 - .../vendor/rxjs/add/operator/partition.js | 5 - .../vendor/rxjs/add/operator/partition.js.map | 1 - .../vendor/rxjs/add/operator/pluck.js | 5 - .../vendor/rxjs/add/operator/pluck.js.map | 1 - .../vendor/rxjs/add/operator/publish.js | 5 - .../vendor/rxjs/add/operator/publish.js.map | 1 - .../rxjs/add/operator/publishBehavior.js | 5 - .../rxjs/add/operator/publishBehavior.js.map | 1 - .../vendor/rxjs/add/operator/publishLast.js | 5 - .../rxjs/add/operator/publishLast.js.map | 1 - .../vendor/rxjs/add/operator/publishReplay.js | 5 - .../rxjs/add/operator/publishReplay.js.map | 1 - .../vendor/rxjs/add/operator/race.js | 5 - .../vendor/rxjs/add/operator/race.js.map | 1 - .../vendor/rxjs/add/operator/reduce.js | 5 - .../vendor/rxjs/add/operator/reduce.js.map | 1 - .../vendor/rxjs/add/operator/repeat.js | 5 - .../vendor/rxjs/add/operator/repeat.js.map | 1 - .../vendor/rxjs/add/operator/retry.js | 5 - .../vendor/rxjs/add/operator/retry.js.map | 1 - .../vendor/rxjs/add/operator/retryWhen.js | 5 - .../vendor/rxjs/add/operator/retryWhen.js.map | 1 - .../vendor/rxjs/add/operator/sample.js | 5 - .../vendor/rxjs/add/operator/sample.js.map | 1 - .../vendor/rxjs/add/operator/sampleTime.js | 5 - .../rxjs/add/operator/sampleTime.js.map | 1 - .../vendor/rxjs/add/operator/scan.js | 5 - .../vendor/rxjs/add/operator/scan.js.map | 1 - .../vendor/rxjs/add/operator/share.js | 5 - .../vendor/rxjs/add/operator/share.js.map | 1 - .../vendor/rxjs/add/operator/single.js | 5 - .../vendor/rxjs/add/operator/single.js.map | 1 - .../vendor/rxjs/add/operator/skip.js | 5 - .../vendor/rxjs/add/operator/skip.js.map | 1 - .../vendor/rxjs/add/operator/skipUntil.js | 5 - .../vendor/rxjs/add/operator/skipUntil.js.map | 1 - .../vendor/rxjs/add/operator/skipWhile.js | 5 - .../vendor/rxjs/add/operator/skipWhile.js.map | 1 - .../vendor/rxjs/add/operator/startWith.js | 5 - .../vendor/rxjs/add/operator/startWith.js.map | 1 - .../vendor/rxjs/add/operator/subscribeOn.js | 5 - .../rxjs/add/operator/subscribeOn.js.map | 1 - .../vendor/rxjs/add/operator/switch.js | 5 - .../vendor/rxjs/add/operator/switch.js.map | 1 - .../vendor/rxjs/add/operator/switchMap.js | 5 - .../vendor/rxjs/add/operator/switchMap.js.map | 1 - .../vendor/rxjs/add/operator/switchMapTo.js | 5 - .../rxjs/add/operator/switchMapTo.js.map | 1 - .../vendor/rxjs/add/operator/take.js | 5 - .../vendor/rxjs/add/operator/take.js.map | 1 - .../vendor/rxjs/add/operator/takeLast.js | 5 - .../vendor/rxjs/add/operator/takeLast.js.map | 1 - .../vendor/rxjs/add/operator/takeUntil.js | 5 - .../vendor/rxjs/add/operator/takeUntil.js.map | 1 - .../vendor/rxjs/add/operator/takeWhile.js | 5 - .../vendor/rxjs/add/operator/takeWhile.js.map | 1 - .../vendor/rxjs/add/operator/throttle.js | 5 - .../vendor/rxjs/add/operator/throttle.js.map | 1 - .../vendor/rxjs/add/operator/throttleTime.js | 5 - .../rxjs/add/operator/throttleTime.js.map | 1 - .../vendor/rxjs/add/operator/timeInterval.js | 5 - .../rxjs/add/operator/timeInterval.js.map | 1 - .../vendor/rxjs/add/operator/timeout.js | 5 - .../vendor/rxjs/add/operator/timeout.js.map | 1 - .../vendor/rxjs/add/operator/timeoutWith.js | 5 - .../rxjs/add/operator/timeoutWith.js.map | 1 - .../vendor/rxjs/add/operator/timestamp.js | 5 - .../vendor/rxjs/add/operator/timestamp.js.map | 1 - .../vendor/rxjs/add/operator/toArray.js | 5 - .../vendor/rxjs/add/operator/toArray.js.map | 1 - .../vendor/rxjs/add/operator/toPromise.js | 5 - .../vendor/rxjs/add/operator/toPromise.js.map | 1 - .../vendor/rxjs/add/operator/window.js | 5 - .../vendor/rxjs/add/operator/window.js.map | 1 - .../vendor/rxjs/add/operator/windowCount.js | 5 - .../rxjs/add/operator/windowCount.js.map | 1 - .../vendor/rxjs/add/operator/windowTime.js | 5 - .../rxjs/add/operator/windowTime.js.map | 1 - .../vendor/rxjs/add/operator/windowToggle.js | 5 - .../rxjs/add/operator/windowToggle.js.map | 1 - .../vendor/rxjs/add/operator/windowWhen.js | 5 - .../rxjs/add/operator/windowWhen.js.map | 1 - .../rxjs/add/operator/withLatestFrom.js | 5 - .../rxjs/add/operator/withLatestFrom.js.map | 1 - .../vendor/rxjs/add/operator/zip.js | 5 - .../vendor/rxjs/add/operator/zip.js.map | 1 - .../vendor/rxjs/add/operator/zipAll.js | 5 - .../vendor/rxjs/add/operator/zipAll.js.map | 1 - .../vendor/rxjs/bundles/Rx.js | 11678 ----------- .../vendor/rxjs/bundles/Rx.min.js | 12 - .../vendor/rxjs/bundles/Rx.min.js.map | 1 - .../vendor/rxjs/bundles/Rx.umd.js | 12704 ------------ .../vendor/rxjs/bundles/Rx.umd.min.js | 351 - .../vendor/rxjs/bundles/Rx.umd.min.js.map | 8 - .../rxjs/observable/ArrayLikeObservable.js | 75 - .../observable/ArrayLikeObservable.js.map | 1 - .../vendor/rxjs/observable/ArrayObservable.js | 122 - .../rxjs/observable/ArrayObservable.js.map | 1 - .../observable/BoundCallbackObservable.js | 142 - .../observable/BoundCallbackObservable.js.map | 1 - .../observable/BoundNodeCallbackObservable.js | 146 - .../BoundNodeCallbackObservable.js.map | 1 - .../rxjs/observable/ConnectableObservable.js | 148 - .../observable/ConnectableObservable.js.map | 1 - .../vendor/rxjs/observable/DeferObservable.js | 93 - .../rxjs/observable/DeferObservable.js.map | 1 - .../vendor/rxjs/observable/EmptyObservable.js | 75 - .../rxjs/observable/EmptyObservable.js.map | 1 - .../vendor/rxjs/observable/ErrorObservable.js | 82 - .../rxjs/observable/ErrorObservable.js.map | 1 - .../rxjs/observable/ForkJoinObservable.js | 111 - .../rxjs/observable/ForkJoinObservable.js.map | 1 - .../rxjs/observable/FromEventObservable.js | 94 - .../observable/FromEventObservable.js.map | 1 - .../observable/FromEventPatternObservable.js | 61 - .../FromEventPatternObservable.js.map | 1 - .../vendor/rxjs/observable/FromObservable.js | 77 - .../rxjs/observable/FromObservable.js.map | 1 - .../vendor/rxjs/observable/IfObservable.js | 61 - .../rxjs/observable/IfObservable.js.map | 1 - .../rxjs/observable/IntervalObservable.js | 88 - .../rxjs/observable/IntervalObservable.js.map | 1 - .../rxjs/observable/IteratorObservable.js | 193 - .../rxjs/observable/IteratorObservable.js.map | 1 - .../vendor/rxjs/observable/NeverObservable.js | 59 - .../rxjs/observable/NeverObservable.js.map | 1 - .../rxjs/observable/PromiseObservable.js | 105 - .../rxjs/observable/PromiseObservable.js.map | 1 - .../vendor/rxjs/observable/RangeObservable.js | 96 - .../rxjs/observable/RangeObservable.js.map | 1 - .../rxjs/observable/ScalarObservable.js | 55 - .../rxjs/observable/ScalarObservable.js.map | 1 - .../rxjs/observable/SubscribeOnObservable.js | 51 - .../observable/SubscribeOnObservable.js.map | 1 - .../vendor/rxjs/observable/TimerObservable.js | 107 - .../rxjs/observable/TimerObservable.js.map | 1 - .../vendor/rxjs/observable/UsingObservable.js | 61 - .../rxjs/observable/UsingObservable.js.map | 1 - .../vendor/rxjs/observable/bindCallback.js | 4 - .../rxjs/observable/bindCallback.js.map | 1 - .../rxjs/observable/bindNodeCallback.js | 4 - .../rxjs/observable/bindNodeCallback.js.map | 1 - .../vendor/rxjs/observable/concat.js | 4 - .../vendor/rxjs/observable/concat.js.map | 1 - .../vendor/rxjs/observable/defer.js | 4 - .../vendor/rxjs/observable/defer.js.map | 1 - .../rxjs/observable/dom/AjaxObservable.js | 379 - .../rxjs/observable/dom/AjaxObservable.js.map | 1 - .../rxjs/observable/dom/WebSocketSubject.js | 187 - .../observable/dom/WebSocketSubject.js.map | 1 - .../vendor/rxjs/observable/dom/ajax.js | 4 - .../vendor/rxjs/observable/dom/ajax.js.map | 1 - .../vendor/rxjs/observable/dom/webSocket.js | 4 - .../rxjs/observable/dom/webSocket.js.map | 1 - .../vendor/rxjs/observable/empty.js | 4 - .../vendor/rxjs/observable/empty.js.map | 1 - .../vendor/rxjs/observable/forkJoin.js | 4 - .../vendor/rxjs/observable/forkJoin.js.map | 1 - .../vendor/rxjs/observable/from.js | 4 - .../vendor/rxjs/observable/from.js.map | 1 - .../vendor/rxjs/observable/fromEvent.js | 4 - .../vendor/rxjs/observable/fromEvent.js.map | 1 - .../rxjs/observable/fromEventPattern.js | 4 - .../rxjs/observable/fromEventPattern.js.map | 1 - .../vendor/rxjs/observable/fromPromise.js | 4 - .../vendor/rxjs/observable/fromPromise.js.map | 1 - .../vendor/rxjs/observable/if.js | 4 - .../vendor/rxjs/observable/if.js.map | 1 - .../vendor/rxjs/observable/interval.js | 4 - .../vendor/rxjs/observable/interval.js.map | 1 - .../vendor/rxjs/observable/merge.js | 4 - .../vendor/rxjs/observable/merge.js.map | 1 - .../vendor/rxjs/observable/never.js | 4 - .../vendor/rxjs/observable/never.js.map | 1 - .../vendor/rxjs/observable/of.js | 4 - .../vendor/rxjs/observable/of.js.map | 1 - .../vendor/rxjs/observable/range.js | 4 - .../vendor/rxjs/observable/range.js.map | 1 - .../vendor/rxjs/observable/throw.js | 4 - .../vendor/rxjs/observable/throw.js.map | 1 - .../vendor/rxjs/observable/timer.js | 4 - .../vendor/rxjs/observable/timer.js.map | 1 - .../vendor/rxjs/observable/using.js | 4 - .../vendor/rxjs/observable/using.js.map | 1 - .../vendor/rxjs/observable/zip.js | 4 - .../vendor/rxjs/observable/zip.js.map | 1 - .../vendor/rxjs/operator/audit.js | 76 - .../vendor/rxjs/operator/audit.js.map | 1 - .../vendor/rxjs/operator/auditTime.js | 69 - .../vendor/rxjs/operator/auditTime.js.map | 1 - .../vendor/rxjs/operator/buffer.js | 76 - .../vendor/rxjs/operator/buffer.js.map | 1 - .../vendor/rxjs/operator/bufferCount.js | 113 - .../vendor/rxjs/operator/bufferCount.js.map | 1 - .../vendor/rxjs/operator/bufferTime.js | 148 - .../vendor/rxjs/operator/bufferTime.js.map | 1 - .../vendor/rxjs/operator/bufferToggle.js | 152 - .../vendor/rxjs/operator/bufferToggle.js.map | 1 - .../vendor/rxjs/operator/bufferWhen.js | 122 - .../vendor/rxjs/operator/bufferWhen.js.map | 1 - .../vendor/rxjs/operator/cache.js | 17 - .../vendor/rxjs/operator/cache.js.map | 1 - .../vendor/rxjs/operator/catch.js | 67 - .../vendor/rxjs/operator/catch.js.map | 1 - .../vendor/rxjs/operator/combineAll.js | 47 - .../vendor/rxjs/operator/combineAll.js.map | 1 - .../vendor/rxjs/operator/combineLatest.js | 185 - .../vendor/rxjs/operator/combineLatest.js.map | 1 - .../vendor/rxjs/operator/concat.js | 108 - .../vendor/rxjs/operator/concat.js.map | 1 - .../vendor/rxjs/operator/concatAll.js | 49 - .../vendor/rxjs/operator/concatAll.js.map | 1 - .../vendor/rxjs/operator/concatMap.js | 63 - .../vendor/rxjs/operator/concatMap.js.map | 1 - .../vendor/rxjs/operator/concatMapTo.js | 57 - .../vendor/rxjs/operator/concatMapTo.js.map | 1 - .../vendor/rxjs/operator/count.js | 108 - .../vendor/rxjs/operator/count.js.map | 1 - .../vendor/rxjs/operator/debounce.js | 97 - .../vendor/rxjs/operator/debounce.js.map | 1 - .../vendor/rxjs/operator/debounceTime.js | 84 - .../vendor/rxjs/operator/debounceTime.js.map | 1 - .../vendor/rxjs/operator/defaultIfEmpty.js | 53 - .../rxjs/operator/defaultIfEmpty.js.map | 1 - .../vendor/rxjs/operator/delay.js | 135 - .../vendor/rxjs/operator/delay.js.map | 1 - .../vendor/rxjs/operator/delayWhen.js | 154 - .../vendor/rxjs/operator/delayWhen.js.map | 1 - .../vendor/rxjs/operator/dematerialize.js | 44 - .../vendor/rxjs/operator/dematerialize.js.map | 1 - .../vendor/rxjs/operator/distinct.js | 83 - .../vendor/rxjs/operator/distinct.js.map | 1 - .../vendor/rxjs/operator/distinctKey.js | 26 - .../vendor/rxjs/operator/distinctKey.js.map | 1 - .../rxjs/operator/distinctUntilChanged.js | 77 - .../rxjs/operator/distinctUntilChanged.js.map | 1 - .../rxjs/operator/distinctUntilKeyChanged.js | 23 - .../operator/distinctUntilKeyChanged.js.map | 1 - .../vendor/rxjs/operator/do.js | 112 - .../vendor/rxjs/operator/do.js.map | 1 - .../vendor/rxjs/operator/elementAt.js | 70 - .../vendor/rxjs/operator/elementAt.js.map | 1 - .../vendor/rxjs/operator/every.js | 69 - .../vendor/rxjs/operator/every.js.map | 1 - .../vendor/rxjs/operator/exhaust.js | 90 - .../vendor/rxjs/operator/exhaust.js.map | 1 - .../vendor/rxjs/operator/exhaustMap.js | 137 - .../vendor/rxjs/operator/exhaustMap.js.map | 1 - .../vendor/rxjs/operator/expand.js | 115 - .../vendor/rxjs/operator/expand.js.map | 1 - .../vendor/rxjs/operator/filter.js | 93 - .../vendor/rxjs/operator/filter.js.map | 1 - .../vendor/rxjs/operator/finally.js | 43 - .../vendor/rxjs/operator/finally.js.map | 1 - .../vendor/rxjs/operator/find.js | 100 - .../vendor/rxjs/operator/find.js.map | 1 - .../vendor/rxjs/operator/findIndex.js | 41 - .../vendor/rxjs/operator/findIndex.js.map | 1 - .../vendor/rxjs/operator/first.js | 148 - .../vendor/rxjs/operator/first.js.map | 1 - .../vendor/rxjs/operator/groupBy.js | 250 - .../vendor/rxjs/operator/groupBy.js.map | 1 - .../vendor/rxjs/operator/ignoreElements.js | 47 - .../rxjs/operator/ignoreElements.js.map | 1 - .../vendor/rxjs/operator/isEmpty.js | 52 - .../vendor/rxjs/operator/isEmpty.js.map | 1 - .../vendor/rxjs/operator/last.js | 118 - .../vendor/rxjs/operator/last.js.map | 1 - .../vendor/rxjs/operator/let.js | 12 - .../vendor/rxjs/operator/let.js.map | 1 - .../vendor/rxjs/operator/map.js | 86 - .../vendor/rxjs/operator/map.js.map | 1 - .../vendor/rxjs/operator/mapTo.js | 63 - .../vendor/rxjs/operator/mapTo.js.map | 1 - .../vendor/rxjs/operator/materialize.js | 61 - .../vendor/rxjs/operator/materialize.js.map | 1 - .../vendor/rxjs/operator/max.js | 22 - .../vendor/rxjs/operator/max.js.map | 1 - .../vendor/rxjs/operator/merge.js | 130 - .../vendor/rxjs/operator/merge.js.map | 1 - .../vendor/rxjs/operator/mergeAll.js | 111 - .../vendor/rxjs/operator/mergeAll.js.map | 1 - .../vendor/rxjs/operator/mergeMap.js | 161 - .../vendor/rxjs/operator/mergeMap.js.map | 1 - .../vendor/rxjs/operator/mergeMapTo.js | 154 - .../vendor/rxjs/operator/mergeMapTo.js.map | 1 - .../vendor/rxjs/operator/mergeScan.js | 106 - .../vendor/rxjs/operator/mergeScan.js.map | 1 - .../vendor/rxjs/operator/min.js | 21 - .../vendor/rxjs/operator/min.js.map | 1 - .../vendor/rxjs/operator/multicast.js | 32 - .../vendor/rxjs/operator/multicast.js.map | 1 - .../vendor/rxjs/operator/observeOn.js | 75 - .../vendor/rxjs/operator/observeOn.js.map | 1 - .../vendor/rxjs/operator/pairwise.js | 53 - .../vendor/rxjs/operator/pairwise.js.map | 1 - .../vendor/rxjs/operator/partition.js | 18 - .../vendor/rxjs/operator/partition.js.map | 1 - .../vendor/rxjs/operator/pluck.js | 58 - .../vendor/rxjs/operator/pluck.js.map | 1 - .../vendor/rxjs/operator/publish.js | 18 - .../vendor/rxjs/operator/publish.js.map | 1 - .../vendor/rxjs/operator/publishBehavior.js | 14 - .../rxjs/operator/publishBehavior.js.map | 1 - .../vendor/rxjs/operator/publishLast.js | 13 - .../vendor/rxjs/operator/publishLast.js.map | 1 - .../vendor/rxjs/operator/publishReplay.js | 18 - .../vendor/rxjs/operator/publishReplay.js.map | 1 - .../vendor/rxjs/operator/race.js | 109 - .../vendor/rxjs/operator/race.js.map | 1 - .../vendor/rxjs/operator/reduce.js | 84 - .../vendor/rxjs/operator/reduce.js.map | 1 - .../vendor/rxjs/operator/repeat.js | 75 - .../vendor/rxjs/operator/repeat.js.map | 1 - .../vendor/rxjs/operator/retry.js | 69 - .../vendor/rxjs/operator/retry.js.map | 1 - .../vendor/rxjs/operator/retryWhen.js | 106 - .../vendor/rxjs/operator/retryWhen.js.map | 1 - .../vendor/rxjs/operator/sample.js | 65 - .../vendor/rxjs/operator/sample.js.map | 1 - .../vendor/rxjs/operator/sampleTime.js | 62 - .../vendor/rxjs/operator/sampleTime.js.map | 1 - .../vendor/rxjs/operator/scan.js | 107 - .../vendor/rxjs/operator/scan.js.map | 1 - .../vendor/rxjs/operator/share.js | 24 - .../vendor/rxjs/operator/share.js.map | 1 - .../vendor/rxjs/operator/single.js | 95 - .../vendor/rxjs/operator/single.js.map | 1 - .../vendor/rxjs/operator/skip.js | 51 - .../vendor/rxjs/operator/skip.js.map | 1 - .../vendor/rxjs/operator/skipUntil.js | 71 - .../vendor/rxjs/operator/skipUntil.js.map | 1 - .../vendor/rxjs/operator/skipWhile.js | 66 - .../vendor/rxjs/operator/skipWhile.js.map | 1 - .../vendor/rxjs/operator/startWith.js | 43 - .../vendor/rxjs/operator/startWith.js.map | 1 - .../vendor/rxjs/operator/subscribeOn.js | 19 - .../vendor/rxjs/operator/subscribeOn.js.map | 1 - .../vendor/rxjs/operator/switch.js | 108 - .../vendor/rxjs/operator/switch.js.map | 1 - .../vendor/rxjs/operator/switchMap.js | 139 - .../vendor/rxjs/operator/switchMap.js.map | 1 - .../vendor/rxjs/operator/switchMapTo.js | 126 - .../vendor/rxjs/operator/switchMapTo.js.map | 1 - .../vendor/rxjs/operator/take.js | 63 - .../vendor/rxjs/operator/take.js.map | 1 - .../vendor/rxjs/operator/takeLast.js | 79 - .../vendor/rxjs/operator/takeLast.js.map | 1 - .../vendor/rxjs/operator/takeUntil.js | 48 - .../vendor/rxjs/operator/takeUntil.js.map | 1 - .../vendor/rxjs/operator/takeWhile.js | 62 - .../vendor/rxjs/operator/takeWhile.js.map | 1 - .../vendor/rxjs/operator/throttle.js | 76 - .../vendor/rxjs/operator/throttle.js.map | 1 - .../vendor/rxjs/operator/throttleTime.js | 63 - .../vendor/rxjs/operator/throttleTime.js.map | 1 - .../vendor/rxjs/operator/timeInterval.js | 59 - .../vendor/rxjs/operator/timeInterval.js.map | 1 - .../vendor/rxjs/operator/timeout.js | 102 - .../vendor/rxjs/operator/timeout.js.map | 1 - .../vendor/rxjs/operator/timeoutWith.js | 110 - .../vendor/rxjs/operator/timeoutWith.js.map | 1 - .../vendor/rxjs/operator/timestamp.js | 50 - .../vendor/rxjs/operator/timestamp.js.map | 1 - .../vendor/rxjs/operator/toArray.js | 45 - .../vendor/rxjs/operator/toArray.js.map | 1 - .../vendor/rxjs/operator/toPromise.js | 28 - .../vendor/rxjs/operator/toPromise.js.map | 1 - .../vendor/rxjs/operator/window.js | 105 - .../vendor/rxjs/operator/window.js.map | 1 - .../vendor/rxjs/operator/windowCount.js | 126 - .../vendor/rxjs/operator/windowCount.js.map | 1 - .../vendor/rxjs/operator/windowTime.js | 170 - .../vendor/rxjs/operator/windowTime.js.map | 1 - .../vendor/rxjs/operator/windowToggle.js | 180 - .../vendor/rxjs/operator/windowToggle.js.map | 1 - .../vendor/rxjs/operator/windowWhen.js | 128 - .../vendor/rxjs/operator/windowWhen.js.map | 1 - .../vendor/rxjs/operator/withLatestFrom.js | 130 - .../rxjs/operator/withLatestFrom.js.map | 1 - .../vendor/rxjs/operator/zip.js | 254 - .../vendor/rxjs/operator/zip.js.map | 1 - .../vendor/rxjs/operator/zipAll.js | 13 - .../vendor/rxjs/operator/zipAll.js.map | 1 - .../vendor/rxjs/scheduler/Action.js | 2 - .../vendor/rxjs/scheduler/Action.js.map | 1 - .../rxjs/scheduler/AnimationFrameAction.js | 51 - .../scheduler/AnimationFrameAction.js.map | 1 - .../rxjs/scheduler/AnimationFrameScheduler.js | 20 - .../scheduler/AnimationFrameScheduler.js.map | 1 - .../vendor/rxjs/scheduler/AsapAction.js | 51 - .../vendor/rxjs/scheduler/AsapAction.js.map | 1 - .../vendor/rxjs/scheduler/AsapScheduler.js | 20 - .../rxjs/scheduler/AsapScheduler.js.map | 1 - .../vendor/rxjs/scheduler/AsyncScheduler.js | 20 - .../rxjs/scheduler/AsyncScheduler.js.map | 1 - .../vendor/rxjs/scheduler/FutureAction.js | 135 - .../vendor/rxjs/scheduler/FutureAction.js.map | 1 - .../vendor/rxjs/scheduler/QueueAction.js | 33 - .../vendor/rxjs/scheduler/QueueAction.js.map | 1 - .../vendor/rxjs/scheduler/QueueScheduler.js | 44 - .../rxjs/scheduler/QueueScheduler.js.map | 1 - .../rxjs/scheduler/VirtualTimeScheduler.js | 129 - .../scheduler/VirtualTimeScheduler.js.map | 1 - .../vendor/rxjs/scheduler/animationFrame.js | 4 - .../rxjs/scheduler/animationFrame.js.map | 1 - .../vendor/rxjs/scheduler/asap.js | 4 - .../vendor/rxjs/scheduler/asap.js.map | 1 - .../vendor/rxjs/scheduler/async.js | 4 - .../vendor/rxjs/scheduler/async.js.map | 1 - .../vendor/rxjs/scheduler/queue.js | 4 - .../vendor/rxjs/scheduler/queue.js.map | 1 - .../vendor/rxjs/src/Rx.global.js | 5 - .../vendor/rxjs/symbol/iterator.js | 32 - .../vendor/rxjs/symbol/iterator.js.map | 1 - .../vendor/rxjs/symbol/observable.js | 21 - .../vendor/rxjs/symbol/observable.js.map | 1 - .../vendor/rxjs/symbol/rxSubscriber.js | 6 - .../vendor/rxjs/symbol/rxSubscriber.js.map | 1 - .../vendor/rxjs/testing/ColdObservable.js | 46 - .../vendor/rxjs/testing/ColdObservable.js.map | 1 - .../vendor/rxjs/testing/HotObservable.js | 48 - .../vendor/rxjs/testing/HotObservable.js.map | 1 - .../vendor/rxjs/testing/SubscriptionLog.js | 11 - .../rxjs/testing/SubscriptionLog.js.map | 1 - .../rxjs/testing/SubscriptionLoggable.js | 19 - .../rxjs/testing/SubscriptionLoggable.js.map | 1 - .../vendor/rxjs/testing/TestMessage.js | 2 - .../vendor/rxjs/testing/TestMessage.js.map | 1 - .../vendor/rxjs/testing/TestScheduler.js | 222 - .../vendor/rxjs/testing/TestScheduler.js.map | 1 - .../vendor/rxjs/util/AnimationFrame.js | 34 - .../vendor/rxjs/util/AnimationFrame.js.map | 1 - .../rxjs/util/ArgumentOutOfRangeError.js | 26 - .../rxjs/util/ArgumentOutOfRangeError.js.map | 1 - .../vendor/rxjs/util/EmptyError.js | 26 - .../vendor/rxjs/util/EmptyError.js.map | 1 - .../vendor/rxjs/util/FastMap.js | 31 - .../vendor/rxjs/util/FastMap.js.map | 1 - .../vendor/rxjs/util/Immediate.js | 209 - .../vendor/rxjs/util/Immediate.js.map | 1 - .../simmvaluationweb/vendor/rxjs/util/Map.js | 5 - .../vendor/rxjs/util/Map.js.map | 1 - .../vendor/rxjs/util/MapPolyfill.js | 47 - .../vendor/rxjs/util/MapPolyfill.js.map | 1 - .../rxjs/util/ObjectUnsubscribedError.js | 25 - .../rxjs/util/ObjectUnsubscribedError.js.map | 1 - .../vendor/rxjs/util/UnsubscriptionError.js | 22 - .../rxjs/util/UnsubscriptionError.js.map | 1 - .../vendor/rxjs/util/applyMixins.js | 13 - .../vendor/rxjs/util/applyMixins.js.map | 1 - .../vendor/rxjs/util/assign.js | 31 - .../vendor/rxjs/util/assign.js.map | 1 - .../vendor/rxjs/util/errorObject.js | 4 - .../vendor/rxjs/util/errorObject.js.map | 1 - .../vendor/rxjs/util/isArray.js | 3 - .../vendor/rxjs/util/isArray.js.map | 1 - .../vendor/rxjs/util/isDate.js | 6 - .../vendor/rxjs/util/isDate.js.map | 1 - .../vendor/rxjs/util/isFunction.js | 6 - .../vendor/rxjs/util/isFunction.js.map | 1 - .../vendor/rxjs/util/isNumeric.js | 12 - .../vendor/rxjs/util/isNumeric.js.map | 1 - .../vendor/rxjs/util/isObject.js | 6 - .../vendor/rxjs/util/isObject.js.map | 1 - .../vendor/rxjs/util/isPromise.js | 6 - .../vendor/rxjs/util/isPromise.js.map | 1 - .../vendor/rxjs/util/isScheduler.js | 6 - .../vendor/rxjs/util/isScheduler.js.map | 1 - .../simmvaluationweb/vendor/rxjs/util/noop.js | 5 - .../vendor/rxjs/util/noop.js.map | 1 - .../simmvaluationweb/vendor/rxjs/util/not.js | 11 - .../vendor/rxjs/util/not.js.map | 1 - .../simmvaluationweb/vendor/rxjs/util/root.js | 18 - .../vendor/rxjs/util/root.js.map | 1 - .../vendor/rxjs/util/subscribeToResult.js | 71 - .../vendor/rxjs/util/subscribeToResult.js.map | 1 - .../vendor/rxjs/util/throwError.js | 4 - .../vendor/rxjs/util/throwError.js.map | 1 - .../vendor/rxjs/util/toSubscriber.js | 16 - .../vendor/rxjs/util/toSubscriber.js.map | 1 - .../vendor/rxjs/util/tryCatch.js | 19 - .../vendor/rxjs/util/tryCatch.js.map | 1 - .../vendor/systemjs/dist/system-polyfills.js | 5 - .../vendor/systemjs/dist/system.src.js | 5035 ----- .../vendor/underscore/underscore.js | 1548 -- .../vendor/zone.js/dist/async-test.js | 118 - .../vendor/zone.js/dist/fake-async-test.js | 283 - .../vendor/zone.js/dist/jasmine-patch.js | 78 - .../vendor/zone.js/dist/jasmine-patch.min.js | 1 - .../zone.js/dist/long-stack-trace-zone.js | 168 - .../zone.js/dist/long-stack-trace-zone.min.js | 1 - .../vendor/zone.js/dist/sync-test.js | 73 - .../vendor/zone.js/dist/wtf.js | 159 - .../vendor/zone.js/dist/wtf.min.js | 1 - .../vendor/zone.js/dist/zone-node.js | 4948 ----- .../vendor/zone.js/dist/zone.js | 1315 -- .../vendor/zone.js/dist/zone.min.js | 1 - .../src/main/web/.editorconfig | 14 - .../src/main/web/.gitignore | 33 - .../src/main/web/.jsbeautifyrc | 17 - .../src/main/web/Dockerfile | 12 - .../src/main/web/README.md | 48 - .../src/main/web/angular-cli-build.js | 34 - .../src/main/web/angular-cli.json | 32 - .../src/main/web/config/environment.dev.ts | 4 - .../src/main/web/config/environment.prod.ts | 4 - .../src/main/web/e2e/app.e2e-spec.ts | 14 - .../src/main/web/e2e/app.po.ts | 9 - .../src/main/web/e2e/tsconfig.json | 17 - .../src/main/web/e2e/typings.d.ts | 1 - .../src/main/web/package.json | 55 - .../src/main/web/public/.npmignore | 0 .../vega/bank-c/portfolio/history/aggregated | 501 - .../api/vega/bank-c/portfolio/valuations | 3 - .../main/web/public/api/vega/bank-c/trades | 251 - .../main/web/public/api/vega/business-date | 3 - .../vega/intesa/portfolio/history/aggregated | 1000 - .../api/vega/intesa/portfolio/valuations | 90 - .../main/web/public/api/vega/intesa/trades | 251 - .../src/main/web/public/api/vega/whoami | 14 - .../web/public/assets/images/checkbox.png | Bin 16080 -> 0 bytes .../public/assets/images/opengamma-logo.png | Bin 49212 -> 0 bytes .../main/web/public/assets/images/r3logo.png | Bin 2310 -> 0 bytes .../src/main/web/public/libs/highstock.js | 7553 -------- .../src/main/web/public/libs/jquery.min.js | 1636 -- .../src/main/web/public/libs/spinners.css | 51 - .../src/main/web/src/app/Deal.ts | 125 - .../src/main/web/src/app/app.component.css | 37 - .../src/main/web/src/app/app.component.html | 50 - .../main/web/src/app/app.component.spec.ts | 15 - .../src/main/web/src/app/app.component.ts | 66 - .../src/main/web/src/app/app.routes.ts | 19 - .../create-trade/create-trade.component.css | 19 - .../create-trade/create-trade.component.html | 53 - .../create-trade.component.spec.ts | 13 - .../create-trade/create-trade.component.ts | 61 - .../main/web/src/app/create-trade/index.ts | 1 - .../web/src/app/create-trade/shared/index.ts | 0 .../src/main/web/src/app/environment.ts | 7 - .../web/src/app/http-wrapper.service.spec.ts | 16 - .../main/web/src/app/http-wrapper.service.ts | 140 - .../src/main/web/src/app/index.ts | 2 - .../src/main/web/src/app/irs.service.spec.ts | 16 - .../src/main/web/src/app/irs.service.ts | 25 - .../src/main/web/src/app/model/CommonModel.ts | 26 - .../main/web/src/app/model/FixedLegModel.ts | 17 - .../web/src/app/model/FloatingLegModel.ts | 28 - .../src/main/web/src/app/node.service.spec.ts | 16 - .../src/main/web/src/app/node.service.ts | 38 - .../src/main/web/src/app/portfolio/index.ts | 1 - .../src/app/portfolio/portfolio.component.css | 1 - .../app/portfolio/portfolio.component.html | 95 - .../app/portfolio/portfolio.component.spec.ts | 6 - .../src/app/portfolio/portfolio.component.ts | 503 - .../src/main/web/src/app/shared/index.ts | 0 .../src/main/web/src/app/valuations/index.ts | 1 - .../app/valuations/valuations.component.css | 17 - .../app/valuations/valuations.component.html | 336 - .../valuations/valuations.component.spec.ts | 11 - .../app/valuations/valuations.component.ts | 107 - .../src/main/web/src/app/view-trade/index.ts | 1 - .../web/src/app/view-trade/shared/index.ts | 0 .../app/view-trade/view-trade.component.css | 0 .../app/view-trade/view-trade.component.html | 206 - .../view-trade/view-trade.component.spec.ts | 13 - .../app/view-trade/view-trade.component.ts | 51 - .../web/src/app/viewmodel/CommonViewModel.ts | 33 - .../web/src/app/viewmodel/DealViewModel.ts | 11 - .../src/app/viewmodel/FixedLegViewModel.ts | 18 - .../src/app/viewmodel/FloatingLegViewModel.ts | 26 - .../src/main/web/src/favicon.ico | Bin 5430 -> 0 bytes .../src/main/web/src/index.html | 48 - .../src/main/web/src/main.ts | 19 - .../src/main/web/src/system-config.ts | 98 - .../src/main/web/src/tsconfig.json | 23 - .../src/main/web/src/typings.d.ts | 6 - .../src/main/web/tslint.json | 110 - .../src/main/web/typings.json | 12 - 3025 files changed, 15 insertions(+), 325573 deletions(-) delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/.npmignore delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/history/aggregated delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/valuations delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/trades delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/business-date delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/history/aggregated delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/valuations delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/trades delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/whoami delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/checkbox.png delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/opengamma-logo.png delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/r3logo.png delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/favicon.ico delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/index.html delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/highstock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/jquery.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/spinners.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/main.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/main.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/system-config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/system-config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/bundles/common.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/bundles/common.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/common_directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/common_directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/core_directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/core_directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_class.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_for.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_for.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_if.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_if.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_plural.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_plural.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_style.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_style.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_switch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_switch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_template_outlet.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/directives/ng_template_outlet.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/intl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/intl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/abstract_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/abstract_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/checkbox_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/checkbox_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/control_container.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/control_container.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/default_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/default_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/form_interface.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/form_interface.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_group.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_group.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_status.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_control_status.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_form_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/ng_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/normalize_validator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/normalize_validator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/number_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/number_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/radio_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/radio_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/select_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/select_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/select_multiple_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/select_multiple_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/directives/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/form_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/form_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/forms-deprecated/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/localization.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/localization.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/hash_location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/hash_location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/path_location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/path_location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/location/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/async_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/async_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/common_pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/common_pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/date_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/date_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/i18n_plural_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/i18n_plural_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/i18n_select_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/i18n_select_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/invalid_pipe_argument_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/invalid_pipe_argument_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/json_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/json_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/lowercase_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/lowercase_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/number_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/number_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/replace_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/replace_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/slice_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/slice_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/uppercase_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/src/pipes/uppercase_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/testing/location_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/esm/testing/location_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/common_directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/common_directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/core_directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/core_directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_class.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_for.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_for.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_if.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_if.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_plural.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_plural.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_style.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_style.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_switch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_switch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_template_outlet.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/directives/ng_template_outlet.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/intl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/intl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/abstract_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/abstract_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/checkbox_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/checkbox_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/control_container.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/control_container.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/default_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/default_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/form_interface.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/form_interface.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_group.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_group.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_status.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_control_status.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_form_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/ng_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/normalize_validator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/normalize_validator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/number_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/number_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/radio_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/radio_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/select_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/select_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/select_multiple_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/select_multiple_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/directives/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/form_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/form_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/forms-deprecated/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/localization.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/localization.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/hash_location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/hash_location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/path_location_strategy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/path_location_strategy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/location/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/async_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/async_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/common_pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/common_pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/date_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/date_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/i18n_plural_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/i18n_plural_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/i18n_select_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/i18n_select_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/invalid_pipe_argument_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/invalid_pipe_argument_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/json_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/json_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/lowercase_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/lowercase_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/number_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/number_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/replace_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/replace_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/slice_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/slice_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/uppercase_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/src/pipes/uppercase_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/testing/location_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/common/testing/location_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/bundles/compiler.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/bundles/compiler.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/animation_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/styles_collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/animation/styles_collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/assertions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/assertions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/chars.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/chars.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/compile_metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/compile_metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_lifecycle_reflector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_lifecycle_reflector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_normalizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_normalizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/directive_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/lexer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/lexer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/expression_parser/parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/math.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/math.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_lexer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_lexer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_tags.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/html_tags.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/expander.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/expander.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/i18n_html_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/i18n_html_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/message.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/message.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/message_extractor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/message_extractor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/xmb_serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/i18n/xmb_serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/identifiers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/identifiers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/interpolation_config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/interpolation_config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/metadata_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/metadata_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/offline_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/offline_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/abstract_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/abstract_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/abstract_js_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/abstract_js_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/dart_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/dart_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/interpretive_view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/interpretive_view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_interpreter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_interpreter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_jit.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/output_jit.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/path_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/path_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/ts_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/output/ts_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/parse_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/parse_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/pipe_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/pipe_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/provider_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/provider_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/runtime_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/runtime_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/dom_element_schema_registry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/dom_element_schema_registry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/dom_security_schema.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/dom_security_schema.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/element_schema_registry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/schema/element_schema_registry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/selector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/selector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/shadow_css.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/shadow_css.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/style_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/style_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/style_url_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/style_url_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_preparser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/template_preparser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/url_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/url_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_binding.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_binding.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_element.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_element.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_method.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_method.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_query.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_query.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/compile_view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/event_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/event_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/expression_converter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/expression_converter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/lifecycle_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/lifecycle_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/property_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/property_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_compiler/view_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/view_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/xhr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/src/xhr.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/directive_resolver_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/directive_resolver_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/schema_registry_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/schema_registry_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/test_component_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/test_component_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/view_resolver_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/esm/testing/view_resolver_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/animation_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/styles_collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/animation/styles_collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/assertions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/assertions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/chars.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/chars.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/compile_metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/compile_metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_lifecycle_reflector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_lifecycle_reflector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_normalizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_normalizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/directive_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/lexer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/lexer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/expression_parser/parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/math.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/math.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_lexer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_lexer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_tags.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/html_tags.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/expander.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/expander.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/i18n_html_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/i18n_html_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/message.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/message.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/message_extractor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/message_extractor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/xmb_serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/i18n/xmb_serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/identifiers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/identifiers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/interpolation_config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/interpolation_config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/metadata_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/metadata_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/offline_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/offline_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/abstract_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/abstract_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/abstract_js_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/abstract_js_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/dart_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/dart_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/interpretive_view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/interpretive_view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_interpreter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_interpreter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_jit.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/output_jit.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/path_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/path_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/ts_emitter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/output/ts_emitter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/parse_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/parse_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/pipe_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/pipe_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/provider_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/provider_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/runtime_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/runtime_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/dom_element_schema_registry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/dom_element_schema_registry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/dom_security_schema.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/dom_security_schema.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/element_schema_registry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/schema/element_schema_registry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/selector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/selector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/shadow_css.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/shadow_css.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/style_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/style_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/style_url_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/style_url_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_ast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_ast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_parser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_parser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_preparser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/template_preparser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/url_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/url_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_binding.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_binding.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_element.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_element.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_method.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_method.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_pipe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_pipe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_query.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_query.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/compile_view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/event_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/event_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/expression_converter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/expression_converter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/lifecycle_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/lifecycle_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/property_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/property_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_binder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_binder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_compiler/view_compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/view_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/xhr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/src/xhr.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/directive_resolver_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/directive_resolver_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/schema_registry_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/schema_registry_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/test_component_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/test_component_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/view_resolver_mock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/compiler/testing/view_resolver_mock.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/bundles/core.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/bundles/core.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/active_animation_players_map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/active_animation_players_map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_driver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_driver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_group_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_group_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_keyframe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_keyframe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_sequence_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_sequence_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_style_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_style_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_styles.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/animation_styles.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/animation/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_common_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_common_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_tokens.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/application_tokens.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detection_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detection_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detector_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/change_detector_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/default_iterable_differ.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/default_iterable_differ.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/default_keyvalue_differ.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/default_keyvalue_differ.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/iterable_differs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/iterable_differs.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/keyvalue_differs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/differs/keyvalue_differs.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/pipe_transform.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/change_detection/pipe_transform.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/console.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/console.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/debug/debug_node.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/debug/debug_node.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/debug/debug_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/debug/debug_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/decorators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/decorators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/forward_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/forward_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/opaque_token.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/opaque_token.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/provider.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/provider.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/provider_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/provider_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_key.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_key.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_provider.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/di/reflective_provider.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/math.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/math.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_factory.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_factory.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_factory_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_factory_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/component_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/debug_context.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/debug_context.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/dynamic_component_loader.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/dynamic_component_loader.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/element_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/query_list.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/query_list.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/systemjs_component_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/systemjs_component_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/template_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/template_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_container_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_container_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_type.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_type.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/linker/view_utils.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/di.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/di.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/lifecycle_hooks.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/lifecycle_hooks.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/metadata/view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/platform_common_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/platform_common_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/platform_directives_and_pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/platform_directives_and_pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/profile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/profile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/wtf_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/wtf_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/wtf_init.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/profile/wtf_init.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/platform_reflection_capabilities.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/platform_reflection_capabilities.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflection_capabilities.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflection_capabilities.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflector_reader.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/reflector_reader.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/types.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/reflection/types.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/render.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/render.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/render/api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/render/api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/security.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/security.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/testability/testability.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/testability/testability.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/util/decorators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/util/decorators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone/ng_zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone/ng_zone.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone/ng_zone_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/src/zone/ng_zone_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/async_test_completer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/async_test_completer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/component_fixture.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/component_fixture.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/fake_async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/fake_async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/test_component_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/test_component_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/test_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/test_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/esm/testing/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/active_animation_players_map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/active_animation_players_map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_driver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_driver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_group_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_group_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_keyframe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_keyframe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_sequence_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_sequence_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_style_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_style_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_styles.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/animation_styles.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/animation/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_common_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_common_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_tokens.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/application_tokens.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detection_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detection_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detector_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/change_detector_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/constants.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/default_iterable_differ.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/default_iterable_differ.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/default_keyvalue_differ.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/default_keyvalue_differ.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/iterable_differs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/iterable_differs.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/keyvalue_differs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/differs/keyvalue_differs.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/pipe_transform.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/change_detection/pipe_transform.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/console.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/console.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/debug/debug_node.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/debug/debug_node.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/debug/debug_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/debug/debug_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/decorators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/decorators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/forward_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/forward_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/opaque_token.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/opaque_token.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/provider.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/provider.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/provider_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/provider_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_key.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_key.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_provider.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/di/reflective_provider.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/math.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/math.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/compiler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/compiler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_factory.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_factory.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_factory_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_factory_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/component_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/debug_context.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/debug_context.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/dynamic_component_loader.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/dynamic_component_loader.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/element_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/query_list.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/query_list.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/systemjs_component_resolver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/systemjs_component_resolver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/template_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/template_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_container_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_container_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_ref.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_ref.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_type.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_type.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/linker/view_utils.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/di.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/di.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/lifecycle_hooks.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/lifecycle_hooks.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/view.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/metadata/view.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/platform_common_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/platform_common_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/platform_directives_and_pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/platform_directives_and_pipes.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/profile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/profile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/wtf_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/wtf_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/wtf_init.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/profile/wtf_init.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/platform_reflection_capabilities.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/platform_reflection_capabilities.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflection_capabilities.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflection_capabilities.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflector_reader.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/reflector_reader.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/types.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/reflection/types.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/render.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/render.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/render/api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/render/api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/security.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/security.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/testability/testability.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/testability/testability.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/util/decorators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/util/decorators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone/ng_zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone/ng_zone.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone/ng_zone_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/src/zone/ng_zone_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/async_test_completer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/async_test_completer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/component_fixture.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/component_fixture.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/fake_async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/fake_async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/test_component_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/test_component_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/test_injector.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/test_injector.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/core/testing/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/bundles/forms.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/bundles/forms.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/abstract_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/abstract_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/abstract_form_group_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/abstract_form_group_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/checkbox_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/checkbox_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/control_container.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/control_container.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/default_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/default_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/form_interface.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/form_interface.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_control_status.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_control_status.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_form.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_form.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_model_group.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/ng_model_group.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/normalize_validator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/normalize_validator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/number_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/number_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/radio_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/radio_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_array_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_array_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_control_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_control_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_group_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_group_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_group_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/reactive_directives/form_group_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/select_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/select_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/select_multiple_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/select_multiple_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/directives/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/form_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/form_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/form_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/form_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/forms.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/forms.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/esm/src/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/abstract_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/abstract_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/abstract_form_group_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/abstract_form_group_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/checkbox_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/checkbox_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/control_container.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/control_container.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/default_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/default_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/form_interface.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/form_interface.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_control.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_control.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_control_status.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_control_status.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_form.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_form.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_model_group.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/ng_model_group.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/normalize_validator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/normalize_validator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/number_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/number_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/radio_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/radio_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_array_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_array_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_control_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_control_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_control_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_control_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_group_directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_group_directive.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_group_name.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/reactive_directives/form_group_name.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/select_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/select_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/select_multiple_control_value_accessor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/select_multiple_control_value_accessor.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/directives/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/form_builder.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/form_builder.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/form_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/form_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/forms.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/forms.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/model.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/model.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/validators.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/forms/src/validators.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/bundles/http.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/bundles/http.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/http.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/http.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/browser_jsonp.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/browser_jsonp.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/browser_xhr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/browser_xhr.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/jsonp_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/jsonp_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/xhr_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/backends/xhr_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/base_request_options.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/base_request_options.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/base_response_options.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/base_response_options.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/enums.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/enums.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/headers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/headers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/http.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/http.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/http_utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/http_utils.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/interfaces.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/interfaces.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/static_request.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/static_request.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/static_response.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/static_response.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/url_search_params.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/src/url_search_params.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/testing/mock_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/esm/testing/mock_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/http.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/http.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/browser_jsonp.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/browser_jsonp.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/browser_xhr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/browser_xhr.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/jsonp_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/jsonp_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/xhr_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/backends/xhr_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/base_request_options.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/base_request_options.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/base_response_options.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/base_response_options.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/enums.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/enums.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/headers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/headers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/http.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/http.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/http_utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/http_utils.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/interfaces.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/interfaces.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/static_request.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/static_request.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/static_response.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/static_response.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/url_search_params.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/src/url_search_params.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/testing/mock_backend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/http/testing/mock_backend.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/bundles/platform-browser-dynamic.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/platform_browser_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/platform_browser_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/private_export_testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/private_export_testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/xhr/xhr_cache.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/xhr/xhr_cache.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/xhr/xhr_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/src/xhr/xhr_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/testing/dom_test_component_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/esm/testing/dom_test_component_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/platform_browser_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/platform_browser_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/private_export_testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/private_export_testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/xhr/xhr_cache.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/xhr/xhr_cache.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/xhr/xhr_impl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/src/xhr/xhr_impl.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/testing/dom_test_component_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser-dynamic/testing/dom_test_component_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/bundles/platform-browser.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/bundles/platform-browser.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/core_private.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/core_private.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/browser_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/browser_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/generic_browser_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/generic_browser_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/location/browser_platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/location/browser_platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/location/history.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/location/history.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/testability.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/testability.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/title.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/title.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/tools/common_tools.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/tools/common_tools.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/tools/tools.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/browser/tools/tools.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/debug/by.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/debug/by.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/debug/ng_probe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/debug/ng_probe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_animate_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_animate_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_tokens.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/dom_tokens.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/dom_events.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/dom_events.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/event_manager.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/event_manager.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/hammer_common.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/hammer_common.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/hammer_gestures.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/hammer_gestures.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/key_events.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/events/key_events.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/shared_styles_host.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/shared_styles_host.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/web_animations_driver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/web_animations_driver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/web_animations_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/dom/web_animations_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/dom_sanitization_service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/dom_sanitization_service.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/html_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/html_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/style_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/style_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/url_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/security/url_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/client_message_broker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/client_message_broker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/message_bus.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/message_bus.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/messaging_api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/messaging_api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/post_message_bus.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/post_message_bus.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/render_store.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/render_store.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/serialized_types.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/serialized_types.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/service_message_broker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/shared/service_message_broker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/event_dispatcher.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/event_dispatcher.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/event_serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/event_serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/location_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/location_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/ui/renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/event_deserializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/event_deserializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/location_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/location_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/worker_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/web_workers/worker/worker_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/worker_app.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/worker_app.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/worker_render.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/src/worker_render.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/browser_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/browser_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/e2e_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing/e2e_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing_e2e.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/esm/testing_e2e.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/private_export.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/private_export.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/browser_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/browser_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/generic_browser_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/generic_browser_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/location/browser_platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/location/browser_platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/location/history.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/location/history.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/testability.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/testability.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/title.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/title.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/tools/common_tools.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/tools/common_tools.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/tools/tools.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/browser/tools/tools.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/debug/by.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/debug/by.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/debug/ng_probe.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/debug/ng_probe.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_animate_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_animate_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_tokens.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/dom_tokens.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/dom_events.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/dom_events.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/event_manager.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/event_manager.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/hammer_common.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/hammer_common.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/hammer_gestures.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/hammer_gestures.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/key_events.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/events/key_events.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/shared_styles_host.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/shared_styles_host.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/web_animations_driver.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/web_animations_driver.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/web_animations_player.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/dom/web_animations_player.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/base_wrapped_exception.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/base_wrapped_exception.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/exception_handler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/exception_handler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/exceptions.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/exceptions.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/lang.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/lang.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/promise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/facade/promise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/dom_sanitization_service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/dom_sanitization_service.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/html_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/html_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/style_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/style_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/url_sanitizer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/security/url_sanitizer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/client_message_broker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/client_message_broker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/message_bus.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/message_bus.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/messaging_api.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/messaging_api.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/post_message_bus.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/post_message_bus.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/render_store.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/render_store.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/serialized_types.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/serialized_types.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/service_message_broker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/shared/service_message_broker.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/event_dispatcher.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/event_dispatcher.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/event_serializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/event_serializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/location_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/location_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/ui/renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/event_deserializer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/event_deserializer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/location_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/location_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/platform_location.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/platform_location.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/renderer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/renderer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/worker_adapter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/web_workers/worker/worker_adapter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/worker_app.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/worker_app.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/worker_render.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/src/worker_render.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/browser.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/browser.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/browser_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/browser_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/e2e_util.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing/e2e_util.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing_e2e.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/platform-browser/testing_e2e.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/bundles/router.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/bundles/router.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/apply_redirects.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/apply_redirects.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/common_router_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/common_router_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/create_router_state.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/create_router_state.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/create_url_tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/create_url_tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_link.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_link.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_link_active.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_link_active.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_outlet.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/directives/router_outlet.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/interfaces.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/interfaces.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/recognize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/recognize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/resolve.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/resolve.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_outlet_map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_outlet_map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_state.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/router_state.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/url_tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/url_tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/utils/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/utils/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/utils/tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/esm/src/utils/tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/index.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/apply_redirects.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/apply_redirects.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/common_router_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/common_router_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/config.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/create_router_state.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/create_router_state.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/create_url_tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/create_url_tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_link.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_link.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_link_active.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_link_active.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_outlet.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/directives/router_outlet.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/interfaces.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/interfaces.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/recognize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/recognize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/resolve.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/resolve.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_outlet_map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_outlet_map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_providers.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_providers.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_state.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/router_state.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/shared.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/shared.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/url_tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/url_tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/utils/collection.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/utils/collection.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/utils/tree.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/@angular/router/src/utils/tree.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/css/bootstrap-theme.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/css/bootstrap-theme.min.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/css/bootstrap.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/css/bootstrap.min.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.eot delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.svg delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.woff delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2 delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/es6-shim/es6-shim.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/css/font-awesome.min.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/FontAwesome.otf delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/fontawesome-webfont.eot delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/fontawesome-webfont.svg delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/fontawesome-webfont.ttf delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/fontawesome-webfont.woff delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/font-awesome/fonts/fontawesome-webfont.woff2 delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/highcharts/highstock.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/jquery/dist/jquery.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/moment/moment.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/bundles/ng2-bootstrap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/bundles/ng2-bootstrap.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/accordion.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/accordion/accordion-group.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/accordion/accordion.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/alert.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/alert/alert.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/buttons.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/buttons/button-checkbox.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/buttons/button-radio.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/carousel.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/carousel/carousel.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/carousel/slide.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/collapse.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/collapse/collapse.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/common.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/date-formatter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/datepicker-inner.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/datepicker-popup.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/datepicker.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/daypicker.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/monthpicker.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/datepicker/yearpicker.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/dropdown.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/dropdown/dropdown-menu.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/dropdown/dropdown-toggle.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/dropdown/dropdown.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/dropdown/dropdown.service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/modal.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/modal/modal-backdrop.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/modal/modal-options.class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/modal/modal.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/ng2-bootstrap-config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/pagination.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/pagination/pager.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/pagination/pagination.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/position.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/progressbar.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/progressbar/bar.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/progressbar/progress.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/progressbar/progressbar.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/rating.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/rating/rating.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tabs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tabs/tab-heading.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tabs/tab.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tabs/tabset.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/timepicker.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/timepicker/timepicker.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tooltip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tooltip/tooltip-container.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tooltip/tooltip-options.class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/tooltip/tooltip.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead/latin-map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead/typeahead-container.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead/typeahead-options.class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead/typeahead-utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/typeahead/typeahead.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/utils/components-helper.service.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/components/utils/utils.class.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/gulpfile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/ng2-bootstrap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/ender.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/af.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ar-ma.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ar-sa.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ar-tn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ar.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/az.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/be.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/bg.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/bn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/bo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/br.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/bs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/cs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/cv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/cy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/da.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/de-at.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/de.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/dv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/el.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/en-au.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/en-ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/en-gb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/en-ie.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/en-nz.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/eo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/es-do.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/es.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/et.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/eu.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fa.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fr-ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fr-ch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/fy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/gd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/gl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/he.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/hi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/hr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/hu.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/hy-am.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/id.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/is.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/it.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ja.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/jv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ka.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/kk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/km.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ko.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ky.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/lb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/lo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/lt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/lv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/me.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/mk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ml.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/mr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ms-my.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ms.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/my.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/nb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ne.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/nl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/nn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/pa-in.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/pl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/pt-br.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/pt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ro.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ru.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/se.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/si.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sq.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sr-cyrl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ss.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/sw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/ta.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/te.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/th.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tl-ph.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tlh.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tzl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tzm-latn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/tzm.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/uk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/uz.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/vi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/x-pseudo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/zh-cn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/locale/zh-tw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/min/locales.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/min/locales.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/min/moment-with-locales.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/min/moment-with-locales.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/min/moment.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/moment.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/package.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/check-overflow.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/date-from-array.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-anything.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-array.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-object.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-string-and-array.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-string-and-format.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/from-string.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/local.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/parsing-flags.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/utc.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/create/valid.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/abs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/add-subtract.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/as.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/bubble.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/constructor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/create.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/duration.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/get.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/humanize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/iso-string.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/duration/prototype.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/format/format.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/base-config.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/calendar.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/constructor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/en.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/formats.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/invalid.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/lists.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/locale.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/locales.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/ordinal.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/pre-post-format.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/prototype.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/relative.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/locale/set.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/add-subtract.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/calendar.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/clone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/compare.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/constructor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/creation-data.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/diff.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/format.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/from.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/get-set.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/locale.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/min-max.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/moment.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/now.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/prototype.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/start-end-of.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/to-type.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/to.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/moment/valid.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/parse/regex.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/parse/token.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/aliases.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/constants.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/day-of-month.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/day-of-week.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/day-of-year.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/hour.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/millisecond.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/minute.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/month.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/offset.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/priorities.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/quarter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/second.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/timestamp.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/timezone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/units.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/week-calendar-utils.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/week-year.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/week.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/units/year.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/abs-ceil.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/abs-floor.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/abs-round.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/compare-arrays.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/defaults.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/deprecate.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/extend.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/has-own-prop.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/hooks.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/index-of.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-array.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-date.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-function.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-object-empty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-object.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/is-undefined.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/keys.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/some.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/to-int.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/lib/utils/zero-fill.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/af.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ar-ma.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ar-sa.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ar-tn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ar.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/az.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/be.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/bg.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/bn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/bo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/br.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/bs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/cs.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/cv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/cy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/da.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/de-at.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/de.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/dv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/el.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/en-au.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/en-ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/en-gb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/en-ie.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/en-nz.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/eo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/es-do.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/es.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/et.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/eu.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fa.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fr-ca.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fr-ch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/fy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/gd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/gl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/he.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/hi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/hr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/hu.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/hy-am.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/id.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/is.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/it.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ja.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/jv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ka.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/kk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/km.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ko.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ky.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/lb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/lo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/lt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/lv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/me.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/mk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ml.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/mr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ms-my.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ms.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/my.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/nb.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ne.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/nl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/nn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/pa-in.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/pl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/pt-br.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/pt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ro.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ru.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/se.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/si.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sq.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sr-cyrl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ss.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sv.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/sw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/ta.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/te.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/th.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tl-ph.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tlh.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tr.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tzl.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tzm-latn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/tzm.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/uk.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/uz.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/vi.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/x-pseudo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/zh-cn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/locale/zh-tw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/node_modules/moment/src/moment.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/protractor.conf.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/spec-bundle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-bootstrap/typedoc.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-popover/Popover.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-popover/PopoverContent.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-popover/index.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/bundles/ng2-select.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/bundles/ng2-select.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/css/ng2-select.css delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/common.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/off-click.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/select-interfaces.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/select-item.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/select-pipes.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/components/select/select.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/gulpfile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-select/ng2-select.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/bundles/ng2-table.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/bundles/ng2-table.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/components/ng-table-directives.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/components/table/ng-table-filtering.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/components/table/ng-table-paging.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/components/table/ng-table-sorting.directive.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/components/table/ng-table.component.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/gulpfile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/ng2-table/ng2-table.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/Reflect.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/Reflect.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/Reflect.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/reflect-metadata.d.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/Reflect.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/Reflect.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/harness.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/harness.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-decorate.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-decorate.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-definemetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-definemetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-deletemetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-deletemetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getmetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getmetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getmetadatakeys.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getmetadatakeys.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getownmetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getownmetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getownmetadatakeys.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-getownmetadatakeys.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-hasmetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-hasmetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-hasownmetadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-hasownmetadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-metadata.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/reflect/reflect-metadata.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/run.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/run.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/spec.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/temp/test/spec.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/harness.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-decorate.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-definemetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-deletemetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-getmetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-getmetadatakeys.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-getownmetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-getownmetadatakeys.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-hasmetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-hasownmetadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/reflect/reflect-metadata.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/run.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/test/spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/typings.d.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/reflect-metadata/typings/node.d.ts delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/AsyncSubject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/AsyncSubject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/BehaviorSubject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/BehaviorSubject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/InnerSubscriber.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/InnerSubscriber.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Notification.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Notification.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Observable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Observable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Observer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Observer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Operator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Operator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/OuterSubscriber.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/OuterSubscriber.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/ReplaySubject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/ReplaySubject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.DOM.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.DOM.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.KitchenSink.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.KitchenSink.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Rx.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Scheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Scheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/SubjectSubscription.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/SubjectSubscription.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subscriber.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subscriber.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subscription.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/Subscription.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/bindCallback.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/bindCallback.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/bindNodeCallback.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/bindNodeCallback.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/combineLatest.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/combineLatest.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/concat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/concat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/defer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/defer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/dom/ajax.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/dom/ajax.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/dom/webSocket.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/dom/webSocket.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/empty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/empty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/forkJoin.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/forkJoin.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/from.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/from.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromEvent.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromEvent.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromEventPattern.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromEventPattern.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromPromise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/fromPromise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/if.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/if.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/interval.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/interval.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/merge.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/merge.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/never.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/never.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/of.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/of.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/race.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/race.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/range.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/range.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/throw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/throw.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/timer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/timer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/using.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/using.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/zip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/observable/zip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/audit.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/audit.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/auditTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/auditTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/buffer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/buffer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferCount.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferCount.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferToggle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferToggle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/bufferWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/cache.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/cache.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/catch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/catch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/combineAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/combineAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/combineLatest.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/combineLatest.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/concatMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/count.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/count.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/debounce.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/debounce.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/debounceTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/debounceTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/defaultIfEmpty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/defaultIfEmpty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/delay.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/delay.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/delayWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/delayWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/dematerialize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/dematerialize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinct.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinct.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctKey.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctKey.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctUntilChanged.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctUntilChanged.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctUntilKeyChanged.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/distinctUntilKeyChanged.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/do.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/do.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/elementAt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/elementAt.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/every.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/every.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/exhaust.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/exhaust.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/exhaustMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/exhaustMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/expand.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/expand.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/filter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/filter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/finally.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/finally.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/find.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/find.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/findIndex.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/findIndex.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/first.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/first.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/groupBy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/groupBy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/ignoreElements.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/ignoreElements.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/isEmpty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/isEmpty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/last.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/last.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/let.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/let.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/materialize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/materialize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/max.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/max.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/merge.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/merge.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeScan.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/mergeScan.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/min.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/multicast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/multicast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/observeOn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/observeOn.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/pairwise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/pairwise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/partition.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/partition.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/pluck.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/pluck.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publish.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publish.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishBehavior.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishBehavior.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishLast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishLast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishReplay.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/publishReplay.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/race.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/race.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/reduce.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/reduce.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/repeat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/repeat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/retry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/retry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/retryWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/retryWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/sample.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/sample.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/sampleTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/sampleTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/scan.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/scan.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/share.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/share.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/single.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/single.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skipUntil.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skipUntil.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skipWhile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/skipWhile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/startWith.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/startWith.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/subscribeOn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/subscribeOn.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switchMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switchMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switchMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/switchMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/take.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/take.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeLast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeLast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeUntil.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeUntil.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeWhile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/takeWhile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/throttle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/throttle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/throttleTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/throttleTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeInterval.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeInterval.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeout.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeout.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeoutWith.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timeoutWith.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timestamp.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/timestamp.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/toArray.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/toArray.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/toPromise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/toPromise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/window.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/window.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowCount.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowCount.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowToggle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowToggle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/windowWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/withLatestFrom.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/withLatestFrom.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/zip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/zip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/zipAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/add/operator/zipAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.min.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.umd.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.umd.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/bundles/Rx.umd.min.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ArrayLikeObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ArrayLikeObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ArrayObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ArrayObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/BoundCallbackObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/BoundCallbackObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/BoundNodeCallbackObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/BoundNodeCallbackObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ConnectableObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ConnectableObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/DeferObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/DeferObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/EmptyObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/EmptyObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ErrorObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ErrorObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ForkJoinObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ForkJoinObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromEventObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromEventObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromEventPatternObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromEventPatternObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/FromObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IfObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IfObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IntervalObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IntervalObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IteratorObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/IteratorObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/NeverObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/NeverObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/PromiseObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/PromiseObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/RangeObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/RangeObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ScalarObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/ScalarObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/SubscribeOnObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/SubscribeOnObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/TimerObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/TimerObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/UsingObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/UsingObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/bindCallback.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/bindCallback.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/bindNodeCallback.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/bindNodeCallback.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/concat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/concat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/defer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/defer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/AjaxObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/AjaxObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/WebSocketSubject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/WebSocketSubject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/ajax.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/ajax.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/webSocket.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/dom/webSocket.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/empty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/empty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/forkJoin.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/forkJoin.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/from.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/from.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromEvent.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromEvent.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromEventPattern.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromEventPattern.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromPromise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/fromPromise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/if.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/if.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/interval.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/interval.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/merge.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/merge.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/never.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/never.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/of.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/of.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/range.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/range.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/throw.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/throw.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/timer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/timer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/using.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/using.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/zip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/observable/zip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/audit.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/audit.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/auditTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/auditTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/buffer.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/buffer.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferCount.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferCount.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferToggle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferToggle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/bufferWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/cache.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/cache.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/catch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/catch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/combineAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/combineAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/combineLatest.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/combineLatest.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/concatMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/count.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/count.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/debounce.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/debounce.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/debounceTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/debounceTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/defaultIfEmpty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/defaultIfEmpty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/delay.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/delay.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/delayWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/delayWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/dematerialize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/dematerialize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinct.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinct.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctKey.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctKey.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctUntilChanged.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctUntilChanged.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctUntilKeyChanged.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/distinctUntilKeyChanged.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/do.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/do.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/elementAt.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/elementAt.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/every.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/every.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/exhaust.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/exhaust.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/exhaustMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/exhaustMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/expand.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/expand.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/filter.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/filter.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/finally.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/finally.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/find.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/find.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/findIndex.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/findIndex.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/first.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/first.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/groupBy.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/groupBy.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/ignoreElements.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/ignoreElements.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/isEmpty.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/isEmpty.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/last.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/last.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/let.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/let.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/materialize.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/materialize.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/max.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/max.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/merge.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/merge.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeScan.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/mergeScan.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/min.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/multicast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/multicast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/observeOn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/observeOn.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/pairwise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/pairwise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/partition.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/partition.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/pluck.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/pluck.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publish.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publish.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishBehavior.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishBehavior.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishLast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishLast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishReplay.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/publishReplay.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/race.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/race.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/reduce.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/reduce.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/repeat.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/repeat.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/retry.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/retry.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/retryWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/retryWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/sample.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/sample.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/sampleTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/sampleTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/scan.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/scan.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/share.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/share.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/single.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/single.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skipUntil.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skipUntil.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skipWhile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/skipWhile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/startWith.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/startWith.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/subscribeOn.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/subscribeOn.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switchMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switchMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switchMapTo.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/switchMapTo.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/take.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/take.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeLast.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeLast.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeUntil.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeUntil.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeWhile.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/takeWhile.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/throttle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/throttle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/throttleTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/throttleTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeInterval.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeInterval.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeout.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeout.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeoutWith.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timeoutWith.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timestamp.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/timestamp.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/toArray.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/toArray.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/toPromise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/toPromise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/window.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/window.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowCount.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowCount.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowTime.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowTime.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowToggle.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowToggle.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowWhen.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/windowWhen.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/withLatestFrom.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/withLatestFrom.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/zip.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/zip.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/zipAll.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/operator/zipAll.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/Action.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/Action.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AnimationFrameAction.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AnimationFrameAction.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AnimationFrameScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AnimationFrameScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsapAction.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsapAction.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsapScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsapScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsyncScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/AsyncScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/FutureAction.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/FutureAction.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/QueueAction.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/QueueAction.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/QueueScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/QueueScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/VirtualTimeScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/VirtualTimeScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/animationFrame.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/animationFrame.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/asap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/asap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/async.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/async.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/queue.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/scheduler/queue.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/src/Rx.global.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/iterator.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/iterator.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/observable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/observable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/rxSubscriber.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/symbol/rxSubscriber.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/ColdObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/ColdObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/HotObservable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/HotObservable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/SubscriptionLog.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/SubscriptionLog.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/SubscriptionLoggable.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/SubscriptionLoggable.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/TestMessage.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/TestMessage.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/TestScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/testing/TestScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/AnimationFrame.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/AnimationFrame.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/ArgumentOutOfRangeError.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/ArgumentOutOfRangeError.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/EmptyError.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/EmptyError.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/FastMap.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/FastMap.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/Immediate.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/Immediate.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/Map.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/Map.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/MapPolyfill.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/MapPolyfill.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/ObjectUnsubscribedError.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/ObjectUnsubscribedError.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/UnsubscriptionError.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/UnsubscriptionError.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/applyMixins.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/applyMixins.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/assign.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/assign.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/errorObject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/errorObject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isArray.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isArray.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isDate.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isDate.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isFunction.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isFunction.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isNumeric.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isNumeric.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isObject.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isObject.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isPromise.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isPromise.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isScheduler.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/isScheduler.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/noop.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/noop.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/not.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/not.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/root.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/root.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/subscribeToResult.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/subscribeToResult.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/throwError.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/throwError.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/toSubscriber.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/toSubscriber.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/tryCatch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/rxjs/util/tryCatch.js.map delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/systemjs/dist/system-polyfills.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/systemjs/dist/system.src.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/underscore/underscore.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/async-test.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/fake-async-test.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/jasmine-patch.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/jasmine-patch.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/long-stack-trace-zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/long-stack-trace-zone.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/sync-test.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/wtf.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/wtf.min.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/zone-node.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/zone.js delete mode 100644 samples/simm-valuation-demo/src/main/resources/simmvaluationweb/vendor/zone.js/dist/zone.min.js delete mode 100644 samples/simm-valuation-demo/src/main/web/.editorconfig delete mode 100644 samples/simm-valuation-demo/src/main/web/.gitignore delete mode 100644 samples/simm-valuation-demo/src/main/web/.jsbeautifyrc delete mode 100644 samples/simm-valuation-demo/src/main/web/Dockerfile delete mode 100644 samples/simm-valuation-demo/src/main/web/README.md delete mode 100644 samples/simm-valuation-demo/src/main/web/angular-cli-build.js delete mode 100644 samples/simm-valuation-demo/src/main/web/angular-cli.json delete mode 100644 samples/simm-valuation-demo/src/main/web/config/environment.dev.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/config/environment.prod.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/e2e/app.e2e-spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/e2e/app.po.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/e2e/tsconfig.json delete mode 100644 samples/simm-valuation-demo/src/main/web/e2e/typings.d.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/package.json delete mode 100644 samples/simm-valuation-demo/src/main/web/public/.npmignore delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/bank-c/portfolio/history/aggregated delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/bank-c/portfolio/valuations delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/bank-c/trades delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/business-date delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/intesa/portfolio/history/aggregated delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/intesa/portfolio/valuations delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/intesa/trades delete mode 100644 samples/simm-valuation-demo/src/main/web/public/api/vega/whoami delete mode 100644 samples/simm-valuation-demo/src/main/web/public/assets/images/checkbox.png delete mode 100644 samples/simm-valuation-demo/src/main/web/public/assets/images/opengamma-logo.png delete mode 100644 samples/simm-valuation-demo/src/main/web/public/assets/images/r3logo.png delete mode 100644 samples/simm-valuation-demo/src/main/web/public/libs/highstock.js delete mode 100644 samples/simm-valuation-demo/src/main/web/public/libs/jquery.min.js delete mode 100644 samples/simm-valuation-demo/src/main/web/public/libs/spinners.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/Deal.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/app.component.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/app.component.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/app.component.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/app.component.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/app.routes.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/create-trade.component.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/create-trade.component.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/create-trade.component.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/create-trade.component.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/create-trade/shared/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/environment.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/http-wrapper.service.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/http-wrapper.service.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/irs.service.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/irs.service.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/model/CommonModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/model/FixedLegModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/model/FloatingLegModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/node.service.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/node.service.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/portfolio/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/portfolio/portfolio.component.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/portfolio/portfolio.component.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/portfolio/portfolio.component.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/portfolio/portfolio.component.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/shared/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/valuations/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/valuations/valuations.component.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/valuations/valuations.component.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/valuations/valuations.component.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/valuations/valuations.component.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/shared/index.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/view-trade.component.css delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/view-trade.component.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/view-trade.component.spec.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/view-trade/view-trade.component.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/viewmodel/CommonViewModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/viewmodel/DealViewModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/viewmodel/FixedLegViewModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/app/viewmodel/FloatingLegViewModel.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/favicon.ico delete mode 100644 samples/simm-valuation-demo/src/main/web/src/index.html delete mode 100644 samples/simm-valuation-demo/src/main/web/src/main.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/system-config.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/src/tsconfig.json delete mode 100644 samples/simm-valuation-demo/src/main/web/src/typings.d.ts delete mode 100644 samples/simm-valuation-demo/src/main/web/tslint.json delete mode 100644 samples/simm-valuation-demo/src/main/web/typings.json diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 4f7e359a92..7426adade4 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -6,6 +6,12 @@ from the previous milestone release. UNRELEASED ---------- + +* Remove the web front end from the simm demo + The state of the code and the extermely old version of (a beta) angular JS makes it almost impossible to maintain at this point. + Whilst the demo code itself is a useful teaching tool, the mess we have here isn't, so remove it with the purpose of putting something + better in place + * ``NodeInfo`` and ``NetworkMapCache`` changes: * Removed ``NodeInfo::legalIdentity`` in preparation for handling of multiple identities. We left list of ``NodeInfo::legalIdentitiesAndCerts``, the first identity still plays a special role of main node identity. diff --git a/docs/source/cordapp-overview.rst b/docs/source/cordapp-overview.rst index ee4656d872..2999489ef6 100644 --- a/docs/source/cordapp-overview.rst +++ b/docs/source/cordapp-overview.rst @@ -5,11 +5,10 @@ Corda is a platform. Its functionality is extended by developers through the wri applications (CorDapps). CorDapps are installed at the level of the individual node, rather than on the network itself. -Each CorDapp allows a node to handle new business processes - everything from asset trading (see :ref:`irs-demo`) to -portfolio valuations (see :ref:`simm-demo`). It does so by defining new flows on the node that, once started by the -node owner, conduct the process of negotiating a specific ledger update with other nodes on the network. The node's -owner can then start these flows as required, either through remote procedure calls (RPC) or HTTP requests that -leverage the RPC interface. +Each CorDapp allows a node to handle new business processes, for example asset trading (see :ref:`irs-demo`). +It does so by defining new flows on the node that, once started by the node owner, conduct the process of negotiating +a specific ledger update with other nodes on the network. The node's owner can then start these flows as required, +either through remote procedure calls (RPC) or HTTP requests that leverage the RPC interface. .. image:: resources/node-diagram.png @@ -23,4 +22,4 @@ CorDapps are made up of definitions for the following components: * Contracts * Flows * Web APIs and static web content -* Services \ No newline at end of file +* Services diff --git a/docs/source/running-the-demos.rst b/docs/source/running-the-demos.rst index 026be15756..6685c6db7e 100644 --- a/docs/source/running-the-demos.rst +++ b/docs/source/running-the-demos.rst @@ -8,10 +8,8 @@ Corda's functionality: 2. The IRS Demo, which shows two nodes establishing an interest rate swap and performing fixings with a rates oracle 3. The Attachment Demo, which demonstrates uploading attachments to nodes -4. The SIMM Valuation Demo, which shows two nodes agreeing on a portfolio and valuing the initial margin - using the Standard Initial Margin Model -5. The Notary Demo, which shows three different types of notaries and a single node getting multiple transactions notarised. -6. The Bank of Corda Demo, which shows a node acting as an issuer of assets (the Bank of Corda) while remote client +4. The Notary Demo, which shows three different types of notaries and a single node getting multiple transactions notarised. +5. The Bank of Corda Demo, which shows a node acting as an issuer of assets (the Bank of Corda) while remote client applications request issuance of some cash on behalf of a node called Big Corporation If any of the demos don't work, please raise an issue on GitHub. @@ -218,83 +216,3 @@ Using the following login details: See https://docs.corda.net/node-explorer.html for further details on usage. -.. _simm-demo: - -SIMM and Portfolio Demo - aka the Initial Margin Agreement Demo ---------------------------------------------------------------- - -Background and SIMM Introduction -******************************** - -This app is a demonstration of how Corda can be used for the real world requirement of initial margin calculation and -agreement; featuring the integration of complex and industry proven third party libraries into Corda nodes. - -SIMM is an acronym for "Standard Initial Margin Model". It is effectively the calculation of a "margin" that is paid -by one party to another when they agree a trade on certain types of transaction. This margin is -paid such that, in the event of one of the counterparties suffering a credit event -(a financial term and a polite way to say defaulting, not paying the debts that are due, or potentially even bankruptcy), -then the party that is owed any sum already has some of the amount that it should have been paid. This payment to the -receiving party is a preventative measure in order to reduce the risk of a potentially catastrophic default domino -effect that caused the `Great Financial Crisis `_, -as it means that they can be assured that if they need to pay another party, they will have a proportion of the funds -that they have been relying on. - -To enact this, in September 2016, the ISDA committee - with full backing from various governing bodies - -`issued a ruling on what is known as the ISDA SIMM ™ model `_, -a way of fairly and consistently calculating this margin. Any parties wishing to trade a financial product that is -covered under this ruling would, independently, use this model and calculate their margin payment requirement, -agree it with their trading counterparty and then pay (or receive, depending on the results of this calculation) -this amount. In the case of disagreement that is not resolved in a timely fashion, this payment would increase -and so therefore it is in the parties' interest to reach agreement in as short as time frame as possible. - -To be more accurate, the SIMM calculation is not performed on just one trade - it is calculated on an aggregate of -intermediary values (which in this model are sensitivities to risk factors) from a portfolio of trades; therefore -the input to a SIMM is actually this data, not the individual trades themselves. - -Also note that implementations of the SIMM are actually protected and subject to license restrictions by ISDA -(this is due to the model itself being protected). We were fortunate enough to technically partner with -`OpenGamma `_ who allowed us to demonstrate the SIMM process using their proprietary model. -In the source code released, we have replaced their analytics engine with very simple stub functions that allow -the process to run without actually calculating correct values, and can easily be swapped out in place for their real libraries. - -What happens in the demo (notionally) -************************************* - -Preliminaries - - Ensure that there are a number of live trades with another party financial products that are covered under the - ISDA SIMM agreement (if none, then use the demo to enter some simple trades as described below). - -Initial Margin Agreement Process - - Agree that one will be performing the margining calculation against a portfolio of trades with another party, and agree the trades in that portfolio. In practice, one node will start the flow but it does not matter which node does. - - Individually (at the node level), identify the data (static, reference etc) one will need in order to be able to calculate the metrics on those trades - - Confirm with the other counterparty the dataset from the above set - - Calculate any intermediary steps and values needed for the margin calculation (ie sensitivities to risk factors) - - Agree on the results of these steps - - Calculate the initial margin - - Agree on the calculation of the above with the other party - - In practice, pay (or receive) this margin (omitted for the sake of complexity for this example) - -Demo execution (step by step) -***************************** - -To run from the command line in Unix: - -1. Deploy the nodes using ``./gradlew samples:simm-valuation-demo:deployNodes`` -2. Run the nodes using ``./samples/simm-valuation-demo/build/nodes/runnodes`` - -To run from the command line in Windows: - -1. Deploy the nodes using ``gradlew samples:simm-valuation-demo:deployNodes`` -2. Run the nodes using ``samples\simm-valuation-demo\build\nodes\runnodes`` - -Then, for both Unix and Windows: - -3. Browse to http://localhost:10005/web/simmvaluationdemo -4. Select the counterparty (i.e. Bank B) -5. Enter at least 3 trades - via the "Create New Trade" tab -6. On the "Agree Valuations" tab, click the "Start Calculations" button - -Additionally, you can confirm that these trades are not visible from `Bank C's node `_ -and are visible to `Bank B `_. - -Please note that any URL path information after `simmvaluationdemo` should not be bookmarked or navigated to directly, as it is only provided for aesthetic purposes. diff --git a/samples/simm-valuation-demo/README.md b/samples/simm-valuation-demo/README.md index 7ea71fe116..7931c876e0 100644 --- a/samples/simm-valuation-demo/README.md +++ b/samples/simm-valuation-demo/README.md @@ -19,7 +19,3 @@ This demo was built in partnership with OpenGamma and used their SIMM library. H | Could not find net.corda.(...):(...):0.6-SNAPSHOT | The corda libraries have not been installed into your local maven directory. View the instructions for doing this in the core corda repository | | Execution failed for task ':simm-valuation-demo:buildWeb' : A problem occurred starting process 'command 'ng'' | You need to have `node packet manager` installed in order to build out some of the web resources. This is not a necessary step as we include pre-built web resources but if you do modify the web source, you will need to rebuild this area | -## Rebuild the web resources - -* Get Node.js v6.11.2 which at time of writing is the LTS release -* ../../gradlew installWeb diff --git a/samples/simm-valuation-demo/build.gradle b/samples/simm-valuation-demo/build.gradle index 29f427cb12..b06cef6212 100644 --- a/samples/simm-valuation-demo/build.gradle +++ b/samples/simm-valuation-demo/build.gradle @@ -98,43 +98,6 @@ task integrationTest(type: Test, dependsOn: []) { classpath = sourceSets.integrationTest.runtimeClasspath } -task npmInstall(type: Exec) { - workingDir 'src/main/web' - if (System.getProperty('os.name').toLowerCase().contains('windows')) { - commandLine 'cmd', '/c', 'npm', 'install' - } else { - commandLine 'npm', 'install' - } - - outputs.upToDateWhen { file('src/main/web/node_modules').exists() } -} - -task cleanWeb() { - doLast { - delete 'src/main/resources/simmvaluationweb' - delete 'src/main/web/dist' - } -} - -task buildWeb(type: Exec, dependsOn: [cleanWeb, npmInstall]) { - workingDir 'src/main/web' - if (System.getProperty('os.name').toLowerCase().contains('windows')) { - commandLine 'cmd', '/c', 'ng', 'build' - } else { - commandLine 'node_modules/angular-cli/bin/ng', 'build' - } -} - -task installWeb(type: Copy, dependsOn: [buildWeb]) { - from 'src/main/web/dist' - into 'src/main/resources/simmvaluationweb' - ['**/*.js', '**/*.js.map', '**/*.ts'].each { - filesMatching(it) { - filter(FixCrLfFilter.class, eol: FixCrLfFilter.CrLf.LF, fixlast: false) - } - } -} - publishing { publications { simmvaluationdemo(MavenPublication) { diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/plugin/SimmPlugin.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/plugin/SimmPlugin.kt index 3b1f492b6c..270f15e57e 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/plugin/SimmPlugin.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/plugin/SimmPlugin.kt @@ -15,6 +15,6 @@ import java.util.function.Function */ class SimmPlugin : WebServerPluginRegistry { override val webApis = listOf(Function(::PortfolioApi)) - override val staticServeDirs: Map = mapOf("simmvaluationdemo" to javaClass.classLoader.getResource("simmvaluationweb").toExternalForm()) + override val staticServeDirs: Map = emptyMap() override fun customizeJSONSerialization(om: ObjectMapper): Unit = registerFinanceJSONMappers(om) -} \ No newline at end of file +} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/.npmignore b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/.npmignore deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/history/aggregated b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/history/aggregated deleted file mode 100644 index aa36d786d9..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/history/aggregated +++ /dev/null @@ -1,501 +0,0 @@ -[{ "id": 1, "date": 1364774400000, "IM": 1980243, "MTM": 17979616, "notional": 12416060, "activeTrades": 129 }, - { "id": 2, "date": 1364860800000, "IM": 1290403, "MTM": 15904924, "notional": 12354320, "activeTrades": 132 }, - { "id": 3, "date": 1364947200000, "IM": 1774187, "MTM": 12106920, "notional": 13428577, "activeTrades": 196 }, - { "id": 4, "date": 1365033600000, "IM": 1229406, "MTM": 18736541, "notional": 17205237, "activeTrades": 129 }, - { "id": 5, "date": 1365120000000, "IM": 1595193, "MTM": 19740422, "notional": 12363985, "activeTrades": 178 }, - { "id": 6, "date": 1365206400000, "IM": 1077438, "MTM": 14986074, "notional": 11127028, "activeTrades": 145 }, - { "id": 7, "date": 1365292800000, "IM": 1037786, "MTM": 16585935, "notional": 13848342, "activeTrades": 102 }, - { "id": 8, "date": 1365379200000, "IM": 1184585, "MTM": 11700155, "notional": 13973174, "activeTrades": 177 }, - { "id": 9, "date": 1365465600000, "IM": 1740065, "MTM": 16616984, "notional": 15889971, "activeTrades": 163 }, - { "id": 10, "date": 1365552000000, "IM": 1892527, "MTM": 12481724, "notional": 12987082, "activeTrades": 186 }, - { "id": 11, "date": 1365638400000, "IM": 1771113, "MTM": 18433603, "notional": 10075530, "activeTrades": 115 }, - { "id": 12, "date": 1365724800000, "IM": 1947191, "MTM": 15458873, "notional": 18722507, "activeTrades": 153 }, - { "id": 13, "date": 1365811200000, "IM": 1327815, "MTM": 10650716, "notional": 10690015, "activeTrades": 165 }, - { "id": 14, "date": 1365897600000, "IM": 1052704, "MTM": 11027343, "notional": 16944664, "activeTrades": 173 }, - { "id": 15, "date": 1365984000000, "IM": 1160441, "MTM": 19291377, "notional": 12246581, "activeTrades": 195 }, - { "id": 16, "date": 1366070400000, "IM": 1944931, "MTM": 11509611, "notional": 10115175, "activeTrades": 176 }, - { "id": 17, "date": 1366156800000, "IM": 1239680, "MTM": 15116514, "notional": 14134210, "activeTrades": 109 }, - { "id": 18, "date": 1366243200000, "IM": 1621232, "MTM": 11398571, "notional": 16413933, "activeTrades": 161 }, - { "id": 19, "date": 1366329600000, "IM": 1357206, "MTM": 16169751, "notional": 12803746, "activeTrades": 116 }, - { "id": 20, "date": 1366416000000, "IM": 1574531, "MTM": 10147428, "notional": 19281386, "activeTrades": 133 }, - { "id": 21, "date": 1366502400000, "IM": 1148449, "MTM": 17575869, "notional": 17682373, "activeTrades": 179 }, - { "id": 22, "date": 1366588800000, "IM": 1904303, "MTM": 11072402, "notional": 13302137, "activeTrades": 115 }, - { "id": 23, "date": 1366675200000, "IM": 1536063, "MTM": 11075073, "notional": 18378502, "activeTrades": 160 }, - { "id": 24, "date": 1366761600000, "IM": 1661562, "MTM": 10524591, "notional": 17264480, "activeTrades": 123 }, - { "id": 25, "date": 1366848000000, "IM": 1466204, "MTM": 11960196, "notional": 12246476, "activeTrades": 143 }, - { "id": 26, "date": 1366934400000, "IM": 1853511, "MTM": 10849648, "notional": 13069300, "activeTrades": 136 }, - { "id": 27, "date": 1367020800000, "IM": 1384277, "MTM": 15887874, "notional": 14346400, "activeTrades": 157 }, - { "id": 28, "date": 1367107200000, "IM": 1712868, "MTM": 12621119, "notional": 11453836, "activeTrades": 104 }, - { "id": 29, "date": 1367193600000, "IM": 1906877, "MTM": 14022900, "notional": 16719753, "activeTrades": 129 }, - { "id": 30, "date": 1367280000000, "IM": 1828652, "MTM": 19874958, "notional": 18402913, "activeTrades": 186 }, - { "id": 31, "date": 1367366400000, "IM": 1701003, "MTM": 13993201, "notional": 18106614, "activeTrades": 172 }, - { "id": 32, "date": 1367452800000, "IM": 1883619, "MTM": 15352081, "notional": 16268030, "activeTrades": 140 }, - { "id": 33, "date": 1367539200000, "IM": 1547083, "MTM": 11389252, "notional": 19432759, "activeTrades": 171 }, - { "id": 34, "date": 1367625600000, "IM": 1464452, "MTM": 18271755, "notional": 15147184, "activeTrades": 184 }, - { "id": 35, "date": 1367712000000, "IM": 1874976, "MTM": 15634295, "notional": 11649680, "activeTrades": 119 }, - { "id": 36, "date": 1367798400000, "IM": 1881366, "MTM": 19903639, "notional": 11937433, "activeTrades": 192 }, - { "id": 37, "date": 1367884800000, "IM": 1859557, "MTM": 11400105, "notional": 13030674, "activeTrades": 148 }, - { "id": 38, "date": 1367971200000, "IM": 1910667, "MTM": 17390376, "notional": 16610412, "activeTrades": 103 }, - { "id": 39, "date": 1368057600000, "IM": 1447876, "MTM": 12617961, "notional": 17809054, "activeTrades": 187 }, - { "id": 40, "date": 1368144000000, "IM": 1033129, "MTM": 11510705, "notional": 16609390, "activeTrades": 197 }, - { "id": 41, "date": 1368230400000, "IM": 1128288, "MTM": 13434273, "notional": 14656796, "activeTrades": 143 }, - { "id": 42, "date": 1368316800000, "IM": 1293693, "MTM": 13422644, "notional": 15062382, "activeTrades": 194 }, - { "id": 43, "date": 1368403200000, "IM": 1935145, "MTM": 15309370, "notional": 14281839, "activeTrades": 153 }, - { "id": 44, "date": 1368489600000, "IM": 1491003, "MTM": 10821800, "notional": 16245543, "activeTrades": 200 }, - { "id": 45, "date": 1368576000000, "IM": 1437633, "MTM": 12520837, "notional": 13127293, "activeTrades": 172 }, - { "id": 46, "date": 1368662400000, "IM": 1332366, "MTM": 15154045, "notional": 16252572, "activeTrades": 123 }, - { "id": 47, "date": 1368748800000, "IM": 1610591, "MTM": 11227366, "notional": 10251897, "activeTrades": 161 }, - { "id": 48, "date": 1368835200000, "IM": 1471045, "MTM": 15753545, "notional": 14085751, "activeTrades": 128 }, - { "id": 49, "date": 1368921600000, "IM": 1510708, "MTM": 16982181, "notional": 14568704, "activeTrades": 179 }, - { "id": 50, "date": 1369008000000, "IM": 1451008, "MTM": 11344040, "notional": 12124052, "activeTrades": 194 }, - { "id": 51, "date": 1369094400000, "IM": 1737515, "MTM": 13202279, "notional": 12040157, "activeTrades": 176 }, - { "id": 52, "date": 1369180800000, "IM": 1557659, "MTM": 12961808, "notional": 13639747, "activeTrades": 162 }, - { "id": 53, "date": 1369267200000, "IM": 1199408, "MTM": 14287756, "notional": 12854887, "activeTrades": 128 }, - { "id": 54, "date": 1369353600000, "IM": 1198945, "MTM": 19272301, "notional": 17584214, "activeTrades": 184 }, - { "id": 55, "date": 1369440000000, "IM": 1896867, "MTM": 12920504, "notional": 18611346, "activeTrades": 200 }, - { "id": 56, "date": 1369526400000, "IM": 1564204, "MTM": 11174960, "notional": 14831089, "activeTrades": 127 }, - { "id": 57, "date": 1369612800000, "IM": 1275313, "MTM": 19574936, "notional": 17129236, "activeTrades": 159 }, - { "id": 58, "date": 1369699200000, "IM": 1163461, "MTM": 17013905, "notional": 14818559, "activeTrades": 178 }, - { "id": 59, "date": 1369785600000, "IM": 1491295, "MTM": 16173343, "notional": 10134408, "activeTrades": 165 }, - { "id": 60, "date": 1369872000000, "IM": 1559450, "MTM": 15465849, "notional": 15818013, "activeTrades": 187 }, - { "id": 61, "date": 1369958400000, "IM": 1200625, "MTM": 18164324, "notional": 16691765, "activeTrades": 177 }, - { "id": 62, "date": 1370044800000, "IM": 1837500, "MTM": 11821544, "notional": 15867625, "activeTrades": 105 }, - { "id": 63, "date": 1370131200000, "IM": 1257376, "MTM": 17138152, "notional": 19637050, "activeTrades": 194 }, - { "id": 64, "date": 1370217600000, "IM": 1670238, "MTM": 19470919, "notional": 11149165, "activeTrades": 142 }, - { "id": 65, "date": 1370304000000, "IM": 1459590, "MTM": 14306326, "notional": 16034203, "activeTrades": 129 }, - { "id": 66, "date": 1370390400000, "IM": 1426668, "MTM": 12107301, "notional": 12525293, "activeTrades": 158 }, - { "id": 67, "date": 1370476800000, "IM": 1393410, "MTM": 16790650, "notional": 14956053, "activeTrades": 177 }, - { "id": 68, "date": 1370563200000, "IM": 1496110, "MTM": 10326542, "notional": 19849083, "activeTrades": 151 }, - { "id": 69, "date": 1370649600000, "IM": 1646963, "MTM": 19510597, "notional": 15071740, "activeTrades": 117 }, - { "id": 70, "date": 1370736000000, "IM": 1837441, "MTM": 18059452, "notional": 19938555, "activeTrades": 188 }, - { "id": 71, "date": 1370822400000, "IM": 1980519, "MTM": 17589592, "notional": 18640181, "activeTrades": 152 }, - { "id": 72, "date": 1370908800000, "IM": 1540009, "MTM": 17312599, "notional": 16624029, "activeTrades": 155 }, - { "id": 73, "date": 1370995200000, "IM": 1120134, "MTM": 16306214, "notional": 14843743, "activeTrades": 171 }, - { "id": 74, "date": 1371081600000, "IM": 1795905, "MTM": 18388212, "notional": 13744380, "activeTrades": 165 }, - { "id": 75, "date": 1371168000000, "IM": 1931505, "MTM": 12888507, "notional": 19541459, "activeTrades": 101 }, - { "id": 76, "date": 1371254400000, "IM": 1469113, "MTM": 16644065, "notional": 16831629, "activeTrades": 174 }, - { "id": 77, "date": 1371340800000, "IM": 1907748, "MTM": 18348383, "notional": 13249916, "activeTrades": 188 }, - { "id": 78, "date": 1371427200000, "IM": 1560896, "MTM": 18820937, "notional": 15409416, "activeTrades": 194 }, - { "id": 79, "date": 1371513600000, "IM": 1707505, "MTM": 18998179, "notional": 15727485, "activeTrades": 159 }, - { "id": 80, "date": 1371600000000, "IM": 1381709, "MTM": 13140692, "notional": 13510104, "activeTrades": 133 }, - { "id": 81, "date": 1371686400000, "IM": 1360882, "MTM": 10399795, "notional": 18381366, "activeTrades": 101 }, - { "id": 82, "date": 1371772800000, "IM": 1301906, "MTM": 18497881, "notional": 11388642, "activeTrades": 141 }, - { "id": 83, "date": 1371859200000, "IM": 1375753, "MTM": 10485731, "notional": 16094865, "activeTrades": 144 }, - { "id": 84, "date": 1371945600000, "IM": 1245418, "MTM": 13797660, "notional": 18869794, "activeTrades": 119 }, - { "id": 85, "date": 1372032000000, "IM": 1636561, "MTM": 14557659, "notional": 12954450, "activeTrades": 120 }, - { "id": 86, "date": 1372118400000, "IM": 1333324, "MTM": 18329107, "notional": 19829361, "activeTrades": 177 }, - { "id": 87, "date": 1372204800000, "IM": 1296032, "MTM": 12455751, "notional": 11108936, "activeTrades": 165 }, - { "id": 88, "date": 1372291200000, "IM": 1571030, "MTM": 10252795, "notional": 16982657, "activeTrades": 190 }, - { "id": 89, "date": 1372377600000, "IM": 1084540, "MTM": 16782465, "notional": 17796544, "activeTrades": 110 }, - { "id": 90, "date": 1372464000000, "IM": 1908578, "MTM": 12526227, "notional": 10393789, "activeTrades": 158 }, - { "id": 91, "date": 1372550400000, "IM": 1007587, "MTM": 16198358, "notional": 12607614, "activeTrades": 104 }, - { "id": 92, "date": 1372636800000, "IM": 1821758, "MTM": 13933767, "notional": 17937861, "activeTrades": 129 }, - { "id": 93, "date": 1372723200000, "IM": 1895576, "MTM": 12682671, "notional": 17217834, "activeTrades": 123 }, - { "id": 94, "date": 1372809600000, "IM": 1800648, "MTM": 12184495, "notional": 18167683, "activeTrades": 177 }, - { "id": 95, "date": 1372896000000, "IM": 1936765, "MTM": 19690711, "notional": 10751559, "activeTrades": 120 }, - { "id": 96, "date": 1372982400000, "IM": 1124330, "MTM": 16789619, "notional": 15234873, "activeTrades": 145 }, - { "id": 97, "date": 1373068800000, "IM": 1008677, "MTM": 11451314, "notional": 10857899, "activeTrades": 137 }, - { "id": 98, "date": 1373155200000, "IM": 1253796, "MTM": 17758749, "notional": 16041575, "activeTrades": 186 }, - { "id": 99, "date": 1373241600000, "IM": 1310332, "MTM": 17047905, "notional": 16998200, "activeTrades": 156 }, - { "id": 100, "date": 1373328000000, "IM": 1002106, "MTM": 15355790, "notional": 11541625, "activeTrades": 126 }, - { "id": 101, "date": 1373414400000, "IM": 1824083, "MTM": 19945041, "notional": 11781164, "activeTrades": 110 }, - { "id": 102, "date": 1373500800000, "IM": 1157754, "MTM": 19151681, "notional": 11762320, "activeTrades": 176 }, - { "id": 103, "date": 1373587200000, "IM": 1164040, "MTM": 13947940, "notional": 15186626, "activeTrades": 143 }, - { "id": 104, "date": 1373673600000, "IM": 1636252, "MTM": 14474787, "notional": 18827290, "activeTrades": 145 }, - { "id": 105, "date": 1373760000000, "IM": 1117031, "MTM": 15538824, "notional": 16872330, "activeTrades": 113 }, - { "id": 106, "date": 1373846400000, "IM": 1016796, "MTM": 16250904, "notional": 16188911, "activeTrades": 150 }, - { "id": 107, "date": 1373932800000, "IM": 1717787, "MTM": 12370074, "notional": 17275961, "activeTrades": 148 }, - { "id": 108, "date": 1374019200000, "IM": 1128963, "MTM": 15240870, "notional": 17839416, "activeTrades": 167 }, - { "id": 109, "date": 1374105600000, "IM": 1615823, "MTM": 12288195, "notional": 15528155, "activeTrades": 191 }, - { "id": 110, "date": 1374192000000, "IM": 1442712, "MTM": 10284737, "notional": 17968708, "activeTrades": 164 }, - { "id": 111, "date": 1374278400000, "IM": 1765530, "MTM": 10027132, "notional": 16318967, "activeTrades": 119 }, - { "id": 112, "date": 1374364800000, "IM": 1118944, "MTM": 10384086, "notional": 14395966, "activeTrades": 123 }, - { "id": 113, "date": 1374451200000, "IM": 1143164, "MTM": 17010560, "notional": 17824835, "activeTrades": 121 }, - { "id": 114, "date": 1374537600000, "IM": 1154723, "MTM": 12812074, "notional": 18809437, "activeTrades": 198 }, - { "id": 115, "date": 1374624000000, "IM": 1565500, "MTM": 10479723, "notional": 15081333, "activeTrades": 105 }, - { "id": 116, "date": 1374710400000, "IM": 1442532, "MTM": 15204186, "notional": 15446007, "activeTrades": 160 }, - { "id": 117, "date": 1374796800000, "IM": 1973023, "MTM": 14692494, "notional": 14571804, "activeTrades": 140 }, - { "id": 118, "date": 1374883200000, "IM": 1349037, "MTM": 12208816, "notional": 13474263, "activeTrades": 196 }, - { "id": 119, "date": 1374969600000, "IM": 1414326, "MTM": 16475687, "notional": 13955286, "activeTrades": 135 }, - { "id": 120, "date": 1375056000000, "IM": 1023133, "MTM": 13329170, "notional": 14772152, "activeTrades": 175 }, - { "id": 121, "date": 1375142400000, "IM": 1097849, "MTM": 12101654, "notional": 14585357, "activeTrades": 195 }, - { "id": 122, "date": 1375228800000, "IM": 1576972, "MTM": 15075419, "notional": 12282767, "activeTrades": 130 }, - { "id": 123, "date": 1375315200000, "IM": 1748793, "MTM": 13592312, "notional": 13426168, "activeTrades": 136 }, - { "id": 124, "date": 1375401600000, "IM": 1657009, "MTM": 19165227, "notional": 14987377, "activeTrades": 153 }, - { "id": 125, "date": 1375488000000, "IM": 1796756, "MTM": 13639705, "notional": 13289473, "activeTrades": 109 }, - { "id": 126, "date": 1375574400000, "IM": 1848167, "MTM": 14088873, "notional": 16217428, "activeTrades": 185 }, - { "id": 127, "date": 1375660800000, "IM": 1093838, "MTM": 13110808, "notional": 16149248, "activeTrades": 181 }, - { "id": 128, "date": 1375747200000, "IM": 1411045, "MTM": 17402937, "notional": 15515617, "activeTrades": 192 }, - { "id": 129, "date": 1375833600000, "IM": 1076881, "MTM": 17391884, "notional": 13540157, "activeTrades": 122 }, - { "id": 130, "date": 1375920000000, "IM": 1245437, "MTM": 15101368, "notional": 15426824, "activeTrades": 145 }, - { "id": 131, "date": 1376006400000, "IM": 1722700, "MTM": 16899146, "notional": 15198763, "activeTrades": 178 }, - { "id": 132, "date": 1376092800000, "IM": 1668607, "MTM": 11357567, "notional": 11810134, "activeTrades": 147 }, - { "id": 133, "date": 1376179200000, "IM": 1767654, "MTM": 13875439, "notional": 10603537, "activeTrades": 132 }, - { "id": 134, "date": 1376265600000, "IM": 1987223, "MTM": 12973339, "notional": 10833995, "activeTrades": 114 }, - { "id": 135, "date": 1376352000000, "IM": 1522636, "MTM": 15174385, "notional": 13599414, "activeTrades": 179 }, - { "id": 136, "date": 1376438400000, "IM": 1997115, "MTM": 10390176, "notional": 19251446, "activeTrades": 152 }, - { "id": 137, "date": 1376524800000, "IM": 1978796, "MTM": 18949070, "notional": 18157593, "activeTrades": 183 }, - { "id": 138, "date": 1376611200000, "IM": 1292210, "MTM": 16164076, "notional": 16365835, "activeTrades": 187 }, - { "id": 139, "date": 1376697600000, "IM": 1204848, "MTM": 19002379, "notional": 17560806, "activeTrades": 172 }, - { "id": 140, "date": 1376784000000, "IM": 1397265, "MTM": 17418152, "notional": 18970223, "activeTrades": 121 }, - { "id": 141, "date": 1376870400000, "IM": 1331904, "MTM": 16515079, "notional": 13699451, "activeTrades": 162 }, - { "id": 142, "date": 1376956800000, "IM": 1517657, "MTM": 14513080, "notional": 10465996, "activeTrades": 173 }, - { "id": 143, "date": 1377043200000, "IM": 1827762, "MTM": 16858069, "notional": 16448648, "activeTrades": 168 }, - { "id": 144, "date": 1377129600000, "IM": 1384985, "MTM": 19139598, "notional": 11152497, "activeTrades": 130 }, - { "id": 145, "date": 1377216000000, "IM": 1718891, "MTM": 14864111, "notional": 10181827, "activeTrades": 113 }, - { "id": 146, "date": 1377302400000, "IM": 1722161, "MTM": 17575066, "notional": 13577324, "activeTrades": 110 }, - { "id": 147, "date": 1377388800000, "IM": 1129766, "MTM": 19229868, "notional": 16947255, "activeTrades": 160 }, - { "id": 148, "date": 1377475200000, "IM": 1023176, "MTM": 12972217, "notional": 19617225, "activeTrades": 155 }, - { "id": 149, "date": 1377561600000, "IM": 1734821, "MTM": 19147045, "notional": 19806581, "activeTrades": 179 }, - { "id": 150, "date": 1377648000000, "IM": 1105050, "MTM": 16548539, "notional": 12757259, "activeTrades": 147 }, - { "id": 151, "date": 1377734400000, "IM": 1229547, "MTM": 19372076, "notional": 10110467, "activeTrades": 148 }, - { "id": 152, "date": 1377820800000, "IM": 1340286, "MTM": 18235467, "notional": 15606094, "activeTrades": 114 }, - { "id": 153, "date": 1377907200000, "IM": 1006317, "MTM": 13772656, "notional": 12610497, "activeTrades": 171 }, - { "id": 154, "date": 1377993600000, "IM": 1396316, "MTM": 18373746, "notional": 18161519, "activeTrades": 179 }, - { "id": 155, "date": 1378080000000, "IM": 1032577, "MTM": 14590388, "notional": 19504146, "activeTrades": 149 }, - { "id": 156, "date": 1378166400000, "IM": 1008749, "MTM": 10237883, "notional": 19408136, "activeTrades": 172 }, - { "id": 157, "date": 1378252800000, "IM": 1914567, "MTM": 17192369, "notional": 15291208, "activeTrades": 170 }, - { "id": 158, "date": 1378339200000, "IM": 1696520, "MTM": 18238934, "notional": 17329031, "activeTrades": 148 }, - { "id": 159, "date": 1378425600000, "IM": 1349395, "MTM": 10561819, "notional": 17536995, "activeTrades": 140 }, - { "id": 160, "date": 1378512000000, "IM": 1683758, "MTM": 18981083, "notional": 11592395, "activeTrades": 124 }, - { "id": 161, "date": 1378598400000, "IM": 1733258, "MTM": 18963171, "notional": 10388106, "activeTrades": 145 }, - { "id": 162, "date": 1378684800000, "IM": 1006957, "MTM": 11041696, "notional": 13918760, "activeTrades": 155 }, - { "id": 163, "date": 1378771200000, "IM": 1935494, "MTM": 13835718, "notional": 13334520, "activeTrades": 161 }, - { "id": 164, "date": 1378857600000, "IM": 1225168, "MTM": 17345690, "notional": 18496023, "activeTrades": 136 }, - { "id": 165, "date": 1378944000000, "IM": 1436065, "MTM": 18728883, "notional": 13754611, "activeTrades": 114 }, - { "id": 166, "date": 1379030400000, "IM": 1087411, "MTM": 19699540, "notional": 11135863, "activeTrades": 181 }, - { "id": 167, "date": 1379116800000, "IM": 1099799, "MTM": 17105981, "notional": 17433397, "activeTrades": 182 }, - { "id": 168, "date": 1379203200000, "IM": 1118853, "MTM": 12305401, "notional": 17421226, "activeTrades": 156 }, - { "id": 169, "date": 1379289600000, "IM": 1260725, "MTM": 15169312, "notional": 16045879, "activeTrades": 101 }, - { "id": 170, "date": 1379376000000, "IM": 1604827, "MTM": 14075786, "notional": 15663226, "activeTrades": 126 }, - { "id": 171, "date": 1379462400000, "IM": 1598684, "MTM": 18583226, "notional": 19195122, "activeTrades": 117 }, - { "id": 172, "date": 1379548800000, "IM": 1453596, "MTM": 19500332, "notional": 12745989, "activeTrades": 130 }, - { "id": 173, "date": 1379635200000, "IM": 1819389, "MTM": 13376148, "notional": 11969256, "activeTrades": 175 }, - { "id": 174, "date": 1379721600000, "IM": 1215262, "MTM": 17547871, "notional": 16823959, "activeTrades": 106 }, - { "id": 175, "date": 1379808000000, "IM": 1914609, "MTM": 14234024, "notional": 12321444, "activeTrades": 129 }, - { "id": 176, "date": 1379894400000, "IM": 1686567, "MTM": 18727231, "notional": 15049811, "activeTrades": 195 }, - { "id": 177, "date": 1379980800000, "IM": 1156232, "MTM": 13548017, "notional": 13414997, "activeTrades": 172 }, - { "id": 178, "date": 1380067200000, "IM": 1164005, "MTM": 19107970, "notional": 15246342, "activeTrades": 166 }, - { "id": 179, "date": 1380153600000, "IM": 1489581, "MTM": 10389177, "notional": 12950104, "activeTrades": 180 }, - { "id": 180, "date": 1380240000000, "IM": 1478138, "MTM": 17199170, "notional": 12548343, "activeTrades": 143 }, - { "id": 181, "date": 1380326400000, "IM": 1709880, "MTM": 12956151, "notional": 14844933, "activeTrades": 104 }, - { "id": 182, "date": 1380412800000, "IM": 1821345, "MTM": 19387385, "notional": 19763874, "activeTrades": 139 }, - { "id": 183, "date": 1380499200000, "IM": 1321990, "MTM": 15429022, "notional": 18410651, "activeTrades": 172 }, - { "id": 184, "date": 1380585600000, "IM": 1341824, "MTM": 12660990, "notional": 16997909, "activeTrades": 108 }, - { "id": 185, "date": 1380672000000, "IM": 1196937, "MTM": 11311863, "notional": 18213436, "activeTrades": 186 }, - { "id": 186, "date": 1380758400000, "IM": 1063232, "MTM": 15550443, "notional": 15850254, "activeTrades": 100 }, - { "id": 187, "date": 1380844800000, "IM": 1270732, "MTM": 13598737, "notional": 19541458, "activeTrades": 105 }, - { "id": 188, "date": 1380931200000, "IM": 1681334, "MTM": 14395433, "notional": 12432662, "activeTrades": 164 }, - { "id": 189, "date": 1381017600000, "IM": 1627632, "MTM": 19211154, "notional": 10928917, "activeTrades": 132 }, - { "id": 190, "date": 1381104000000, "IM": 1201524, "MTM": 15934703, "notional": 11616380, "activeTrades": 147 }, - { "id": 191, "date": 1381190400000, "IM": 1014576, "MTM": 12700613, "notional": 18153464, "activeTrades": 196 }, - { "id": 192, "date": 1381276800000, "IM": 1699616, "MTM": 15647778, "notional": 18775156, "activeTrades": 160 }, - { "id": 193, "date": 1381363200000, "IM": 1975124, "MTM": 16399709, "notional": 13797921, "activeTrades": 111 }, - { "id": 194, "date": 1381449600000, "IM": 1403333, "MTM": 15399380, "notional": 14546141, "activeTrades": 193 }, - { "id": 195, "date": 1381536000000, "IM": 1517948, "MTM": 17560879, "notional": 15850592, "activeTrades": 144 }, - { "id": 196, "date": 1381622400000, "IM": 1362563, "MTM": 17672765, "notional": 18641448, "activeTrades": 104 }, - { "id": 197, "date": 1381708800000, "IM": 1250747, "MTM": 10176312, "notional": 15443596, "activeTrades": 120 }, - { "id": 198, "date": 1381795200000, "IM": 1945502, "MTM": 12624619, "notional": 11860961, "activeTrades": 116 }, - { "id": 199, "date": 1381881600000, "IM": 1774412, "MTM": 16889430, "notional": 11419754, "activeTrades": 123 }, - { "id": 200, "date": 1381968000000, "IM": 1603746, "MTM": 11400568, "notional": 11557979, "activeTrades": 185 }, - { "id": 201, "date": 1382054400000, "IM": 1204921, "MTM": 14761744, "notional": 16664286, "activeTrades": 134 }, - { "id": 202, "date": 1382140800000, "IM": 1490013, "MTM": 19526595, "notional": 14718750, "activeTrades": 180 }, - { "id": 203, "date": 1382227200000, "IM": 1017094, "MTM": 17835518, "notional": 11389511, "activeTrades": 191 }, - { "id": 204, "date": 1382313600000, "IM": 1913662, "MTM": 13206654, "notional": 16269861, "activeTrades": 181 }, - { "id": 205, "date": 1382400000000, "IM": 1679443, "MTM": 16508564, "notional": 16195324, "activeTrades": 148 }, - { "id": 206, "date": 1382486400000, "IM": 1454367, "MTM": 17982571, "notional": 18087935, "activeTrades": 163 }, - { "id": 207, "date": 1382572800000, "IM": 1612703, "MTM": 16604108, "notional": 16037190, "activeTrades": 125 }, - { "id": 208, "date": 1382659200000, "IM": 1446693, "MTM": 17116492, "notional": 19229868, "activeTrades": 176 }, - { "id": 209, "date": 1382745600000, "IM": 1339141, "MTM": 11733203, "notional": 11356573, "activeTrades": 112 }, - { "id": 210, "date": 1382832000000, "IM": 1313244, "MTM": 17794630, "notional": 16836150, "activeTrades": 146 }, - { "id": 211, "date": 1382918400000, "IM": 1033110, "MTM": 12608532, "notional": 11236434, "activeTrades": 114 }, - { "id": 212, "date": 1383004800000, "IM": 1461876, "MTM": 10825029, "notional": 12047329, "activeTrades": 189 }, - { "id": 213, "date": 1383091200000, "IM": 1550320, "MTM": 11594571, "notional": 17118218, "activeTrades": 178 }, - { "id": 214, "date": 1383177600000, "IM": 1785916, "MTM": 10404344, "notional": 13885222, "activeTrades": 187 }, - { "id": 215, "date": 1383264000000, "IM": 1177683, "MTM": 11851629, "notional": 11292670, "activeTrades": 119 }, - { "id": 216, "date": 1383350400000, "IM": 1681654, "MTM": 11457035, "notional": 14567432, "activeTrades": 123 }, - { "id": 217, "date": 1383436800000, "IM": 1964962, "MTM": 18818802, "notional": 18419911, "activeTrades": 174 }, - { "id": 218, "date": 1383523200000, "IM": 1939422, "MTM": 17033036, "notional": 14633031, "activeTrades": 101 }, - { "id": 219, "date": 1383609600000, "IM": 1870248, "MTM": 17137565, "notional": 17483987, "activeTrades": 100 }, - { "id": 220, "date": 1383696000000, "IM": 1040893, "MTM": 11648347, "notional": 12161540, "activeTrades": 173 }, - { "id": 221, "date": 1383782400000, "IM": 1437568, "MTM": 18731962, "notional": 10946895, "activeTrades": 191 }, - { "id": 222, "date": 1383868800000, "IM": 1857026, "MTM": 13753469, "notional": 15866673, "activeTrades": 186 }, - { "id": 223, "date": 1383955200000, "IM": 1215897, "MTM": 12683534, "notional": 13587822, "activeTrades": 154 }, - { "id": 224, "date": 1384041600000, "IM": 1617038, "MTM": 13050399, "notional": 18041374, "activeTrades": 133 }, - { "id": 225, "date": 1384128000000, "IM": 1558272, "MTM": 11697025, "notional": 12270915, "activeTrades": 151 }, - { "id": 226, "date": 1384214400000, "IM": 1058196, "MTM": 12389117, "notional": 15907393, "activeTrades": 151 }, - { "id": 227, "date": 1384300800000, "IM": 1526241, "MTM": 19449190, "notional": 19206652, "activeTrades": 176 }, - { "id": 228, "date": 1384387200000, "IM": 1063567, "MTM": 15070468, "notional": 10408471, "activeTrades": 168 }, - { "id": 229, "date": 1384473600000, "IM": 1291252, "MTM": 17322900, "notional": 11702063, "activeTrades": 124 }, - { "id": 230, "date": 1384560000000, "IM": 1316156, "MTM": 14388126, "notional": 17403664, "activeTrades": 168 }, - { "id": 231, "date": 1384646400000, "IM": 1140831, "MTM": 11244792, "notional": 11008595, "activeTrades": 196 }, - { "id": 232, "date": 1384732800000, "IM": 1426562, "MTM": 15023197, "notional": 11275775, "activeTrades": 189 }, - { "id": 233, "date": 1384819200000, "IM": 1785048, "MTM": 19790122, "notional": 12512234, "activeTrades": 105 }, - { "id": 234, "date": 1384905600000, "IM": 1227159, "MTM": 19841143, "notional": 16143302, "activeTrades": 169 }, - { "id": 235, "date": 1384992000000, "IM": 1310400, "MTM": 18728637, "notional": 12930259, "activeTrades": 113 }, - { "id": 236, "date": 1385078400000, "IM": 1126800, "MTM": 19675311, "notional": 16135405, "activeTrades": 126 }, - { "id": 237, "date": 1385164800000, "IM": 1530518, "MTM": 11096275, "notional": 16338875, "activeTrades": 181 }, - { "id": 238, "date": 1385251200000, "IM": 1770570, "MTM": 16511670, "notional": 12642609, "activeTrades": 137 }, - { "id": 239, "date": 1385337600000, "IM": 1734538, "MTM": 18200130, "notional": 19383894, "activeTrades": 127 }, - { "id": 240, "date": 1385424000000, "IM": 1719403, "MTM": 17802502, "notional": 16341134, "activeTrades": 159 }, - { "id": 241, "date": 1385510400000, "IM": 1292289, "MTM": 18337491, "notional": 19263481, "activeTrades": 171 }, - { "id": 242, "date": 1385596800000, "IM": 1149316, "MTM": 10858864, "notional": 19480103, "activeTrades": 125 }, - { "id": 243, "date": 1385683200000, "IM": 1703467, "MTM": 18275620, "notional": 16106753, "activeTrades": 145 }, - { "id": 244, "date": 1385769600000, "IM": 1062408, "MTM": 12743472, "notional": 15666155, "activeTrades": 150 }, - { "id": 245, "date": 1385856000000, "IM": 1050046, "MTM": 11261197, "notional": 16418144, "activeTrades": 194 }, - { "id": 246, "date": 1385942400000, "IM": 1549840, "MTM": 19441982, "notional": 18503398, "activeTrades": 185 }, - { "id": 247, "date": 1386028800000, "IM": 1038708, "MTM": 16226021, "notional": 11913020, "activeTrades": 180 }, - { "id": 248, "date": 1386115200000, "IM": 1153296, "MTM": 13107659, "notional": 19985208, "activeTrades": 153 }, - { "id": 249, "date": 1386201600000, "IM": 1827751, "MTM": 17900523, "notional": 18795310, "activeTrades": 133 }, - { "id": 250, "date": 1386288000000, "IM": 1962642, "MTM": 13237813, "notional": 18521352, "activeTrades": 156 }, - { "id": 251, "date": 1386374400000, "IM": 1500516, "MTM": 10844744, "notional": 12390077, "activeTrades": 195 }, - { "id": 252, "date": 1386460800000, "IM": 1481320, "MTM": 19676192, "notional": 19075133, "activeTrades": 134 }, - { "id": 253, "date": 1386547200000, "IM": 1292355, "MTM": 13800578, "notional": 10910329, "activeTrades": 123 }, - { "id": 254, "date": 1386633600000, "IM": 1398357, "MTM": 12728234, "notional": 13877462, "activeTrades": 148 }, - { "id": 255, "date": 1386720000000, "IM": 1884890, "MTM": 11219302, "notional": 14250620, "activeTrades": 156 }, - { "id": 256, "date": 1386806400000, "IM": 1458148, "MTM": 12649460, "notional": 16371667, "activeTrades": 178 }, - { "id": 257, "date": 1386892800000, "IM": 1232526, "MTM": 15002916, "notional": 12938773, "activeTrades": 200 }, - { "id": 258, "date": 1386979200000, "IM": 1100100, "MTM": 18571118, "notional": 11671080, "activeTrades": 146 }, - { "id": 259, "date": 1387065600000, "IM": 1054797, "MTM": 19857329, "notional": 10581922, "activeTrades": 170 }, - { "id": 260, "date": 1387152000000, "IM": 1880930, "MTM": 13819789, "notional": 19273332, "activeTrades": 137 }, - { "id": 261, "date": 1387238400000, "IM": 1177842, "MTM": 10114693, "notional": 17734658, "activeTrades": 189 }, - { "id": 262, "date": 1387324800000, "IM": 1752672, "MTM": 19389922, "notional": 18274305, "activeTrades": 140 }, - { "id": 263, "date": 1387411200000, "IM": 1006906, "MTM": 13649027, "notional": 16056600, "activeTrades": 124 }, - { "id": 264, "date": 1387497600000, "IM": 1937684, "MTM": 19596211, "notional": 16789301, "activeTrades": 180 }, - { "id": 265, "date": 1387584000000, "IM": 1096029, "MTM": 15714722, "notional": 11894299, "activeTrades": 198 }, - { "id": 266, "date": 1387670400000, "IM": 1347788, "MTM": 14822683, "notional": 18960890, "activeTrades": 112 }, - { "id": 267, "date": 1387756800000, "IM": 1940584, "MTM": 15856837, "notional": 19154208, "activeTrades": 161 }, - { "id": 268, "date": 1387843200000, "IM": 1179078, "MTM": 18211191, "notional": 10906684, "activeTrades": 110 }, - { "id": 269, "date": 1387929600000, "IM": 1934442, "MTM": 12508994, "notional": 14045868, "activeTrades": 133 }, - { "id": 270, "date": 1388016000000, "IM": 1150184, "MTM": 18714763, "notional": 12896887, "activeTrades": 154 }, - { "id": 271, "date": 1388102400000, "IM": 1526926, "MTM": 15223842, "notional": 11475051, "activeTrades": 192 }, - { "id": 272, "date": 1388188800000, "IM": 1123101, "MTM": 15447625, "notional": 11584535, "activeTrades": 199 }, - { "id": 273, "date": 1388275200000, "IM": 1522278, "MTM": 19932721, "notional": 13392820, "activeTrades": 157 }, - { "id": 274, "date": 1388361600000, "IM": 1018607, "MTM": 12838000, "notional": 14919104, "activeTrades": 134 }, - { "id": 275, "date": 1388448000000, "IM": 1771904, "MTM": 15229754, "notional": 11124744, "activeTrades": 196 }, - { "id": 276, "date": 1388534400000, "IM": 1805899, "MTM": 10248189, "notional": 18624884, "activeTrades": 157 }, - { "id": 277, "date": 1388620800000, "IM": 1859509, "MTM": 10283501, "notional": 10981099, "activeTrades": 117 }, - { "id": 278, "date": 1388707200000, "IM": 1343409, "MTM": 10144431, "notional": 13913502, "activeTrades": 185 }, - { "id": 279, "date": 1388793600000, "IM": 1581769, "MTM": 19072187, "notional": 14282429, "activeTrades": 101 }, - { "id": 280, "date": 1388880000000, "IM": 1020003, "MTM": 18741980, "notional": 18163783, "activeTrades": 120 }, - { "id": 281, "date": 1388966400000, "IM": 1399410, "MTM": 14281826, "notional": 17505996, "activeTrades": 147 }, - { "id": 282, "date": 1389052800000, "IM": 1899970, "MTM": 19858478, "notional": 16968288, "activeTrades": 103 }, - { "id": 283, "date": 1389139200000, "IM": 1566644, "MTM": 18496738, "notional": 14166995, "activeTrades": 135 }, - { "id": 284, "date": 1389225600000, "IM": 1165467, "MTM": 19215904, "notional": 15377121, "activeTrades": 158 }, - { "id": 285, "date": 1389312000000, "IM": 1765792, "MTM": 14814826, "notional": 15562282, "activeTrades": 168 }, - { "id": 286, "date": 1389398400000, "IM": 1145412, "MTM": 12171623, "notional": 15139624, "activeTrades": 200 }, - { "id": 287, "date": 1389484800000, "IM": 1782891, "MTM": 17746322, "notional": 19325958, "activeTrades": 172 }, - { "id": 288, "date": 1389571200000, "IM": 1724144, "MTM": 10778023, "notional": 15517914, "activeTrades": 134 }, - { "id": 289, "date": 1389657600000, "IM": 1196572, "MTM": 18183072, "notional": 11977792, "activeTrades": 160 }, - { "id": 290, "date": 1389744000000, "IM": 1707973, "MTM": 13496510, "notional": 19721469, "activeTrades": 188 }, - { "id": 291, "date": 1389830400000, "IM": 1146309, "MTM": 16286207, "notional": 17151249, "activeTrades": 182 }, - { "id": 292, "date": 1389916800000, "IM": 1366865, "MTM": 18579195, "notional": 19153205, "activeTrades": 125 }, - { "id": 293, "date": 1390003200000, "IM": 1022646, "MTM": 14046317, "notional": 13655825, "activeTrades": 173 }, - { "id": 294, "date": 1390089600000, "IM": 1094663, "MTM": 11496399, "notional": 13148320, "activeTrades": 172 }, - { "id": 295, "date": 1390176000000, "IM": 1247327, "MTM": 15580264, "notional": 15254304, "activeTrades": 185 }, - { "id": 296, "date": 1390262400000, "IM": 1929233, "MTM": 15659229, "notional": 10127965, "activeTrades": 151 }, - { "id": 297, "date": 1390348800000, "IM": 1926946, "MTM": 19235796, "notional": 16419192, "activeTrades": 131 }, - { "id": 298, "date": 1390435200000, "IM": 1434531, "MTM": 11580607, "notional": 18498565, "activeTrades": 117 }, - { "id": 299, "date": 1390521600000, "IM": 1304857, "MTM": 15963527, "notional": 13100170, "activeTrades": 177 }, - { "id": 300, "date": 1390608000000, "IM": 1208516, "MTM": 11227063, "notional": 14008107, "activeTrades": 193 }, - { "id": 301, "date": 1390694400000, "IM": 1014480, "MTM": 18233854, "notional": 14838771, "activeTrades": 163 }, - { "id": 302, "date": 1390780800000, "IM": 1697723, "MTM": 10862147, "notional": 16420863, "activeTrades": 109 }, - { "id": 303, "date": 1390867200000, "IM": 1490074, "MTM": 10431555, "notional": 18222646, "activeTrades": 135 }, - { "id": 304, "date": 1390953600000, "IM": 1227578, "MTM": 14022680, "notional": 15199533, "activeTrades": 140 }, - { "id": 305, "date": 1391040000000, "IM": 1694410, "MTM": 10476164, "notional": 11786269, "activeTrades": 177 }, - { "id": 306, "date": 1391126400000, "IM": 1217442, "MTM": 15635430, "notional": 19542457, "activeTrades": 140 }, - { "id": 307, "date": 1391212800000, "IM": 1531814, "MTM": 14645117, "notional": 15712587, "activeTrades": 171 }, - { "id": 308, "date": 1391299200000, "IM": 1864745, "MTM": 16526407, "notional": 10363551, "activeTrades": 195 }, - { "id": 309, "date": 1391385600000, "IM": 1897812, "MTM": 16301747, "notional": 12740437, "activeTrades": 121 }, - { "id": 310, "date": 1391472000000, "IM": 1333884, "MTM": 14182681, "notional": 17214193, "activeTrades": 172 }, - { "id": 311, "date": 1391558400000, "IM": 1817472, "MTM": 11760739, "notional": 12961899, "activeTrades": 115 }, - { "id": 312, "date": 1391644800000, "IM": 1324629, "MTM": 17001154, "notional": 13329368, "activeTrades": 114 }, - { "id": 313, "date": 1391731200000, "IM": 1791390, "MTM": 11049045, "notional": 17423293, "activeTrades": 176 }, - { "id": 314, "date": 1391817600000, "IM": 1287666, "MTM": 16872117, "notional": 12900293, "activeTrades": 153 }, - { "id": 315, "date": 1391904000000, "IM": 1691669, "MTM": 12088372, "notional": 15108470, "activeTrades": 109 }, - { "id": 316, "date": 1391990400000, "IM": 1488549, "MTM": 10167762, "notional": 14944059, "activeTrades": 128 }, - { "id": 317, "date": 1392076800000, "IM": 1655551, "MTM": 19531759, "notional": 19403181, "activeTrades": 151 }, - { "id": 318, "date": 1392163200000, "IM": 1749659, "MTM": 12999802, "notional": 13118020, "activeTrades": 153 }, - { "id": 319, "date": 1392249600000, "IM": 1255079, "MTM": 17401503, "notional": 13998047, "activeTrades": 164 }, - { "id": 320, "date": 1392336000000, "IM": 1654093, "MTM": 11736229, "notional": 15610264, "activeTrades": 151 }, - { "id": 321, "date": 1392422400000, "IM": 1942807, "MTM": 19520876, "notional": 12538927, "activeTrades": 113 }, - { "id": 322, "date": 1392508800000, "IM": 1489822, "MTM": 14800019, "notional": 18349629, "activeTrades": 144 }, - { "id": 323, "date": 1392595200000, "IM": 1226677, "MTM": 19563975, "notional": 12417469, "activeTrades": 151 }, - { "id": 324, "date": 1392681600000, "IM": 1862237, "MTM": 19682467, "notional": 12708149, "activeTrades": 110 }, - { "id": 325, "date": 1392768000000, "IM": 1054504, "MTM": 13241191, "notional": 14688356, "activeTrades": 195 }, - { "id": 326, "date": 1392854400000, "IM": 1610321, "MTM": 16731366, "notional": 15780773, "activeTrades": 152 }, - { "id": 327, "date": 1392940800000, "IM": 1387087, "MTM": 17152328, "notional": 15980517, "activeTrades": 183 }, - { "id": 328, "date": 1393027200000, "IM": 1323546, "MTM": 16511775, "notional": 17377814, "activeTrades": 182 }, - { "id": 329, "date": 1393113600000, "IM": 1172604, "MTM": 12603878, "notional": 15024821, "activeTrades": 146 }, - { "id": 330, "date": 1393200000000, "IM": 1188371, "MTM": 15489057, "notional": 14513507, "activeTrades": 153 }, - { "id": 331, "date": 1393286400000, "IM": 1214083, "MTM": 11809362, "notional": 12769583, "activeTrades": 174 }, - { "id": 332, "date": 1393372800000, "IM": 1791324, "MTM": 17366662, "notional": 15167865, "activeTrades": 194 }, - { "id": 333, "date": 1393459200000, "IM": 1873823, "MTM": 12691685, "notional": 14749495, "activeTrades": 173 }, - { "id": 334, "date": 1393545600000, "IM": 1619959, "MTM": 17457259, "notional": 13803429, "activeTrades": 163 }, - { "id": 335, "date": 1393632000000, "IM": 1786951, "MTM": 19627560, "notional": 13732198, "activeTrades": 122 }, - { "id": 336, "date": 1393718400000, "IM": 1128879, "MTM": 18272972, "notional": 14899325, "activeTrades": 157 }, - { "id": 337, "date": 1393804800000, "IM": 1705506, "MTM": 15849271, "notional": 17362945, "activeTrades": 125 }, - { "id": 338, "date": 1393891200000, "IM": 1146126, "MTM": 19614201, "notional": 14586536, "activeTrades": 141 }, - { "id": 339, "date": 1393977600000, "IM": 1674908, "MTM": 11611880, "notional": 15648439, "activeTrades": 167 }, - { "id": 340, "date": 1394064000000, "IM": 1614999, "MTM": 11498747, "notional": 18321022, "activeTrades": 146 }, - { "id": 341, "date": 1394150400000, "IM": 1682159, "MTM": 13747859, "notional": 12608734, "activeTrades": 100 }, - { "id": 342, "date": 1394236800000, "IM": 1610931, "MTM": 15936335, "notional": 11074903, "activeTrades": 134 }, - { "id": 343, "date": 1394323200000, "IM": 1751736, "MTM": 12977444, "notional": 16708600, "activeTrades": 132 }, - { "id": 344, "date": 1394409600000, "IM": 1707968, "MTM": 16793511, "notional": 14081132, "activeTrades": 131 }, - { "id": 345, "date": 1394496000000, "IM": 1795275, "MTM": 11723436, "notional": 14883410, "activeTrades": 188 }, - { "id": 346, "date": 1394582400000, "IM": 1012266, "MTM": 13622737, "notional": 19799082, "activeTrades": 182 }, - { "id": 347, "date": 1394668800000, "IM": 1719818, "MTM": 15728893, "notional": 17214291, "activeTrades": 187 }, - { "id": 348, "date": 1394755200000, "IM": 1948895, "MTM": 10138153, "notional": 14200899, "activeTrades": 159 }, - { "id": 349, "date": 1394841600000, "IM": 1236189, "MTM": 18386802, "notional": 14410467, "activeTrades": 105 }, - { "id": 350, "date": 1394928000000, "IM": 1584581, "MTM": 12779867, "notional": 16033849, "activeTrades": 107 }, - { "id": 351, "date": 1395014400000, "IM": 1110887, "MTM": 13495886, "notional": 16769190, "activeTrades": 171 }, - { "id": 352, "date": 1395100800000, "IM": 1441039, "MTM": 10550629, "notional": 10751176, "activeTrades": 143 }, - { "id": 353, "date": 1395187200000, "IM": 1297672, "MTM": 17316282, "notional": 16954429, "activeTrades": 187 }, - { "id": 354, "date": 1395273600000, "IM": 1412747, "MTM": 17730519, "notional": 14850738, "activeTrades": 194 }, - { "id": 355, "date": 1395360000000, "IM": 1994987, "MTM": 10772521, "notional": 19262503, "activeTrades": 194 }, - { "id": 356, "date": 1395446400000, "IM": 1036695, "MTM": 16925141, "notional": 17660043, "activeTrades": 176 }, - { "id": 357, "date": 1395532800000, "IM": 1348292, "MTM": 12593942, "notional": 13041825, "activeTrades": 179 }, - { "id": 358, "date": 1395619200000, "IM": 1977703, "MTM": 18006137, "notional": 14532065, "activeTrades": 167 }, - { "id": 359, "date": 1395705600000, "IM": 1178214, "MTM": 16492402, "notional": 10361784, "activeTrades": 104 }, - { "id": 360, "date": 1395792000000, "IM": 1297399, "MTM": 17809049, "notional": 17594950, "activeTrades": 121 }, - { "id": 361, "date": 1395878400000, "IM": 1460711, "MTM": 18871390, "notional": 18178872, "activeTrades": 116 }, - { "id": 362, "date": 1395964800000, "IM": 1368552, "MTM": 10608448, "notional": 16636546, "activeTrades": 195 }, - { "id": 363, "date": 1396051200000, "IM": 1663658, "MTM": 18531141, "notional": 11398664, "activeTrades": 145 }, - { "id": 364, "date": 1396137600000, "IM": 1029170, "MTM": 11929127, "notional": 11594952, "activeTrades": 130 }, - { "id": 365, "date": 1396224000000, "IM": 1618245, "MTM": 15221508, "notional": 13747366, "activeTrades": 182 }, - { "id": 366, "date": 1396310400000, "IM": 1085418, "MTM": 19633763, "notional": 12296227, "activeTrades": 147 }, - { "id": 367, "date": 1396396800000, "IM": 1684040, "MTM": 11301823, "notional": 19576137, "activeTrades": 158 }, - { "id": 368, "date": 1396483200000, "IM": 1620564, "MTM": 17186000, "notional": 18945036, "activeTrades": 105 }, - { "id": 369, "date": 1396569600000, "IM": 1949893, "MTM": 11709449, "notional": 16836307, "activeTrades": 189 }, - { "id": 370, "date": 1396656000000, "IM": 1147102, "MTM": 13184605, "notional": 11629997, "activeTrades": 155 }, - { "id": 371, "date": 1396742400000, "IM": 1277460, "MTM": 14129619, "notional": 13842240, "activeTrades": 153 }, - { "id": 372, "date": 1396828800000, "IM": 1748677, "MTM": 15087903, "notional": 13099013, "activeTrades": 163 }, - { "id": 373, "date": 1396915200000, "IM": 1091276, "MTM": 15475631, "notional": 18312616, "activeTrades": 149 }, - { "id": 374, "date": 1397001600000, "IM": 1632525, "MTM": 18767010, "notional": 12290245, "activeTrades": 118 }, - { "id": 375, "date": 1397088000000, "IM": 1407055, "MTM": 18569815, "notional": 19265347, "activeTrades": 167 }, - { "id": 376, "date": 1397174400000, "IM": 1733794, "MTM": 10803314, "notional": 11534358, "activeTrades": 185 }, - { "id": 377, "date": 1397260800000, "IM": 1296641, "MTM": 19766397, "notional": 18644477, "activeTrades": 108 }, - { "id": 378, "date": 1397347200000, "IM": 1833337, "MTM": 10134740, "notional": 13782275, "activeTrades": 188 }, - { "id": 379, "date": 1397433600000, "IM": 1586885, "MTM": 12745387, "notional": 15599227, "activeTrades": 157 }, - { "id": 380, "date": 1397520000000, "IM": 1849481, "MTM": 16510058, "notional": 13371575, "activeTrades": 157 }, - { "id": 381, "date": 1397606400000, "IM": 1406417, "MTM": 14648443, "notional": 17522499, "activeTrades": 197 }, - { "id": 382, "date": 1397692800000, "IM": 1789959, "MTM": 18063985, "notional": 11406810, "activeTrades": 163 }, - { "id": 383, "date": 1397779200000, "IM": 1892406, "MTM": 13070458, "notional": 15719236, "activeTrades": 194 }, - { "id": 384, "date": 1397865600000, "IM": 1946229, "MTM": 12647176, "notional": 19330843, "activeTrades": 162 }, - { "id": 385, "date": 1397952000000, "IM": 1215680, "MTM": 19338077, "notional": 18446955, "activeTrades": 165 }, - { "id": 386, "date": 1398038400000, "IM": 1321085, "MTM": 18178769, "notional": 15428090, "activeTrades": 134 }, - { "id": 387, "date": 1398124800000, "IM": 1560916, "MTM": 13759633, "notional": 19386466, "activeTrades": 113 }, - { "id": 388, "date": 1398211200000, "IM": 1975660, "MTM": 10859952, "notional": 13044979, "activeTrades": 200 }, - { "id": 389, "date": 1398297600000, "IM": 1425776, "MTM": 10517854, "notional": 18139656, "activeTrades": 114 }, - { "id": 390, "date": 1398384000000, "IM": 1788204, "MTM": 17488565, "notional": 11662081, "activeTrades": 150 }, - { "id": 391, "date": 1398470400000, "IM": 1142605, "MTM": 11132013, "notional": 13586301, "activeTrades": 186 }, - { "id": 392, "date": 1398556800000, "IM": 1629345, "MTM": 14172074, "notional": 18383472, "activeTrades": 155 }, - { "id": 393, "date": 1398643200000, "IM": 1120184, "MTM": 18141240, "notional": 15233563, "activeTrades": 167 }, - { "id": 394, "date": 1398729600000, "IM": 1183515, "MTM": 15998957, "notional": 16029414, "activeTrades": 178 }, - { "id": 395, "date": 1398816000000, "IM": 1219148, "MTM": 11725525, "notional": 13835022, "activeTrades": 103 }, - { "id": 396, "date": 1398902400000, "IM": 1949240, "MTM": 15701868, "notional": 17771786, "activeTrades": 129 }, - { "id": 397, "date": 1398988800000, "IM": 1900704, "MTM": 17299519, "notional": 19161350, "activeTrades": 166 }, - { "id": 398, "date": 1399075200000, "IM": 1763518, "MTM": 13654831, "notional": 12241462, "activeTrades": 144 }, - { "id": 399, "date": 1399161600000, "IM": 1441044, "MTM": 10029431, "notional": 11712116, "activeTrades": 121 }, - { "id": 400, "date": 1399248000000, "IM": 1227916, "MTM": 18218790, "notional": 12294877, "activeTrades": 172 }, - { "id": 401, "date": 1399334400000, "IM": 1971099, "MTM": 13565354, "notional": 14368215, "activeTrades": 166 }, - { "id": 402, "date": 1399420800000, "IM": 1398515, "MTM": 14440628, "notional": 19666525, "activeTrades": 166 }, - { "id": 403, "date": 1399507200000, "IM": 1086667, "MTM": 11377103, "notional": 19859713, "activeTrades": 119 }, - { "id": 404, "date": 1399593600000, "IM": 1861520, "MTM": 10925356, "notional": 13532212, "activeTrades": 196 }, - { "id": 405, "date": 1399680000000, "IM": 1624161, "MTM": 17029027, "notional": 10732362, "activeTrades": 120 }, - { "id": 406, "date": 1399766400000, "IM": 1660392, "MTM": 12179341, "notional": 13317571, "activeTrades": 106 }, - { "id": 407, "date": 1399852800000, "IM": 1946067, "MTM": 15093662, "notional": 17998551, "activeTrades": 143 }, - { "id": 408, "date": 1399939200000, "IM": 1054844, "MTM": 14591322, "notional": 15201940, "activeTrades": 172 }, - { "id": 409, "date": 1400025600000, "IM": 1087577, "MTM": 11500439, "notional": 16709964, "activeTrades": 184 }, - { "id": 410, "date": 1400112000000, "IM": 1130289, "MTM": 17323722, "notional": 15602653, "activeTrades": 148 }, - { "id": 411, "date": 1400198400000, "IM": 1632981, "MTM": 18290551, "notional": 19546441, "activeTrades": 163 }, - { "id": 412, "date": 1400284800000, "IM": 1606050, "MTM": 12253204, "notional": 14952654, "activeTrades": 133 }, - { "id": 413, "date": 1400371200000, "IM": 1278442, "MTM": 14116028, "notional": 14600985, "activeTrades": 122 }, - { "id": 414, "date": 1400457600000, "IM": 1873980, "MTM": 11186695, "notional": 11267703, "activeTrades": 128 }, - { "id": 415, "date": 1400544000000, "IM": 1906623, "MTM": 17674951, "notional": 15569473, "activeTrades": 125 }, - { "id": 416, "date": 1400630400000, "IM": 1374546, "MTM": 11688511, "notional": 13522441, "activeTrades": 122 }, - { "id": 417, "date": 1400716800000, "IM": 1873152, "MTM": 15199191, "notional": 18618056, "activeTrades": 192 }, - { "id": 418, "date": 1400803200000, "IM": 1590206, "MTM": 19713126, "notional": 13127422, "activeTrades": 143 }, - { "id": 419, "date": 1400889600000, "IM": 1889268, "MTM": 11531918, "notional": 18122105, "activeTrades": 124 }, - { "id": 420, "date": 1400976000000, "IM": 1769672, "MTM": 16525248, "notional": 15346207, "activeTrades": 112 }, - { "id": 421, "date": 1401062400000, "IM": 1507524, "MTM": 12274956, "notional": 19121860, "activeTrades": 147 }, - { "id": 422, "date": 1401148800000, "IM": 1272319, "MTM": 13493788, "notional": 16494511, "activeTrades": 110 }, - { "id": 423, "date": 1401235200000, "IM": 1710951, "MTM": 15687372, "notional": 14014438, "activeTrades": 193 }, - { "id": 424, "date": 1401321600000, "IM": 1746296, "MTM": 13658800, "notional": 10745147, "activeTrades": 154 }, - { "id": 425, "date": 1401408000000, "IM": 1034947, "MTM": 14859655, "notional": 15643135, "activeTrades": 117 }, - { "id": 426, "date": 1401494400000, "IM": 1624378, "MTM": 14276853, "notional": 19224028, "activeTrades": 135 }, - { "id": 427, "date": 1401580800000, "IM": 1158865, "MTM": 16254389, "notional": 16988263, "activeTrades": 121 }, - { "id": 428, "date": 1401667200000, "IM": 1013212, "MTM": 12120393, "notional": 19743658, "activeTrades": 109 }, - { "id": 429, "date": 1401753600000, "IM": 1676279, "MTM": 16787299, "notional": 13913579, "activeTrades": 190 }, - { "id": 430, "date": 1401840000000, "IM": 1081276, "MTM": 13782365, "notional": 17901210, "activeTrades": 100 }, - { "id": 431, "date": 1401926400000, "IM": 1032239, "MTM": 10398910, "notional": 19055245, "activeTrades": 164 }, - { "id": 432, "date": 1402012800000, "IM": 1219361, "MTM": 18555401, "notional": 14333302, "activeTrades": 187 }, - { "id": 433, "date": 1402099200000, "IM": 1052763, "MTM": 14119032, "notional": 10926019, "activeTrades": 133 }, - { "id": 434, "date": 1402185600000, "IM": 1608949, "MTM": 14234958, "notional": 15279500, "activeTrades": 129 }, - { "id": 435, "date": 1402272000000, "IM": 1010889, "MTM": 12288400, "notional": 19402128, "activeTrades": 156 }, - { "id": 436, "date": 1402358400000, "IM": 1996887, "MTM": 18813297, "notional": 12873465, "activeTrades": 164 }, - { "id": 437, "date": 1402444800000, "IM": 1738662, "MTM": 14414327, "notional": 16662302, "activeTrades": 126 }, - { "id": 438, "date": 1402531200000, "IM": 1253289, "MTM": 16555755, "notional": 13230096, "activeTrades": 180 }, - { "id": 439, "date": 1402617600000, "IM": 1704635, "MTM": 18467582, "notional": 12419790, "activeTrades": 137 }, - { "id": 440, "date": 1402704000000, "IM": 1078436, "MTM": 14228368, "notional": 11280494, "activeTrades": 189 }, - { "id": 441, "date": 1402790400000, "IM": 1801093, "MTM": 18410826, "notional": 14786044, "activeTrades": 178 }, - { "id": 442, "date": 1402876800000, "IM": 1439145, "MTM": 13574880, "notional": 15624997, "activeTrades": 150 }, - { "id": 443, "date": 1402963200000, "IM": 1711911, "MTM": 18160944, "notional": 10714153, "activeTrades": 179 }, - { "id": 444, "date": 1403049600000, "IM": 1102786, "MTM": 16186654, "notional": 18812722, "activeTrades": 157 }, - { "id": 445, "date": 1403136000000, "IM": 1465138, "MTM": 12455275, "notional": 14383681, "activeTrades": 181 }, - { "id": 446, "date": 1403222400000, "IM": 1700027, "MTM": 17545128, "notional": 18570646, "activeTrades": 108 }, - { "id": 447, "date": 1403308800000, "IM": 1691257, "MTM": 15538415, "notional": 19077103, "activeTrades": 113 }, - { "id": 448, "date": 1403395200000, "IM": 1959805, "MTM": 18249613, "notional": 16311514, "activeTrades": 140 }, - { "id": 449, "date": 1403481600000, "IM": 1790010, "MTM": 14433229, "notional": 13862868, "activeTrades": 144 }, - { "id": 450, "date": 1403568000000, "IM": 1384790, "MTM": 11091035, "notional": 19227235, "activeTrades": 105 }, - { "id": 451, "date": 1403654400000, "IM": 1343185, "MTM": 18346520, "notional": 14845198, "activeTrades": 155 }, - { "id": 452, "date": 1403740800000, "IM": 1996114, "MTM": 14278289, "notional": 18002239, "activeTrades": 172 }, - { "id": 453, "date": 1403827200000, "IM": 1753418, "MTM": 18898090, "notional": 17544556, "activeTrades": 180 }, - { "id": 454, "date": 1403913600000, "IM": 1975458, "MTM": 15685828, "notional": 12283141, "activeTrades": 189 }, - { "id": 455, "date": 1404000000000, "IM": 1845344, "MTM": 19013882, "notional": 13698027, "activeTrades": 122 }, - { "id": 456, "date": 1404086400000, "IM": 1399699, "MTM": 12659464, "notional": 19171447, "activeTrades": 190 }, - { "id": 457, "date": 1404172800000, "IM": 1896914, "MTM": 15505095, "notional": 16925715, "activeTrades": 108 }, - { "id": 458, "date": 1404259200000, "IM": 1878554, "MTM": 11439841, "notional": 16526768, "activeTrades": 153 }, - { "id": 459, "date": 1404345600000, "IM": 1864707, "MTM": 18148849, "notional": 12031637, "activeTrades": 156 }, - { "id": 460, "date": 1404432000000, "IM": 1945854, "MTM": 13169209, "notional": 19929002, "activeTrades": 161 }, - { "id": 461, "date": 1404518400000, "IM": 1823928, "MTM": 11476485, "notional": 14803502, "activeTrades": 199 }, - { "id": 462, "date": 1404604800000, "IM": 1476536, "MTM": 15949295, "notional": 18868393, "activeTrades": 161 }, - { "id": 463, "date": 1404691200000, "IM": 1426729, "MTM": 10389308, "notional": 15645063, "activeTrades": 161 }, - { "id": 464, "date": 1404777600000, "IM": 1570589, "MTM": 14558461, "notional": 19189013, "activeTrades": 136 }, - { "id": 465, "date": 1404864000000, "IM": 1225134, "MTM": 10525234, "notional": 12794968, "activeTrades": 191 }, - { "id": 466, "date": 1404950400000, "IM": 1646447, "MTM": 12091571, "notional": 17345671, "activeTrades": 188 }, - { "id": 467, "date": 1405036800000, "IM": 1328823, "MTM": 10360714, "notional": 13323595, "activeTrades": 134 }, - { "id": 468, "date": 1405123200000, "IM": 1410735, "MTM": 14161479, "notional": 16378974, "activeTrades": 169 }, - { "id": 469, "date": 1405209600000, "IM": 1636885, "MTM": 17435420, "notional": 18082158, "activeTrades": 135 }, - { "id": 470, "date": 1405296000000, "IM": 1417433, "MTM": 15211873, "notional": 19169478, "activeTrades": 180 }, - { "id": 471, "date": 1405382400000, "IM": 1819946, "MTM": 14301899, "notional": 17782540, "activeTrades": 123 }, - { "id": 472, "date": 1405468800000, "IM": 1570268, "MTM": 16495740, "notional": 10408291, "activeTrades": 101 }, - { "id": 473, "date": 1405555200000, "IM": 1410182, "MTM": 15001368, "notional": 12099802, "activeTrades": 124 }, - { "id": 474, "date": 1405641600000, "IM": 1164751, "MTM": 14493386, "notional": 10924661, "activeTrades": 112 }, - { "id": 475, "date": 1405728000000, "IM": 1765857, "MTM": 13823751, "notional": 18439049, "activeTrades": 165 }, - { "id": 476, "date": 1405814400000, "IM": 1877212, "MTM": 14137178, "notional": 14824064, "activeTrades": 155 }, - { "id": 477, "date": 1405900800000, "IM": 1154781, "MTM": 11702529, "notional": 15733396, "activeTrades": 179 }, - { "id": 478, "date": 1405987200000, "IM": 1196551, "MTM": 19009660, "notional": 14605184, "activeTrades": 155 }, - { "id": 479, "date": 1406073600000, "IM": 1728956, "MTM": 19115481, "notional": 12284821, "activeTrades": 123 }, - { "id": 480, "date": 1406160000000, "IM": 1656539, "MTM": 11154293, "notional": 14114530, "activeTrades": 151 }, - { "id": 481, "date": 1406246400000, "IM": 1668125, "MTM": 12901113, "notional": 13193990, "activeTrades": 193 }, - { "id": 482, "date": 1406332800000, "IM": 1456243, "MTM": 16563229, "notional": 11173038, "activeTrades": 174 }, - { "id": 483, "date": 1406419200000, "IM": 1220749, "MTM": 19137582, "notional": 16251821, "activeTrades": 169 }, - { "id": 484, "date": 1406505600000, "IM": 1101641, "MTM": 19287673, "notional": 17752901, "activeTrades": 148 }, - { "id": 485, "date": 1406592000000, "IM": 1511552, "MTM": 11504985, "notional": 14596259, "activeTrades": 135 }, - { "id": 486, "date": 1406678400000, "IM": 1203290, "MTM": 12152544, "notional": 17956987, "activeTrades": 114 }, - { "id": 487, "date": 1406764800000, "IM": 1464086, "MTM": 18100770, "notional": 10508866, "activeTrades": 161 }, - { "id": 488, "date": 1406851200000, "IM": 1925641, "MTM": 12654835, "notional": 16718482, "activeTrades": 164 }, - { "id": 489, "date": 1406937600000, "IM": 1638046, "MTM": 14991766, "notional": 14506776, "activeTrades": 101 }, - { "id": 490, "date": 1407024000000, "IM": 1101418, "MTM": 16640900, "notional": 18532129, "activeTrades": 198 }, - { "id": 491, "date": 1407110400000, "IM": 1066836, "MTM": 10177160, "notional": 16585532, "activeTrades": 116 }, - { "id": 492, "date": 1407196800000, "IM": 1421447, "MTM": 16092975, "notional": 13273450, "activeTrades": 110 }, - { "id": 493, "date": 1407283200000, "IM": 1198352, "MTM": 10603486, "notional": 17912970, "activeTrades": 198 }, - { "id": 494, "date": 1407369600000, "IM": 1461667, "MTM": 11996600, "notional": 18196776, "activeTrades": 194 }, - { "id": 495, "date": 1407456000000, "IM": 1891045, "MTM": 10965037, "notional": 15399742, "activeTrades": 174 }, - { "id": 496, "date": 1407542400000, "IM": 1374815, "MTM": 16569840, "notional": 11759051, "activeTrades": 149 }, - { "id": 497, "date": 1407628800000, "IM": 1296234, "MTM": 10868767, "notional": 15375616, "activeTrades": 120 }, - { "id": 498, "date": 1407715200000, "IM": 1179899, "MTM": 12984200, "notional": 19685434, "activeTrades": 140 }, - { "id": 499, "date": 1407801600000, "IM": 1370472, "MTM": 12305613, "notional": 18815041, "activeTrades": 176 }, - { "id": 500, "date": 1407888000000, "IM": 1827185, "MTM": 10073451, "notional": 15680629, "activeTrades": 178 } -] diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/valuations b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/valuations deleted file mode 100644 index 3866519636..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/portfolio/valuations +++ /dev/null @@ -1,3 +0,0 @@ -{ - "businessDate": "2016-09-31" -} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/trades b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/trades deleted file mode 100644 index 3728a7f8e8..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/bank-c/trades +++ /dev/null @@ -1,251 +0,0 @@ -[{ "id": 1, "product": "Vanilla IRS", "tradeDate": "2016-04-09", "effectiveDate": "2015-07-17", "maturityDate": "2016-01-10", "currency": "EUR", "notional": 379901, "IM": 360734, "MTM": 748773, "margined": true }, - { "id": 2, "product": "Vanilla IRS", "tradeDate": "2015-09-04", "effectiveDate": "2016-02-26", "maturityDate": "2016-07-12", "currency": "EUR", "notional": 435010, "IM": 935916, "MTM": 205601, "margined": true }, - { "id": 3, "product": "Vanilla IRS", "tradeDate": "2016-03-19", "effectiveDate": "2016-04-22", "maturityDate": "2015-08-06", "currency": "EUR", "notional": 902645, "IM": 521639, "MTM": 801987, "margined": true }, - { "id": 4, "product": "Vanilla IRS", "tradeDate": "2015-02-15", "effectiveDate": "2015-11-04", "maturityDate": "2015-06-19", "currency": "EUR", "notional": 801838, "IM": 296955, "MTM": 538946, "margined": true }, - { "id": 5, "product": "Vanilla IRS", "tradeDate": "2015-06-07", "effectiveDate": "2015-03-02", "maturityDate": "2016-07-08", "currency": "EUR", "notional": 705350, "IM": 698637, "MTM": 367028, "margined": true }, - { "id": 6, "product": "Vanilla IRS", "tradeDate": "2016-03-02", "effectiveDate": "2015-10-14", "maturityDate": "2015-08-19", "currency": "EUR", "notional": 467636, "IM": 851486, "MTM": 483235, "margined": true }, - { "id": 7, "product": "Vanilla IRS", "tradeDate": "2015-01-27", "effectiveDate": "2015-12-17", "maturityDate": "2015-07-16", "currency": "EUR", "notional": 533406, "IM": 280695, "MTM": 867550, "margined": true }, - { "id": 8, "product": "Vanilla IRS", "tradeDate": "2015-01-07", "effectiveDate": "2016-06-05", "maturityDate": "2016-07-02", "currency": "EUR", "notional": 935894, "IM": 305115, "MTM": 683463, "margined": true }, - { "id": 9, "product": "Vanilla IRS", "tradeDate": "2015-06-01", "effectiveDate": "2015-09-19", "maturityDate": "2015-06-04", "currency": "EUR", "notional": 936814, "IM": 669743, "MTM": 574835, "margined": true }, - { "id": 10, "product": "Vanilla IRS", "tradeDate": "2016-06-07", "effectiveDate": "2015-10-22", "maturityDate": "2016-02-24", "currency": "EUR", "notional": 786271, "IM": 974797, "MTM": 960390, "margined": true }, - { "id": 11, "product": "Vanilla IRS", "tradeDate": "2015-02-19", "effectiveDate": "2016-06-29", "maturityDate": "2015-07-15", "currency": "EUR", "notional": 351887, "IM": 705757, "MTM": 697884, "margined": true }, - { "id": 12, "product": "Vanilla IRS", "tradeDate": "2015-08-17", "effectiveDate": "2015-10-15", "maturityDate": "2015-01-17", "currency": "EUR", "notional": 774143, "IM": 662081, "MTM": 505141, "margined": true }, - { "id": 13, "product": "Vanilla IRS", "tradeDate": "2015-01-28", "effectiveDate": "2015-10-10", "maturityDate": "2015-10-25", "currency": "EUR", "notional": 252237, "IM": 733135, "MTM": 858173, "margined": true }, - { "id": 14, "product": "Vanilla IRS", "tradeDate": "2015-07-24", "effectiveDate": "2016-05-28", "maturityDate": "2016-06-25", "currency": "EUR", "notional": 383662, "IM": 970200, "MTM": 454450, "margined": true }, - { "id": 15, "product": "Vanilla IRS", "tradeDate": "2016-03-24", "effectiveDate": "2016-07-11", "maturityDate": "2016-04-20", "currency": "EUR", "notional": 919238, "IM": 858857, "MTM": 823940, "margined": true }, - { "id": 16, "product": "Vanilla IRS", "tradeDate": "2015-05-25", "effectiveDate": "2015-09-09", "maturityDate": "2015-02-12", "currency": "EUR", "notional": 277943, "IM": 742446, "MTM": 366786, "margined": true }, - { "id": 17, "product": "Vanilla IRS", "tradeDate": "2015-02-16", "effectiveDate": "2016-04-19", "maturityDate": "2016-07-06", "currency": "EUR", "notional": 453553, "IM": 714356, "MTM": 204144, "margined": true }, - { "id": 18, "product": "Vanilla IRS", "tradeDate": "2016-08-11", "effectiveDate": "2016-06-25", "maturityDate": "2016-04-09", "currency": "EUR", "notional": 980078, "IM": 253491, "MTM": 291619, "margined": true }, - { "id": 19, "product": "Vanilla IRS", "tradeDate": "2015-02-10", "effectiveDate": "2015-05-31", "maturityDate": "2015-10-29", "currency": "EUR", "notional": 801901, "IM": 846874, "MTM": 256072, "margined": true }, - { "id": 20, "product": "Vanilla IRS", "tradeDate": "2016-06-26", "effectiveDate": "2015-10-13", "maturityDate": "2015-12-23", "currency": "EUR", "notional": 297493, "IM": 880052, "MTM": 386186, "margined": true }, - { "id": 21, "product": "Vanilla IRS", "tradeDate": "2016-04-14", "effectiveDate": "2015-05-02", "maturityDate": "2016-04-23", "currency": "EUR", "notional": 755697, "IM": 470870, "MTM": 141983, "margined": true }, - { "id": 22, "product": "Vanilla IRS", "tradeDate": "2016-05-14", "effectiveDate": "2015-04-09", "maturityDate": "2015-03-12", "currency": "EUR", "notional": 570895, "IM": 568584, "MTM": 756590, "margined": true }, - { "id": 23, "product": "Vanilla IRS", "tradeDate": "2016-04-02", "effectiveDate": "2015-11-03", "maturityDate": "2015-01-05", "currency": "EUR", "notional": 347723, "IM": 787941, "MTM": 416687, "margined": true }, - { "id": 24, "product": "Vanilla IRS", "tradeDate": "2016-01-25", "effectiveDate": "2015-05-03", "maturityDate": "2015-05-06", "currency": "EUR", "notional": 304967, "IM": 237842, "MTM": 948630, "margined": true }, - { "id": 25, "product": "Vanilla IRS", "tradeDate": "2015-11-07", "effectiveDate": "2016-05-09", "maturityDate": "2015-11-27", "currency": "EUR", "notional": 256514, "IM": 348983, "MTM": 337163, "margined": true }, - { "id": 26, "product": "Vanilla IRS", "tradeDate": "2015-08-19", "effectiveDate": "2015-05-14", "maturityDate": "2015-07-14", "currency": "EUR", "notional": 286610, "IM": 575365, "MTM": 788386, "margined": true }, - { "id": 27, "product": "Vanilla IRS", "tradeDate": "2016-05-13", "effectiveDate": "2016-04-01", "maturityDate": "2015-02-09", "currency": "EUR", "notional": 410287, "IM": 686287, "MTM": 355748, "margined": true }, - { "id": 28, "product": "Vanilla IRS", "tradeDate": "2015-08-11", "effectiveDate": "2015-02-15", "maturityDate": "2016-02-18", "currency": "EUR", "notional": 395320, "IM": 839265, "MTM": 839939, "margined": true }, - { "id": 29, "product": "Vanilla IRS", "tradeDate": "2015-11-09", "effectiveDate": "2016-05-26", "maturityDate": "2016-02-22", "currency": "EUR", "notional": 718363, "IM": 238423, "MTM": 815547, "margined": true }, - { "id": 30, "product": "Vanilla IRS", "tradeDate": "2015-03-06", "effectiveDate": "2015-05-25", "maturityDate": "2015-06-07", "currency": "EUR", "notional": 719987, "IM": 470712, "MTM": 606781, "margined": true }, - { "id": 31, "product": "Vanilla IRS", "tradeDate": "2015-12-12", "effectiveDate": "2016-03-18", "maturityDate": "2015-11-04", "currency": "EUR", "notional": 914842, "IM": 668384, "MTM": 381560, "margined": true }, - { "id": 32, "product": "Vanilla IRS", "tradeDate": "2015-12-20", "effectiveDate": "2016-03-25", "maturityDate": "2015-11-19", "currency": "EUR", "notional": 416002, "IM": 209134, "MTM": 726968, "margined": true }, - { "id": 33, "product": "Vanilla IRS", "tradeDate": "2016-03-05", "effectiveDate": "2015-12-03", "maturityDate": "2015-10-20", "currency": "EUR", "notional": 921803, "IM": 217855, "MTM": 626271, "margined": true }, - { "id": 34, "product": "Vanilla IRS", "tradeDate": "2015-04-23", "effectiveDate": "2016-02-12", "maturityDate": "2016-05-09", "currency": "EUR", "notional": 381824, "IM": 127137, "MTM": 430121, "margined": true }, - { "id": 35, "product": "Vanilla IRS", "tradeDate": "2015-11-05", "effectiveDate": "2015-12-26", "maturityDate": "2015-07-22", "currency": "EUR", "notional": 231121, "IM": 690371, "MTM": 523352, "margined": true }, - { "id": 36, "product": "Vanilla IRS", "tradeDate": "2015-10-06", "effectiveDate": "2015-02-21", "maturityDate": "2015-08-30", "currency": "EUR", "notional": 307151, "IM": 474940, "MTM": 824829, "margined": true }, - { "id": 37, "product": "Vanilla IRS", "tradeDate": "2016-05-11", "effectiveDate": "2015-02-13", "maturityDate": "2016-01-22", "currency": "EUR", "notional": 188135, "IM": 513467, "MTM": 859530, "margined": true }, - { "id": 38, "product": "Vanilla IRS", "tradeDate": "2016-08-01", "effectiveDate": "2015-05-08", "maturityDate": "2016-03-19", "currency": "EUR", "notional": 825794, "IM": 240275, "MTM": 632997, "margined": true }, - { "id": 39, "product": "Vanilla IRS", "tradeDate": "2015-01-11", "effectiveDate": "2016-01-20", "maturityDate": "2015-09-06", "currency": "EUR", "notional": 137752, "IM": 461840, "MTM": 341537, "margined": true }, - { "id": 40, "product": "Vanilla IRS", "tradeDate": "2016-02-15", "effectiveDate": "2016-03-21", "maturityDate": "2015-02-16", "currency": "EUR", "notional": 977380, "IM": 960650, "MTM": 575656, "margined": true }, - { "id": 41, "product": "Vanilla IRS", "tradeDate": "2016-04-08", "effectiveDate": "2016-03-10", "maturityDate": "2015-06-02", "currency": "EUR", "notional": 892116, "IM": 992207, "MTM": 229471, "margined": true }, - { "id": 42, "product": "Vanilla IRS", "tradeDate": "2015-02-27", "effectiveDate": "2015-03-09", "maturityDate": "2016-04-18", "currency": "EUR", "notional": 780687, "IM": 513569, "MTM": 430389, "margined": true }, - { "id": 43, "product": "Vanilla IRS", "tradeDate": "2015-05-31", "effectiveDate": "2015-03-29", "maturityDate": "2015-02-14", "currency": "EUR", "notional": 527508, "IM": 221797, "MTM": 863389, "margined": true }, - { "id": 44, "product": "Vanilla IRS", "tradeDate": "2015-05-16", "effectiveDate": "2015-04-10", "maturityDate": "2015-03-02", "currency": "EUR", "notional": 155483, "IM": 588045, "MTM": 256669, "margined": true }, - { "id": 45, "product": "Vanilla IRS", "tradeDate": "2015-12-10", "effectiveDate": "2015-06-05", "maturityDate": "2015-10-24", "currency": "EUR", "notional": 436788, "IM": 816545, "MTM": 529090, "margined": true }, - { "id": 46, "product": "Vanilla IRS", "tradeDate": "2015-12-21", "effectiveDate": "2015-09-12", "maturityDate": "2016-03-11", "currency": "EUR", "notional": 638088, "IM": 763757, "MTM": 899542, "margined": true }, - { "id": 47, "product": "Vanilla IRS", "tradeDate": "2015-07-28", "effectiveDate": "2015-03-26", "maturityDate": "2016-07-09", "currency": "EUR", "notional": 223864, "IM": 418690, "MTM": 604640, "margined": true }, - { "id": 48, "product": "Vanilla IRS", "tradeDate": "2016-08-02", "effectiveDate": "2015-07-19", "maturityDate": "2015-12-02", "currency": "EUR", "notional": 963357, "IM": 658121, "MTM": 812159, "margined": true }, - { "id": 49, "product": "Vanilla IRS", "tradeDate": "2015-10-08", "effectiveDate": "2016-04-30", "maturityDate": "2016-04-29", "currency": "EUR", "notional": 867667, "IM": 459073, "MTM": 191807, "margined": true }, - { "id": 50, "product": "Vanilla IRS", "tradeDate": "2015-01-19", "effectiveDate": "2016-04-25", "maturityDate": "2015-09-01", "currency": "EUR", "notional": 401901, "IM": 653763, "MTM": 308748, "margined": true }, - { "id": 51, "product": "Vanilla IRS", "tradeDate": "2015-09-06", "effectiveDate": "2015-10-06", "maturityDate": "2015-11-16", "currency": "EUR", "notional": 228375, "IM": 677679, "MTM": 393348, "margined": true }, - { "id": 52, "product": "Vanilla IRS", "tradeDate": "2016-05-21", "effectiveDate": "2016-01-09", "maturityDate": "2016-03-27", "currency": "EUR", "notional": 330826, "IM": 275412, "MTM": 540542, "margined": true }, - { "id": 53, "product": "Vanilla IRS", "tradeDate": "2015-02-09", "effectiveDate": "2015-11-20", "maturityDate": "2015-05-03", "currency": "EUR", "notional": 758071, "IM": 627724, "MTM": 386657, "margined": true }, - { "id": 54, "product": "Vanilla IRS", "tradeDate": "2015-07-28", "effectiveDate": "2015-03-31", "maturityDate": "2015-07-18", "currency": "EUR", "notional": 959341, "IM": 426966, "MTM": 821734, "margined": true }, - { "id": 55, "product": "Vanilla IRS", "tradeDate": "2015-11-13", "effectiveDate": "2015-08-26", "maturityDate": "2016-01-04", "currency": "EUR", "notional": 341366, "IM": 904617, "MTM": 765865, "margined": true }, - { "id": 56, "product": "Vanilla IRS", "tradeDate": "2015-07-13", "effectiveDate": "2015-12-16", "maturityDate": "2015-03-20", "currency": "EUR", "notional": 460367, "IM": 710303, "MTM": 290556, "margined": true }, - { "id": 57, "product": "Vanilla IRS", "tradeDate": "2015-02-11", "effectiveDate": "2015-06-04", "maturityDate": "2015-06-04", "currency": "EUR", "notional": 463040, "IM": 476802, "MTM": 522112, "margined": true }, - { "id": 58, "product": "Vanilla IRS", "tradeDate": "2015-11-23", "effectiveDate": "2015-04-13", "maturityDate": "2015-12-18", "currency": "EUR", "notional": 128611, "IM": 751296, "MTM": 674892, "margined": true }, - { "id": 59, "product": "Vanilla IRS", "tradeDate": "2015-04-01", "effectiveDate": "2016-02-22", "maturityDate": "2015-11-03", "currency": "EUR", "notional": 808913, "IM": 156923, "MTM": 872471, "margined": true }, - { "id": 60, "product": "Vanilla IRS", "tradeDate": "2015-06-04", "effectiveDate": "2015-04-07", "maturityDate": "2016-04-13", "currency": "EUR", "notional": 487582, "IM": 271296, "MTM": 698236, "margined": true }, - { "id": 61, "product": "Vanilla IRS", "tradeDate": "2016-08-01", "effectiveDate": "2015-09-21", "maturityDate": "2016-01-31", "currency": "EUR", "notional": 497058, "IM": 209686, "MTM": 325310, "margined": true }, - { "id": 62, "product": "Vanilla IRS", "tradeDate": "2015-04-28", "effectiveDate": "2015-10-02", "maturityDate": "2015-02-06", "currency": "EUR", "notional": 774176, "IM": 104589, "MTM": 131435, "margined": true }, - { "id": 63, "product": "Vanilla IRS", "tradeDate": "2016-05-07", "effectiveDate": "2015-10-20", "maturityDate": "2015-10-29", "currency": "EUR", "notional": 113419, "IM": 524114, "MTM": 947658, "margined": true }, - { "id": 64, "product": "Vanilla IRS", "tradeDate": "2015-11-17", "effectiveDate": "2016-01-18", "maturityDate": "2015-05-29", "currency": "EUR", "notional": 179789, "IM": 270418, "MTM": 332208, "margined": true }, - { "id": 65, "product": "Vanilla IRS", "tradeDate": "2015-04-07", "effectiveDate": "2016-05-06", "maturityDate": "2015-09-21", "currency": "EUR", "notional": 168915, "IM": 939269, "MTM": 578900, "margined": true }, - { "id": 66, "product": "Vanilla IRS", "tradeDate": "2015-04-17", "effectiveDate": "2015-04-12", "maturityDate": "2015-03-03", "currency": "EUR", "notional": 287722, "IM": 456958, "MTM": 884379, "margined": true }, - { "id": 67, "product": "Vanilla IRS", "tradeDate": "2015-01-04", "effectiveDate": "2016-06-18", "maturityDate": "2015-09-11", "currency": "EUR", "notional": 394305, "IM": 232633, "MTM": 537030, "margined": true }, - { "id": 68, "product": "Vanilla IRS", "tradeDate": "2015-12-26", "effectiveDate": "2016-03-01", "maturityDate": "2015-07-31", "currency": "EUR", "notional": 358097, "IM": 478894, "MTM": 551911, "margined": true }, - { "id": 69, "product": "Vanilla IRS", "tradeDate": "2016-01-10", "effectiveDate": "2016-04-11", "maturityDate": "2015-07-31", "currency": "EUR", "notional": 542063, "IM": 334516, "MTM": 115124, "margined": true }, - { "id": 70, "product": "Vanilla IRS", "tradeDate": "2015-03-20", "effectiveDate": "2015-10-10", "maturityDate": "2015-05-11", "currency": "EUR", "notional": 298792, "IM": 549745, "MTM": 773720, "margined": true }, - { "id": 71, "product": "Vanilla IRS", "tradeDate": "2015-10-24", "effectiveDate": "2016-03-05", "maturityDate": "2015-10-09", "currency": "EUR", "notional": 133994, "IM": 456918, "MTM": 143574, "margined": true }, - { "id": 72, "product": "Vanilla IRS", "tradeDate": "2015-09-25", "effectiveDate": "2016-04-04", "maturityDate": "2016-02-17", "currency": "EUR", "notional": 495675, "IM": 712328, "MTM": 508972, "margined": true }, - { "id": 73, "product": "Vanilla IRS", "tradeDate": "2016-01-26", "effectiveDate": "2015-08-18", "maturityDate": "2015-07-10", "currency": "EUR", "notional": 653308, "IM": 312098, "MTM": 491501, "margined": true }, - { "id": 74, "product": "Vanilla IRS", "tradeDate": "2016-07-18", "effectiveDate": "2015-07-29", "maturityDate": "2015-07-19", "currency": "EUR", "notional": 460693, "IM": 876612, "MTM": 613266, "margined": true }, - { "id": 75, "product": "Vanilla IRS", "tradeDate": "2015-04-29", "effectiveDate": "2016-02-17", "maturityDate": "2015-04-07", "currency": "EUR", "notional": 714540, "IM": 635045, "MTM": 429946, "margined": true }, - { "id": 76, "product": "Vanilla IRS", "tradeDate": "2015-01-14", "effectiveDate": "2015-02-23", "maturityDate": "2015-06-19", "currency": "EUR", "notional": 393350, "IM": 305149, "MTM": 640237, "margined": true }, - { "id": 77, "product": "Vanilla IRS", "tradeDate": "2015-08-25", "effectiveDate": "2015-08-28", "maturityDate": "2015-06-10", "currency": "EUR", "notional": 141311, "IM": 731878, "MTM": 805134, "margined": true }, - { "id": 78, "product": "Vanilla IRS", "tradeDate": "2015-09-19", "effectiveDate": "2016-07-15", "maturityDate": "2016-03-02", "currency": "EUR", "notional": 364776, "IM": 931776, "MTM": 253116, "margined": true }, - { "id": 79, "product": "Vanilla IRS", "tradeDate": "2015-05-03", "effectiveDate": "2016-05-01", "maturityDate": "2015-01-22", "currency": "EUR", "notional": 532600, "IM": 650972, "MTM": 270969, "margined": true }, - { "id": 80, "product": "Vanilla IRS", "tradeDate": "2015-08-06", "effectiveDate": "2015-08-07", "maturityDate": "2015-05-15", "currency": "EUR", "notional": 727813, "IM": 734718, "MTM": 171136, "margined": true }, - { "id": 81, "product": "Vanilla IRS", "tradeDate": "2015-07-27", "effectiveDate": "2015-03-11", "maturityDate": "2016-07-30", "currency": "EUR", "notional": 134024, "IM": 106272, "MTM": 696671, "margined": true }, - { "id": 82, "product": "Vanilla IRS", "tradeDate": "2016-02-06", "effectiveDate": "2015-10-23", "maturityDate": "2015-09-21", "currency": "EUR", "notional": 408393, "IM": 938446, "MTM": 293404, "margined": true }, - { "id": 83, "product": "Vanilla IRS", "tradeDate": "2016-06-16", "effectiveDate": "2015-08-02", "maturityDate": "2016-07-18", "currency": "EUR", "notional": 520325, "IM": 559956, "MTM": 356283, "margined": true }, - { "id": 84, "product": "Vanilla IRS", "tradeDate": "2015-06-22", "effectiveDate": "2015-09-09", "maturityDate": "2016-06-26", "currency": "EUR", "notional": 287454, "IM": 329715, "MTM": 184341, "margined": true }, - { "id": 85, "product": "Vanilla IRS", "tradeDate": "2015-04-08", "effectiveDate": "2016-07-15", "maturityDate": "2015-11-13", "currency": "EUR", "notional": 540568, "IM": 971807, "MTM": 556055, "margined": true }, - { "id": 86, "product": "Vanilla IRS", "tradeDate": "2015-03-15", "effectiveDate": "2015-03-07", "maturityDate": "2015-05-04", "currency": "EUR", "notional": 335631, "IM": 128541, "MTM": 310404, "margined": true }, - { "id": 87, "product": "Vanilla IRS", "tradeDate": "2015-12-09", "effectiveDate": "2015-04-23", "maturityDate": "2015-12-11", "currency": "EUR", "notional": 597311, "IM": 210087, "MTM": 226107, "margined": true }, - { "id": 88, "product": "Vanilla IRS", "tradeDate": "2015-11-27", "effectiveDate": "2016-07-22", "maturityDate": "2015-05-10", "currency": "EUR", "notional": 396229, "IM": 247052, "MTM": 304876, "margined": true }, - { "id": 89, "product": "Vanilla IRS", "tradeDate": "2015-07-21", "effectiveDate": "2016-02-20", "maturityDate": "2015-09-02", "currency": "EUR", "notional": 355770, "IM": 495782, "MTM": 703656, "margined": true }, - { "id": 90, "product": "Vanilla IRS", "tradeDate": "2015-12-06", "effectiveDate": "2015-04-01", "maturityDate": "2016-06-05", "currency": "EUR", "notional": 820022, "IM": 851662, "MTM": 112374, "margined": true }, - { "id": 91, "product": "Vanilla IRS", "tradeDate": "2015-10-04", "effectiveDate": "2016-01-13", "maturityDate": "2015-06-25", "currency": "EUR", "notional": 647034, "IM": 764090, "MTM": 631648, "margined": true }, - { "id": 92, "product": "Vanilla IRS", "tradeDate": "2016-01-23", "effectiveDate": "2015-03-21", "maturityDate": "2016-02-29", "currency": "EUR", "notional": 320752, "IM": 882869, "MTM": 372473, "margined": true }, - { "id": 93, "product": "Vanilla IRS", "tradeDate": "2015-11-05", "effectiveDate": "2016-05-31", "maturityDate": "2016-07-13", "currency": "EUR", "notional": 840581, "IM": 165397, "MTM": 670960, "margined": true }, - { "id": 94, "product": "Vanilla IRS", "tradeDate": "2015-11-30", "effectiveDate": "2016-02-12", "maturityDate": "2016-01-12", "currency": "EUR", "notional": 540990, "IM": 901114, "MTM": 953227, "margined": true }, - { "id": 95, "product": "Vanilla IRS", "tradeDate": "2016-08-06", "effectiveDate": "2015-09-24", "maturityDate": "2015-03-01", "currency": "EUR", "notional": 620797, "IM": 485641, "MTM": 869657, "margined": true }, - { "id": 96, "product": "Vanilla IRS", "tradeDate": "2016-07-06", "effectiveDate": "2015-11-08", "maturityDate": "2015-01-30", "currency": "EUR", "notional": 735236, "IM": 409339, "MTM": 103279, "margined": true }, - { "id": 97, "product": "Vanilla IRS", "tradeDate": "2015-05-09", "effectiveDate": "2015-06-19", "maturityDate": "2015-06-18", "currency": "EUR", "notional": 320266, "IM": 846686, "MTM": 206835, "margined": true }, - { "id": 98, "product": "Vanilla IRS", "tradeDate": "2015-12-29", "effectiveDate": "2015-01-17", "maturityDate": "2015-05-05", "currency": "EUR", "notional": 246773, "IM": 650760, "MTM": 644383, "margined": true }, - { "id": 99, "product": "Vanilla IRS", "tradeDate": "2016-04-18", "effectiveDate": "2016-03-09", "maturityDate": "2015-01-10", "currency": "EUR", "notional": 845031, "IM": 737392, "MTM": 379855, "margined": true }, - { "id": 100, "product": "Vanilla IRS", "tradeDate": "2015-02-25", "effectiveDate": "2015-02-09", "maturityDate": "2016-04-28", "currency": "EUR", "notional": 309346, "IM": 541269, "MTM": 198941, "margined": true }, - { "id": 101, "product": "Vanilla IRS", "tradeDate": "2016-07-04", "effectiveDate": "2015-12-13", "maturityDate": "2015-12-18", "currency": "EUR", "notional": 282242, "IM": 117148, "MTM": 834255, "margined": true }, - { "id": 102, "product": "Vanilla IRS", "tradeDate": "2016-02-22", "effectiveDate": "2016-05-10", "maturityDate": "2016-01-03", "currency": "EUR", "notional": 703016, "IM": 695915, "MTM": 611568, "margined": true }, - { "id": 103, "product": "Vanilla IRS", "tradeDate": "2015-02-16", "effectiveDate": "2015-03-26", "maturityDate": "2015-12-29", "currency": "EUR", "notional": 941851, "IM": 821837, "MTM": 794285, "margined": true }, - { "id": 104, "product": "Vanilla IRS", "tradeDate": "2015-05-08", "effectiveDate": "2016-06-25", "maturityDate": "2015-09-11", "currency": "EUR", "notional": 887428, "IM": 944187, "MTM": 791572, "margined": true }, - { "id": 105, "product": "Vanilla IRS", "tradeDate": "2015-01-27", "effectiveDate": "2015-09-27", "maturityDate": "2016-05-06", "currency": "EUR", "notional": 495755, "IM": 217975, "MTM": 966627, "margined": true }, - { "id": 106, "product": "Vanilla IRS", "tradeDate": "2016-07-14", "effectiveDate": "2015-04-02", "maturityDate": "2015-10-02", "currency": "EUR", "notional": 856587, "IM": 864090, "MTM": 558381, "margined": true }, - { "id": 107, "product": "Vanilla IRS", "tradeDate": "2015-10-15", "effectiveDate": "2015-01-30", "maturityDate": "2015-08-03", "currency": "EUR", "notional": 786133, "IM": 436880, "MTM": 128669, "margined": true }, - { "id": 108, "product": "Vanilla IRS", "tradeDate": "2015-01-15", "effectiveDate": "2016-05-06", "maturityDate": "2016-03-29", "currency": "EUR", "notional": 712089, "IM": 840568, "MTM": 766662, "margined": true }, - { "id": 109, "product": "Vanilla IRS", "tradeDate": "2015-07-26", "effectiveDate": "2015-06-13", "maturityDate": "2015-06-18", "currency": "EUR", "notional": 574472, "IM": 572550, "MTM": 427038, "margined": true }, - { "id": 110, "product": "Vanilla IRS", "tradeDate": "2015-03-18", "effectiveDate": "2015-03-03", "maturityDate": "2015-11-18", "currency": "EUR", "notional": 961439, "IM": 271983, "MTM": 501135, "margined": true }, - { "id": 111, "product": "Vanilla IRS", "tradeDate": "2015-03-23", "effectiveDate": "2016-03-28", "maturityDate": "2015-01-15", "currency": "EUR", "notional": 610010, "IM": 260123, "MTM": 606904, "margined": true }, - { "id": 112, "product": "Vanilla IRS", "tradeDate": "2015-08-22", "effectiveDate": "2015-06-19", "maturityDate": "2016-03-01", "currency": "EUR", "notional": 373213, "IM": 354395, "MTM": 300434, "margined": true }, - { "id": 113, "product": "Vanilla IRS", "tradeDate": "2015-01-08", "effectiveDate": "2016-06-06", "maturityDate": "2015-03-30", "currency": "EUR", "notional": 721045, "IM": 574434, "MTM": 982097, "margined": true }, - { "id": 114, "product": "Vanilla IRS", "tradeDate": "2015-08-15", "effectiveDate": "2015-03-27", "maturityDate": "2015-09-16", "currency": "EUR", "notional": 410689, "IM": 191354, "MTM": 508457, "margined": true }, - { "id": 115, "product": "Vanilla IRS", "tradeDate": "2015-02-12", "effectiveDate": "2015-05-01", "maturityDate": "2016-08-09", "currency": "EUR", "notional": 574459, "IM": 333545, "MTM": 552131, "margined": true }, - { "id": 116, "product": "Vanilla IRS", "tradeDate": "2016-02-08", "effectiveDate": "2015-10-21", "maturityDate": "2015-05-28", "currency": "EUR", "notional": 301679, "IM": 304429, "MTM": 725354, "margined": true }, - { "id": 117, "product": "Vanilla IRS", "tradeDate": "2015-08-17", "effectiveDate": "2015-09-23", "maturityDate": "2015-08-05", "currency": "EUR", "notional": 692176, "IM": 224568, "MTM": 684007, "margined": true }, - { "id": 118, "product": "Vanilla IRS", "tradeDate": "2015-10-31", "effectiveDate": "2015-01-08", "maturityDate": "2015-04-10", "currency": "EUR", "notional": 665387, "IM": 924896, "MTM": 163306, "margined": true }, - { "id": 119, "product": "Vanilla IRS", "tradeDate": "2015-02-09", "effectiveDate": "2016-03-28", "maturityDate": "2016-06-06", "currency": "EUR", "notional": 764512, "IM": 775347, "MTM": 920303, "margined": true }, - { "id": 120, "product": "Vanilla IRS", "tradeDate": "2016-06-28", "effectiveDate": "2015-03-25", "maturityDate": "2015-08-17", "currency": "EUR", "notional": 557575, "IM": 808406, "MTM": 748901, "margined": true }, - { "id": 121, "product": "Vanilla IRS", "tradeDate": "2015-11-03", "effectiveDate": "2016-08-03", "maturityDate": "2015-07-18", "currency": "EUR", "notional": 379007, "IM": 817870, "MTM": 646495, "margined": true }, - { "id": 122, "product": "Vanilla IRS", "tradeDate": "2016-04-28", "effectiveDate": "2015-05-17", "maturityDate": "2016-07-01", "currency": "EUR", "notional": 826854, "IM": 125450, "MTM": 304051, "margined": true }, - { "id": 123, "product": "Vanilla IRS", "tradeDate": "2015-11-26", "effectiveDate": "2016-06-03", "maturityDate": "2015-10-16", "currency": "EUR", "notional": 619716, "IM": 171352, "MTM": 102397, "margined": true }, - { "id": 124, "product": "Vanilla IRS", "tradeDate": "2015-03-20", "effectiveDate": "2015-08-20", "maturityDate": "2016-04-18", "currency": "EUR", "notional": 559044, "IM": 278259, "MTM": 569061, "margined": true }, - { "id": 125, "product": "Vanilla IRS", "tradeDate": "2015-01-24", "effectiveDate": "2016-03-30", "maturityDate": "2016-05-01", "currency": "EUR", "notional": 241364, "IM": 568676, "MTM": 326451, "margined": true }, - { "id": 126, "product": "Vanilla IRS", "tradeDate": "2015-02-20", "effectiveDate": "2015-12-05", "maturityDate": "2016-06-07", "currency": "EUR", "notional": 959227, "IM": 625438, "MTM": 184337, "margined": true }, - { "id": 127, "product": "Vanilla IRS", "tradeDate": "2016-02-04", "effectiveDate": "2015-04-17", "maturityDate": "2016-02-15", "currency": "EUR", "notional": 110533, "IM": 756114, "MTM": 712481, "margined": true }, - { "id": 128, "product": "Vanilla IRS", "tradeDate": "2015-10-14", "effectiveDate": "2015-09-03", "maturityDate": "2015-04-01", "currency": "EUR", "notional": 837721, "IM": 699882, "MTM": 940429, "margined": true }, - { "id": 129, "product": "Vanilla IRS", "tradeDate": "2015-06-28", "effectiveDate": "2015-03-24", "maturityDate": "2016-05-31", "currency": "EUR", "notional": 882369, "IM": 488096, "MTM": 127600, "margined": true }, - { "id": 130, "product": "Vanilla IRS", "tradeDate": "2015-12-30", "effectiveDate": "2015-02-16", "maturityDate": "2015-05-12", "currency": "EUR", "notional": 956648, "IM": 863890, "MTM": 644611, "margined": true }, - { "id": 131, "product": "Vanilla IRS", "tradeDate": "2015-09-04", "effectiveDate": "2015-12-10", "maturityDate": "2015-09-07", "currency": "EUR", "notional": 920698, "IM": 827054, "MTM": 574335, "margined": true }, - { "id": 132, "product": "Vanilla IRS", "tradeDate": "2016-08-03", "effectiveDate": "2016-03-30", "maturityDate": "2016-01-15", "currency": "EUR", "notional": 607200, "IM": 238673, "MTM": 629081, "margined": true }, - { "id": 133, "product": "Vanilla IRS", "tradeDate": "2015-05-22", "effectiveDate": "2015-01-03", "maturityDate": "2015-02-16", "currency": "EUR", "notional": 422765, "IM": 392952, "MTM": 313599, "margined": true }, - { "id": 134, "product": "Vanilla IRS", "tradeDate": "2016-07-11", "effectiveDate": "2015-02-20", "maturityDate": "2015-02-08", "currency": "EUR", "notional": 353249, "IM": 551820, "MTM": 266555, "margined": true }, - { "id": 135, "product": "Vanilla IRS", "tradeDate": "2015-08-07", "effectiveDate": "2015-07-07", "maturityDate": "2015-07-26", "currency": "EUR", "notional": 656967, "IM": 423372, "MTM": 797888, "margined": true }, - { "id": 136, "product": "Vanilla IRS", "tradeDate": "2016-08-03", "effectiveDate": "2016-01-12", "maturityDate": "2016-04-08", "currency": "EUR", "notional": 934552, "IM": 805306, "MTM": 692681, "margined": true }, - { "id": 137, "product": "Vanilla IRS", "tradeDate": "2015-05-03", "effectiveDate": "2015-09-05", "maturityDate": "2015-08-02", "currency": "EUR", "notional": 771686, "IM": 541699, "MTM": 836563, "margined": true }, - { "id": 138, "product": "Vanilla IRS", "tradeDate": "2015-03-15", "effectiveDate": "2016-01-03", "maturityDate": "2015-11-15", "currency": "EUR", "notional": 777864, "IM": 465468, "MTM": 492054, "margined": true }, - { "id": 139, "product": "Vanilla IRS", "tradeDate": "2016-06-23", "effectiveDate": "2016-02-24", "maturityDate": "2016-02-20", "currency": "EUR", "notional": 476100, "IM": 612901, "MTM": 600235, "margined": true }, - { "id": 140, "product": "Vanilla IRS", "tradeDate": "2016-06-14", "effectiveDate": "2015-09-28", "maturityDate": "2016-03-09", "currency": "EUR", "notional": 194410, "IM": 226590, "MTM": 251118, "margined": true }, - { "id": 141, "product": "Vanilla IRS", "tradeDate": "2016-01-07", "effectiveDate": "2016-04-01", "maturityDate": "2015-12-11", "currency": "EUR", "notional": 150449, "IM": 805126, "MTM": 482672, "margined": true }, - { "id": 142, "product": "Vanilla IRS", "tradeDate": "2015-12-08", "effectiveDate": "2016-01-24", "maturityDate": "2015-01-25", "currency": "EUR", "notional": 652693, "IM": 360177, "MTM": 468827, "margined": true }, - { "id": 143, "product": "Vanilla IRS", "tradeDate": "2016-01-09", "effectiveDate": "2015-11-03", "maturityDate": "2015-08-20", "currency": "EUR", "notional": 603875, "IM": 556388, "MTM": 133838, "margined": true }, - { "id": 144, "product": "Vanilla IRS", "tradeDate": "2015-06-15", "effectiveDate": "2016-02-18", "maturityDate": "2016-06-11", "currency": "EUR", "notional": 960588, "IM": 459365, "MTM": 354038, "margined": true }, - { "id": 145, "product": "Vanilla IRS", "tradeDate": "2015-04-02", "effectiveDate": "2016-07-01", "maturityDate": "2015-04-13", "currency": "EUR", "notional": 626069, "IM": 577624, "MTM": 316384, "margined": true }, - { "id": 146, "product": "Vanilla IRS", "tradeDate": "2015-06-27", "effectiveDate": "2015-07-05", "maturityDate": "2016-03-03", "currency": "EUR", "notional": 501133, "IM": 805155, "MTM": 755679, "margined": true }, - { "id": 147, "product": "Vanilla IRS", "tradeDate": "2015-05-15", "effectiveDate": "2015-02-11", "maturityDate": "2015-10-16", "currency": "EUR", "notional": 530756, "IM": 430938, "MTM": 632317, "margined": true }, - { "id": 148, "product": "Vanilla IRS", "tradeDate": "2015-10-21", "effectiveDate": "2015-09-05", "maturityDate": "2016-05-18", "currency": "EUR", "notional": 321363, "IM": 696929, "MTM": 386009, "margined": true }, - { "id": 149, "product": "Vanilla IRS", "tradeDate": "2015-10-01", "effectiveDate": "2015-05-09", "maturityDate": "2016-05-12", "currency": "EUR", "notional": 554605, "IM": 668366, "MTM": 345623, "margined": true }, - { "id": 150, "product": "Vanilla IRS", "tradeDate": "2015-04-07", "effectiveDate": "2016-04-24", "maturityDate": "2016-01-21", "currency": "EUR", "notional": 487866, "IM": 660974, "MTM": 292259, "margined": true }, - { "id": 151, "product": "Vanilla IRS", "tradeDate": "2015-05-09", "effectiveDate": "2015-06-11", "maturityDate": "2016-05-01", "currency": "EUR", "notional": 880172, "IM": 392191, "MTM": 765341, "margined": true }, - { "id": 152, "product": "Vanilla IRS", "tradeDate": "2015-08-27", "effectiveDate": "2015-03-04", "maturityDate": "2015-12-17", "currency": "EUR", "notional": 982260, "IM": 559974, "MTM": 147756, "margined": true }, - { "id": 153, "product": "Vanilla IRS", "tradeDate": "2015-04-13", "effectiveDate": "2016-04-18", "maturityDate": "2015-02-21", "currency": "EUR", "notional": 314432, "IM": 725979, "MTM": 512789, "margined": true }, - { "id": 154, "product": "Vanilla IRS", "tradeDate": "2016-02-29", "effectiveDate": "2016-07-17", "maturityDate": "2015-06-24", "currency": "EUR", "notional": 503128, "IM": 478809, "MTM": 264343, "margined": true }, - { "id": 155, "product": "Vanilla IRS", "tradeDate": "2016-07-16", "effectiveDate": "2015-06-24", "maturityDate": "2015-12-27", "currency": "EUR", "notional": 130257, "IM": 714998, "MTM": 844551, "margined": true }, - { "id": 156, "product": "Vanilla IRS", "tradeDate": "2015-07-05", "effectiveDate": "2016-03-09", "maturityDate": "2015-04-24", "currency": "EUR", "notional": 629988, "IM": 906140, "MTM": 113893, "margined": true }, - { "id": 157, "product": "Vanilla IRS", "tradeDate": "2016-05-29", "effectiveDate": "2015-06-09", "maturityDate": "2015-08-29", "currency": "EUR", "notional": 304945, "IM": 776396, "MTM": 996638, "margined": true }, - { "id": 158, "product": "Vanilla IRS", "tradeDate": "2015-03-05", "effectiveDate": "2016-03-06", "maturityDate": "2015-08-04", "currency": "EUR", "notional": 747333, "IM": 570631, "MTM": 417961, "margined": true }, - { "id": 159, "product": "Vanilla IRS", "tradeDate": "2015-10-02", "effectiveDate": "2016-07-19", "maturityDate": "2016-01-17", "currency": "EUR", "notional": 537330, "IM": 759469, "MTM": 538300, "margined": true }, - { "id": 160, "product": "Vanilla IRS", "tradeDate": "2016-01-27", "effectiveDate": "2016-06-21", "maturityDate": "2015-10-15", "currency": "EUR", "notional": 390877, "IM": 731455, "MTM": 478047, "margined": true }, - { "id": 161, "product": "Vanilla IRS", "tradeDate": "2015-07-11", "effectiveDate": "2015-10-20", "maturityDate": "2016-07-13", "currency": "EUR", "notional": 706544, "IM": 255875, "MTM": 865391, "margined": true }, - { "id": 162, "product": "Vanilla IRS", "tradeDate": "2015-02-06", "effectiveDate": "2015-07-25", "maturityDate": "2015-03-29", "currency": "EUR", "notional": 490037, "IM": 507030, "MTM": 608750, "margined": true }, - { "id": 163, "product": "Vanilla IRS", "tradeDate": "2015-07-20", "effectiveDate": "2015-02-16", "maturityDate": "2015-01-12", "currency": "EUR", "notional": 936666, "IM": 168665, "MTM": 167728, "margined": true }, - { "id": 164, "product": "Vanilla IRS", "tradeDate": "2015-05-15", "effectiveDate": "2015-06-18", "maturityDate": "2015-04-24", "currency": "EUR", "notional": 239086, "IM": 342696, "MTM": 188455, "margined": true }, - { "id": 165, "product": "Vanilla IRS", "tradeDate": "2015-12-28", "effectiveDate": "2015-05-08", "maturityDate": "2016-01-01", "currency": "EUR", "notional": 532008, "IM": 904602, "MTM": 428179, "margined": true }, - { "id": 166, "product": "Vanilla IRS", "tradeDate": "2015-05-08", "effectiveDate": "2015-07-19", "maturityDate": "2015-12-30", "currency": "EUR", "notional": 706261, "IM": 307822, "MTM": 447155, "margined": true }, - { "id": 167, "product": "Vanilla IRS", "tradeDate": "2016-04-09", "effectiveDate": "2015-06-10", "maturityDate": "2015-09-16", "currency": "EUR", "notional": 681187, "IM": 344205, "MTM": 355077, "margined": true }, - { "id": 168, "product": "Vanilla IRS", "tradeDate": "2015-10-16", "effectiveDate": "2015-03-12", "maturityDate": "2015-10-08", "currency": "EUR", "notional": 517714, "IM": 816710, "MTM": 139042, "margined": true }, - { "id": 169, "product": "Vanilla IRS", "tradeDate": "2016-05-06", "effectiveDate": "2016-04-12", "maturityDate": "2015-07-27", "currency": "EUR", "notional": 670830, "IM": 107511, "MTM": 197087, "margined": true }, - { "id": 170, "product": "Vanilla IRS", "tradeDate": "2015-06-04", "effectiveDate": "2015-04-24", "maturityDate": "2015-06-24", "currency": "EUR", "notional": 365567, "IM": 234064, "MTM": 451188, "margined": true }, - { "id": 171, "product": "Vanilla IRS", "tradeDate": "2015-04-10", "effectiveDate": "2016-05-14", "maturityDate": "2015-06-23", "currency": "EUR", "notional": 213163, "IM": 904233, "MTM": 976016, "margined": true }, - { "id": 172, "product": "Vanilla IRS", "tradeDate": "2016-02-19", "effectiveDate": "2015-02-05", "maturityDate": "2015-09-14", "currency": "EUR", "notional": 588857, "IM": 919424, "MTM": 915195, "margined": true }, - { "id": 173, "product": "Vanilla IRS", "tradeDate": "2015-05-17", "effectiveDate": "2016-01-21", "maturityDate": "2016-02-19", "currency": "EUR", "notional": 774250, "IM": 930188, "MTM": 587283, "margined": true }, - { "id": 174, "product": "Vanilla IRS", "tradeDate": "2016-01-28", "effectiveDate": "2015-05-08", "maturityDate": "2016-03-26", "currency": "EUR", "notional": 343068, "IM": 863193, "MTM": 935389, "margined": true }, - { "id": 175, "product": "Vanilla IRS", "tradeDate": "2016-05-30", "effectiveDate": "2016-03-18", "maturityDate": "2015-11-11", "currency": "EUR", "notional": 539338, "IM": 941874, "MTM": 361090, "margined": true }, - { "id": 176, "product": "Vanilla IRS", "tradeDate": "2016-02-09", "effectiveDate": "2015-03-03", "maturityDate": "2016-04-25", "currency": "EUR", "notional": 457416, "IM": 134488, "MTM": 176154, "margined": true }, - { "id": 177, "product": "Vanilla IRS", "tradeDate": "2015-07-15", "effectiveDate": "2016-07-07", "maturityDate": "2015-06-24", "currency": "EUR", "notional": 237968, "IM": 477676, "MTM": 649342, "margined": true }, - { "id": 178, "product": "Vanilla IRS", "tradeDate": "2015-01-30", "effectiveDate": "2015-04-19", "maturityDate": "2015-10-29", "currency": "EUR", "notional": 812310, "IM": 757507, "MTM": 321624, "margined": true }, - { "id": 179, "product": "Vanilla IRS", "tradeDate": "2015-01-03", "effectiveDate": "2015-07-12", "maturityDate": "2016-06-28", "currency": "EUR", "notional": 247734, "IM": 708914, "MTM": 526668, "margined": true }, - { "id": 180, "product": "Vanilla IRS", "tradeDate": "2015-01-17", "effectiveDate": "2016-05-07", "maturityDate": "2016-01-17", "currency": "EUR", "notional": 174565, "IM": 198502, "MTM": 221386, "margined": true }, - { "id": 181, "product": "Vanilla IRS", "tradeDate": "2015-08-27", "effectiveDate": "2015-09-10", "maturityDate": "2015-08-15", "currency": "EUR", "notional": 851611, "IM": 509977, "MTM": 846636, "margined": true }, - { "id": 182, "product": "Vanilla IRS", "tradeDate": "2016-08-05", "effectiveDate": "2015-05-06", "maturityDate": "2015-02-24", "currency": "EUR", "notional": 599004, "IM": 640325, "MTM": 781028, "margined": true }, - { "id": 183, "product": "Vanilla IRS", "tradeDate": "2015-01-12", "effectiveDate": "2015-01-22", "maturityDate": "2015-06-20", "currency": "EUR", "notional": 799256, "IM": 763766, "MTM": 110203, "margined": true }, - { "id": 184, "product": "Vanilla IRS", "tradeDate": "2015-05-20", "effectiveDate": "2015-03-01", "maturityDate": "2015-08-16", "currency": "EUR", "notional": 313638, "IM": 485014, "MTM": 995424, "margined": true }, - { "id": 185, "product": "Vanilla IRS", "tradeDate": "2015-12-26", "effectiveDate": "2016-03-22", "maturityDate": "2016-04-07", "currency": "EUR", "notional": 302194, "IM": 879727, "MTM": 571055, "margined": true }, - { "id": 186, "product": "Vanilla IRS", "tradeDate": "2015-08-09", "effectiveDate": "2015-01-30", "maturityDate": "2015-07-02", "currency": "EUR", "notional": 413163, "IM": 797254, "MTM": 764824, "margined": true }, - { "id": 187, "product": "Vanilla IRS", "tradeDate": "2015-11-25", "effectiveDate": "2015-03-15", "maturityDate": "2015-07-07", "currency": "EUR", "notional": 259095, "IM": 572139, "MTM": 915076, "margined": true }, - { "id": 188, "product": "Vanilla IRS", "tradeDate": "2016-06-01", "effectiveDate": "2015-01-23", "maturityDate": "2015-01-05", "currency": "EUR", "notional": 270020, "IM": 318493, "MTM": 827346, "margined": true }, - { "id": 189, "product": "Vanilla IRS", "tradeDate": "2015-07-14", "effectiveDate": "2016-08-11", "maturityDate": "2016-01-15", "currency": "EUR", "notional": 969790, "IM": 709715, "MTM": 932849, "margined": true }, - { "id": 190, "product": "Vanilla IRS", "tradeDate": "2015-01-25", "effectiveDate": "2015-02-19", "maturityDate": "2016-02-06", "currency": "EUR", "notional": 287607, "IM": 652106, "MTM": 231059, "margined": true }, - { "id": 191, "product": "Vanilla IRS", "tradeDate": "2016-02-22", "effectiveDate": "2016-03-23", "maturityDate": "2016-01-22", "currency": "EUR", "notional": 388933, "IM": 265402, "MTM": 977226, "margined": true }, - { "id": 192, "product": "Vanilla IRS", "tradeDate": "2015-03-21", "effectiveDate": "2015-02-06", "maturityDate": "2015-07-24", "currency": "EUR", "notional": 224686, "IM": 671689, "MTM": 473482, "margined": true }, - { "id": 193, "product": "Vanilla IRS", "tradeDate": "2015-05-19", "effectiveDate": "2015-08-23", "maturityDate": "2015-09-17", "currency": "EUR", "notional": 870383, "IM": 609458, "MTM": 778323, "margined": true }, - { "id": 194, "product": "Vanilla IRS", "tradeDate": "2016-02-17", "effectiveDate": "2015-02-24", "maturityDate": "2015-11-08", "currency": "EUR", "notional": 496976, "IM": 752623, "MTM": 650366, "margined": true }, - { "id": 195, "product": "Vanilla IRS", "tradeDate": "2015-08-16", "effectiveDate": "2016-05-18", "maturityDate": "2015-12-27", "currency": "EUR", "notional": 973321, "IM": 418083, "MTM": 865566, "margined": true }, - { "id": 196, "product": "Vanilla IRS", "tradeDate": "2016-03-24", "effectiveDate": "2015-04-26", "maturityDate": "2015-07-06", "currency": "EUR", "notional": 251931, "IM": 127370, "MTM": 254059, "margined": true }, - { "id": 197, "product": "Vanilla IRS", "tradeDate": "2016-08-13", "effectiveDate": "2016-03-11", "maturityDate": "2015-06-15", "currency": "EUR", "notional": 906352, "IM": 540839, "MTM": 365465, "margined": true }, - { "id": 198, "product": "Vanilla IRS", "tradeDate": "2015-10-27", "effectiveDate": "2015-09-24", "maturityDate": "2015-03-25", "currency": "EUR", "notional": 579334, "IM": 758965, "MTM": 216042, "margined": true }, - { "id": 199, "product": "Vanilla IRS", "tradeDate": "2016-02-29", "effectiveDate": "2016-01-31", "maturityDate": "2015-04-09", "currency": "EUR", "notional": 638855, "IM": 508532, "MTM": 532724, "margined": true }, - { "id": 200, "product": "Vanilla IRS", "tradeDate": "2016-06-23", "effectiveDate": "2015-11-21", "maturityDate": "2015-05-11", "currency": "EUR", "notional": 696674, "IM": 872687, "MTM": 502753, "margined": true }, - { "id": 201, "product": "Vanilla IRS", "tradeDate": "2016-08-15", "effectiveDate": "2016-08-08", "maturityDate": "2016-01-12", "currency": "EUR", "notional": 766501, "IM": 686393, "MTM": 277935, "margined": true }, - { "id": 202, "product": "Vanilla IRS", "tradeDate": "2016-05-11", "effectiveDate": "2016-04-13", "maturityDate": "2015-08-29", "currency": "EUR", "notional": 131246, "IM": 679990, "MTM": 863563, "margined": true }, - { "id": 203, "product": "Vanilla IRS", "tradeDate": "2016-03-14", "effectiveDate": "2015-12-31", "maturityDate": "2016-02-18", "currency": "EUR", "notional": 417173, "IM": 969702, "MTM": 474018, "margined": true }, - { "id": 204, "product": "Vanilla IRS", "tradeDate": "2016-03-12", "effectiveDate": "2016-02-02", "maturityDate": "2015-12-23", "currency": "EUR", "notional": 872241, "IM": 712659, "MTM": 453915, "margined": true }, - { "id": 205, "product": "Vanilla IRS", "tradeDate": "2015-04-22", "effectiveDate": "2015-04-30", "maturityDate": "2015-09-24", "currency": "EUR", "notional": 643159, "IM": 620332, "MTM": 402337, "margined": true }, - { "id": 206, "product": "Vanilla IRS", "tradeDate": "2015-04-12", "effectiveDate": "2015-03-11", "maturityDate": "2015-01-31", "currency": "EUR", "notional": 714373, "IM": 149746, "MTM": 900071, "margined": true }, - { "id": 207, "product": "Vanilla IRS", "tradeDate": "2015-02-02", "effectiveDate": "2015-09-22", "maturityDate": "2015-07-10", "currency": "EUR", "notional": 318518, "IM": 424525, "MTM": 943123, "margined": true }, - { "id": 208, "product": "Vanilla IRS", "tradeDate": "2016-06-16", "effectiveDate": "2015-04-07", "maturityDate": "2016-02-16", "currency": "EUR", "notional": 139654, "IM": 380448, "MTM": 230593, "margined": true }, - { "id": 209, "product": "Vanilla IRS", "tradeDate": "2016-08-12", "effectiveDate": "2016-01-14", "maturityDate": "2015-11-15", "currency": "EUR", "notional": 816217, "IM": 846579, "MTM": 276920, "margined": true }, - { "id": 210, "product": "Vanilla IRS", "tradeDate": "2015-08-05", "effectiveDate": "2015-03-27", "maturityDate": "2015-08-17", "currency": "EUR", "notional": 673724, "IM": 864525, "MTM": 955338, "margined": true }, - { "id": 211, "product": "Vanilla IRS", "tradeDate": "2015-07-02", "effectiveDate": "2016-08-01", "maturityDate": "2015-11-07", "currency": "EUR", "notional": 831741, "IM": 666143, "MTM": 746993, "margined": true }, - { "id": 212, "product": "Vanilla IRS", "tradeDate": "2015-07-31", "effectiveDate": "2016-05-04", "maturityDate": "2015-06-25", "currency": "EUR", "notional": 636819, "IM": 532143, "MTM": 462310, "margined": true }, - { "id": 213, "product": "Vanilla IRS", "tradeDate": "2015-10-21", "effectiveDate": "2015-01-08", "maturityDate": "2015-09-27", "currency": "EUR", "notional": 342988, "IM": 618957, "MTM": 803554, "margined": true }, - { "id": 214, "product": "Vanilla IRS", "tradeDate": "2015-07-26", "effectiveDate": "2015-06-04", "maturityDate": "2015-11-10", "currency": "EUR", "notional": 276246, "IM": 291288, "MTM": 706183, "margined": true }, - { "id": 215, "product": "Vanilla IRS", "tradeDate": "2016-06-05", "effectiveDate": "2015-06-15", "maturityDate": "2016-02-26", "currency": "EUR", "notional": 389210, "IM": 195536, "MTM": 160494, "margined": true }, - { "id": 216, "product": "Vanilla IRS", "tradeDate": "2016-07-23", "effectiveDate": "2016-05-21", "maturityDate": "2016-08-12", "currency": "EUR", "notional": 864565, "IM": 966061, "MTM": 852521, "margined": true }, - { "id": 217, "product": "Vanilla IRS", "tradeDate": "2016-03-05", "effectiveDate": "2015-11-11", "maturityDate": "2016-07-28", "currency": "EUR", "notional": 699676, "IM": 824406, "MTM": 637541, "margined": true }, - { "id": 218, "product": "Vanilla IRS", "tradeDate": "2015-01-07", "effectiveDate": "2016-04-10", "maturityDate": "2015-01-05", "currency": "EUR", "notional": 619825, "IM": 273428, "MTM": 466635, "margined": true }, - { "id": 219, "product": "Vanilla IRS", "tradeDate": "2015-06-28", "effectiveDate": "2015-03-03", "maturityDate": "2015-01-06", "currency": "EUR", "notional": 479481, "IM": 809109, "MTM": 848633, "margined": true }, - { "id": 220, "product": "Vanilla IRS", "tradeDate": "2015-03-25", "effectiveDate": "2015-05-16", "maturityDate": "2015-12-26", "currency": "EUR", "notional": 554682, "IM": 218050, "MTM": 758285, "margined": true }, - { "id": 221, "product": "Vanilla IRS", "tradeDate": "2015-01-19", "effectiveDate": "2015-03-06", "maturityDate": "2015-07-08", "currency": "EUR", "notional": 392631, "IM": 473087, "MTM": 130100, "margined": true }, - { "id": 222, "product": "Vanilla IRS", "tradeDate": "2015-07-15", "effectiveDate": "2015-08-06", "maturityDate": "2016-02-09", "currency": "EUR", "notional": 702446, "IM": 272708, "MTM": 249664, "margined": true }, - { "id": 223, "product": "Vanilla IRS", "tradeDate": "2016-04-07", "effectiveDate": "2016-01-20", "maturityDate": "2015-02-13", "currency": "EUR", "notional": 411239, "IM": 180807, "MTM": 862189, "margined": true }, - { "id": 224, "product": "Vanilla IRS", "tradeDate": "2015-05-10", "effectiveDate": "2015-10-25", "maturityDate": "2015-06-21", "currency": "EUR", "notional": 128083, "IM": 468901, "MTM": 239829, "margined": true }, - { "id": 225, "product": "Vanilla IRS", "tradeDate": "2015-07-19", "effectiveDate": "2016-01-22", "maturityDate": "2015-09-06", "currency": "EUR", "notional": 366153, "IM": 319223, "MTM": 873436, "margined": true }, - { "id": 226, "product": "Vanilla IRS", "tradeDate": "2015-08-31", "effectiveDate": "2015-09-23", "maturityDate": "2016-03-15", "currency": "EUR", "notional": 951764, "IM": 139046, "MTM": 863242, "margined": true }, - { "id": 227, "product": "Vanilla IRS", "tradeDate": "2016-06-08", "effectiveDate": "2015-08-31", "maturityDate": "2015-03-28", "currency": "EUR", "notional": 498146, "IM": 979930, "MTM": 755265, "margined": true }, - { "id": 228, "product": "Vanilla IRS", "tradeDate": "2015-12-03", "effectiveDate": "2015-03-11", "maturityDate": "2015-10-20", "currency": "EUR", "notional": 707198, "IM": 792927, "MTM": 526909, "margined": true }, - { "id": 229, "product": "Vanilla IRS", "tradeDate": "2015-07-26", "effectiveDate": "2016-03-06", "maturityDate": "2015-06-07", "currency": "EUR", "notional": 773299, "IM": 290507, "MTM": 911591, "margined": true }, - { "id": 230, "product": "Vanilla IRS", "tradeDate": "2015-03-04", "effectiveDate": "2016-03-26", "maturityDate": "2015-06-20", "currency": "EUR", "notional": 714056, "IM": 356985, "MTM": 174213, "margined": true }, - { "id": 231, "product": "Vanilla IRS", "tradeDate": "2015-11-01", "effectiveDate": "2015-06-08", "maturityDate": "2016-02-10", "currency": "EUR", "notional": 460226, "IM": 806308, "MTM": 926144, "margined": true }, - { "id": 232, "product": "Vanilla IRS", "tradeDate": "2015-08-29", "effectiveDate": "2015-12-07", "maturityDate": "2016-07-25", "currency": "EUR", "notional": 521983, "IM": 438763, "MTM": 245527, "margined": true }, - { "id": 233, "product": "Vanilla IRS", "tradeDate": "2015-04-25", "effectiveDate": "2016-02-12", "maturityDate": "2015-09-01", "currency": "EUR", "notional": 780536, "IM": 584452, "MTM": 405066, "margined": true }, - { "id": 234, "product": "Vanilla IRS", "tradeDate": "2016-06-24", "effectiveDate": "2015-06-30", "maturityDate": "2016-04-13", "currency": "EUR", "notional": 656509, "IM": 678845, "MTM": 748807, "margined": true }, - { "id": 235, "product": "Vanilla IRS", "tradeDate": "2015-06-22", "effectiveDate": "2016-07-29", "maturityDate": "2015-08-07", "currency": "EUR", "notional": 974897, "IM": 834048, "MTM": 686951, "margined": true }, - { "id": 236, "product": "Vanilla IRS", "tradeDate": "2015-03-10", "effectiveDate": "2015-01-12", "maturityDate": "2015-11-21", "currency": "EUR", "notional": 577094, "IM": 373660, "MTM": 825934, "margined": true }, - { "id": 237, "product": "Vanilla IRS", "tradeDate": "2015-02-16", "effectiveDate": "2015-01-26", "maturityDate": "2016-02-01", "currency": "EUR", "notional": 863092, "IM": 434930, "MTM": 909051, "margined": true }, - { "id": 238, "product": "Vanilla IRS", "tradeDate": "2016-05-26", "effectiveDate": "2015-04-01", "maturityDate": "2016-05-04", "currency": "EUR", "notional": 698829, "IM": 114321, "MTM": 160921, "margined": true }, - { "id": 239, "product": "Vanilla IRS", "tradeDate": "2016-01-07", "effectiveDate": "2015-06-04", "maturityDate": "2015-09-23", "currency": "EUR", "notional": 311718, "IM": 801998, "MTM": 842009, "margined": true }, - { "id": 240, "product": "Vanilla IRS", "tradeDate": "2016-07-26", "effectiveDate": "2015-04-06", "maturityDate": "2015-12-25", "currency": "EUR", "notional": 341873, "IM": 729171, "MTM": 274249, "margined": true }, - { "id": 241, "product": "Vanilla IRS", "tradeDate": "2015-06-02", "effectiveDate": "2016-04-28", "maturityDate": "2015-01-27", "currency": "EUR", "notional": 218974, "IM": 191045, "MTM": 255279, "margined": true }, - { "id": 242, "product": "Vanilla IRS", "tradeDate": "2015-02-12", "effectiveDate": "2016-05-09", "maturityDate": "2016-05-19", "currency": "EUR", "notional": 766589, "IM": 906673, "MTM": 542975, "margined": true }, - { "id": 243, "product": "Vanilla IRS", "tradeDate": "2015-02-26", "effectiveDate": "2015-03-03", "maturityDate": "2015-09-13", "currency": "EUR", "notional": 955935, "IM": 112513, "MTM": 781381, "margined": true }, - { "id": 244, "product": "Vanilla IRS", "tradeDate": "2015-04-15", "effectiveDate": "2015-06-26", "maturityDate": "2015-08-05", "currency": "EUR", "notional": 111591, "IM": 175302, "MTM": 245891, "margined": true }, - { "id": 245, "product": "Vanilla IRS", "tradeDate": "2016-05-15", "effectiveDate": "2016-05-06", "maturityDate": "2016-02-25", "currency": "EUR", "notional": 885253, "IM": 556764, "MTM": 772196, "margined": true }, - { "id": 246, "product": "Vanilla IRS", "tradeDate": "2016-05-05", "effectiveDate": "2015-04-19", "maturityDate": "2015-04-09", "currency": "EUR", "notional": 410430, "IM": 527024, "MTM": 624572, "margined": true }, - { "id": 247, "product": "Vanilla IRS", "tradeDate": "2016-04-18", "effectiveDate": "2016-03-21", "maturityDate": "2016-02-07", "currency": "EUR", "notional": 304155, "IM": 647200, "MTM": 602136, "margined": true }, - { "id": 248, "product": "Vanilla IRS", "tradeDate": "2016-04-06", "effectiveDate": "2015-09-15", "maturityDate": "2015-03-26", "currency": "EUR", "notional": 354148, "IM": 803855, "MTM": 694514, "margined": true }, - { "id": 249, "product": "Vanilla IRS", "tradeDate": "2015-08-16", "effectiveDate": "2015-06-13", "maturityDate": "2015-12-12", "currency": "EUR", "notional": 810360, "IM": 926528, "MTM": 744766, "margined": true }, - { "id": 250, "product": "Vanilla IRS", "tradeDate": "2015-01-18", "effectiveDate": "2015-11-28", "maturityDate": "2015-09-01", "currency": "EUR", "notional": 280255, "IM": 178704, "MTM": 113958, "margined": true } -] diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/business-date b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/business-date deleted file mode 100644 index 3866519636..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/business-date +++ /dev/null @@ -1,3 +0,0 @@ -{ - "businessDate": "2016-09-31" -} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/history/aggregated b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/history/aggregated deleted file mode 100644 index 0e76e8a89b..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/history/aggregated +++ /dev/null @@ -1,1000 +0,0 @@ -[{"id":1,"date":1364774400000,"IM":1959426,"MTM":16409130,"notional":11799198,"activeTrades":158}, -{"id":2,"date":1364860800000,"IM":1282085,"MTM":19574770,"notional":14829876,"activeTrades":140}, -{"id":3,"date":1364947200000,"IM":1609354,"MTM":17995978,"notional":14240378,"activeTrades":103}, -{"id":4,"date":1365033600000,"IM":1982424,"MTM":11360478,"notional":10446609,"activeTrades":114}, -{"id":5,"date":1365120000000,"IM":1499078,"MTM":18856289,"notional":12739058,"activeTrades":110}, -{"id":6,"date":1365206400000,"IM":1237298,"MTM":11710154,"notional":13340408,"activeTrades":126}, -{"id":7,"date":1365292800000,"IM":1103421,"MTM":14193683,"notional":13896435,"activeTrades":138}, -{"id":8,"date":1365379200000,"IM":1777947,"MTM":11793404,"notional":15060102,"activeTrades":185}, -{"id":9,"date":1365465600000,"IM":1018116,"MTM":12194482,"notional":14047416,"activeTrades":126}, -{"id":10,"date":1365552000000,"IM":1388180,"MTM":16239740,"notional":14007180,"activeTrades":157}, -{"id":11,"date":1365638400000,"IM":1476966,"MTM":15881549,"notional":12090699,"activeTrades":182}, -{"id":12,"date":1365724800000,"IM":1398947,"MTM":18260946,"notional":13680506,"activeTrades":180}, -{"id":13,"date":1365811200000,"IM":1883662,"MTM":10896138,"notional":12449838,"activeTrades":146}, -{"id":14,"date":1365897600000,"IM":1074864,"MTM":12605140,"notional":13966099,"activeTrades":199}, -{"id":15,"date":1365984000000,"IM":1723898,"MTM":19383814,"notional":14491057,"activeTrades":123}, -{"id":16,"date":1366070400000,"IM":1177447,"MTM":17007313,"notional":19539568,"activeTrades":127}, -{"id":17,"date":1366156800000,"IM":1319353,"MTM":11893644,"notional":13731286,"activeTrades":195}, -{"id":18,"date":1366243200000,"IM":1030340,"MTM":16404752,"notional":19317573,"activeTrades":184}, -{"id":19,"date":1366329600000,"IM":1395033,"MTM":15207057,"notional":18176697,"activeTrades":158}, -{"id":20,"date":1366416000000,"IM":1694986,"MTM":19543272,"notional":19048857,"activeTrades":170}, -{"id":21,"date":1366502400000,"IM":1074245,"MTM":12231047,"notional":14101148,"activeTrades":127}, -{"id":22,"date":1366588800000,"IM":1103367,"MTM":12382484,"notional":14290612,"activeTrades":195}, -{"id":23,"date":1366675200000,"IM":1898357,"MTM":18185946,"notional":16269951,"activeTrades":184}, -{"id":24,"date":1366761600000,"IM":1215086,"MTM":18700041,"notional":10793600,"activeTrades":125}, -{"id":25,"date":1366848000000,"IM":1110935,"MTM":18412704,"notional":11465926,"activeTrades":171}, -{"id":26,"date":1366934400000,"IM":1322198,"MTM":11180062,"notional":18221853,"activeTrades":151}, -{"id":27,"date":1367020800000,"IM":1194627,"MTM":17762161,"notional":12617741,"activeTrades":174}, -{"id":28,"date":1367107200000,"IM":1385050,"MTM":17643838,"notional":10269032,"activeTrades":120}, -{"id":29,"date":1367193600000,"IM":1114804,"MTM":16256817,"notional":16363986,"activeTrades":177}, -{"id":30,"date":1367280000000,"IM":1175349,"MTM":10523118,"notional":18628427,"activeTrades":142}, -{"id":31,"date":1367366400000,"IM":1740687,"MTM":11065644,"notional":11814483,"activeTrades":150}, -{"id":32,"date":1367452800000,"IM":1509899,"MTM":13015098,"notional":15847581,"activeTrades":157}, -{"id":33,"date":1367539200000,"IM":1090796,"MTM":12213408,"notional":14986784,"activeTrades":189}, -{"id":34,"date":1367625600000,"IM":1580127,"MTM":17982949,"notional":15341878,"activeTrades":193}, -{"id":35,"date":1367712000000,"IM":1599230,"MTM":18865990,"notional":15354007,"activeTrades":188}, -{"id":36,"date":1367798400000,"IM":1639198,"MTM":14765008,"notional":15324131,"activeTrades":117}, -{"id":37,"date":1367884800000,"IM":1095980,"MTM":13535414,"notional":10826179,"activeTrades":114}, -{"id":38,"date":1367971200000,"IM":1859889,"MTM":14864440,"notional":11484608,"activeTrades":106}, -{"id":39,"date":1368057600000,"IM":1389973,"MTM":11803315,"notional":18037372,"activeTrades":106}, -{"id":40,"date":1368144000000,"IM":1061091,"MTM":17694490,"notional":16696672,"activeTrades":156}, -{"id":41,"date":1368230400000,"IM":1074418,"MTM":11994328,"notional":14480360,"activeTrades":128}, -{"id":42,"date":1368316800000,"IM":1438839,"MTM":16064375,"notional":19967893,"activeTrades":200}, -{"id":43,"date":1368403200000,"IM":1297032,"MTM":11342874,"notional":16262553,"activeTrades":174}, -{"id":44,"date":1368489600000,"IM":1721517,"MTM":14609981,"notional":10794890,"activeTrades":130}, -{"id":45,"date":1368576000000,"IM":1414748,"MTM":14162299,"notional":15501312,"activeTrades":124}, -{"id":46,"date":1368662400000,"IM":1072913,"MTM":18116085,"notional":18512415,"activeTrades":107}, -{"id":47,"date":1368748800000,"IM":1286831,"MTM":10549561,"notional":16778247,"activeTrades":158}, -{"id":48,"date":1368835200000,"IM":1495025,"MTM":13075318,"notional":12586395,"activeTrades":107}, -{"id":49,"date":1368921600000,"IM":1488199,"MTM":13607576,"notional":13413514,"activeTrades":108}, -{"id":50,"date":1369008000000,"IM":1790383,"MTM":13265771,"notional":19193618,"activeTrades":182}, -{"id":51,"date":1369094400000,"IM":1767760,"MTM":17354162,"notional":17238148,"activeTrades":177}, -{"id":52,"date":1369180800000,"IM":1259406,"MTM":18333333,"notional":18083095,"activeTrades":115}, -{"id":53,"date":1369267200000,"IM":1000159,"MTM":16993678,"notional":13916080,"activeTrades":153}, -{"id":54,"date":1369353600000,"IM":1068584,"MTM":15554901,"notional":10235887,"activeTrades":199}, -{"id":55,"date":1369440000000,"IM":1465307,"MTM":15801060,"notional":17610390,"activeTrades":154}, -{"id":56,"date":1369526400000,"IM":1487450,"MTM":19043098,"notional":18915125,"activeTrades":122}, -{"id":57,"date":1369612800000,"IM":1118296,"MTM":10298563,"notional":11041331,"activeTrades":185}, -{"id":58,"date":1369699200000,"IM":1767011,"MTM":13220741,"notional":16853076,"activeTrades":156}, -{"id":59,"date":1369785600000,"IM":1535742,"MTM":19545719,"notional":10007070,"activeTrades":187}, -{"id":60,"date":1369872000000,"IM":1250811,"MTM":12977321,"notional":16936265,"activeTrades":162}, -{"id":61,"date":1369958400000,"IM":1101790,"MTM":14513421,"notional":15160976,"activeTrades":195}, -{"id":62,"date":1370044800000,"IM":1356761,"MTM":10560430,"notional":13890771,"activeTrades":174}, -{"id":63,"date":1370131200000,"IM":1181967,"MTM":18111016,"notional":17314082,"activeTrades":151}, -{"id":64,"date":1370217600000,"IM":1446388,"MTM":18939875,"notional":12992708,"activeTrades":129}, -{"id":65,"date":1370304000000,"IM":1278802,"MTM":14827390,"notional":12122225,"activeTrades":133}, -{"id":66,"date":1370390400000,"IM":1160585,"MTM":19577714,"notional":13633997,"activeTrades":169}, -{"id":67,"date":1370476800000,"IM":1828115,"MTM":12715625,"notional":19683483,"activeTrades":117}, -{"id":68,"date":1370563200000,"IM":1121076,"MTM":10252620,"notional":17103519,"activeTrades":125}, -{"id":69,"date":1370649600000,"IM":1588190,"MTM":11971935,"notional":18569596,"activeTrades":122}, -{"id":70,"date":1370736000000,"IM":1064713,"MTM":16377643,"notional":11126753,"activeTrades":176}, -{"id":71,"date":1370822400000,"IM":1741565,"MTM":10009071,"notional":11204834,"activeTrades":190}, -{"id":72,"date":1370908800000,"IM":1040915,"MTM":16441254,"notional":15450973,"activeTrades":166}, -{"id":73,"date":1370995200000,"IM":1050268,"MTM":19980656,"notional":11354178,"activeTrades":148}, -{"id":74,"date":1371081600000,"IM":1828745,"MTM":15762563,"notional":19711615,"activeTrades":124}, -{"id":75,"date":1371168000000,"IM":1833389,"MTM":11406931,"notional":18766169,"activeTrades":145}, -{"id":76,"date":1371254400000,"IM":1658658,"MTM":18833010,"notional":12218595,"activeTrades":197}, -{"id":77,"date":1371340800000,"IM":1435074,"MTM":17336975,"notional":10752472,"activeTrades":133}, -{"id":78,"date":1371427200000,"IM":1716333,"MTM":17943975,"notional":16315645,"activeTrades":180}, -{"id":79,"date":1371513600000,"IM":1449800,"MTM":12092878,"notional":12211866,"activeTrades":144}, -{"id":80,"date":1371600000000,"IM":1571497,"MTM":13026364,"notional":16598495,"activeTrades":172}, -{"id":81,"date":1371686400000,"IM":1811334,"MTM":14267473,"notional":12223013,"activeTrades":191}, -{"id":82,"date":1371772800000,"IM":1008234,"MTM":17550134,"notional":19965287,"activeTrades":142}, -{"id":83,"date":1371859200000,"IM":1764151,"MTM":15258376,"notional":12588652,"activeTrades":167}, -{"id":84,"date":1371945600000,"IM":1549466,"MTM":10453481,"notional":13461754,"activeTrades":180}, -{"id":85,"date":1372032000000,"IM":1955080,"MTM":18233592,"notional":12365991,"activeTrades":186}, -{"id":86,"date":1372118400000,"IM":1677582,"MTM":11954349,"notional":16607859,"activeTrades":124}, -{"id":87,"date":1372204800000,"IM":1369385,"MTM":18424637,"notional":10554329,"activeTrades":144}, -{"id":88,"date":1372291200000,"IM":1071648,"MTM":16844439,"notional":18532599,"activeTrades":126}, -{"id":89,"date":1372377600000,"IM":1183168,"MTM":11180439,"notional":19558212,"activeTrades":122}, -{"id":90,"date":1372464000000,"IM":1575614,"MTM":17353415,"notional":13050257,"activeTrades":166}, -{"id":91,"date":1372550400000,"IM":1216450,"MTM":14469259,"notional":19872588,"activeTrades":111}, -{"id":92,"date":1372636800000,"IM":1366630,"MTM":18106249,"notional":16964948,"activeTrades":143}, -{"id":93,"date":1372723200000,"IM":1510087,"MTM":11282792,"notional":16507614,"activeTrades":149}, -{"id":94,"date":1372809600000,"IM":1165689,"MTM":12675811,"notional":10829243,"activeTrades":175}, -{"id":95,"date":1372896000000,"IM":1527935,"MTM":19181020,"notional":11545513,"activeTrades":106}, -{"id":96,"date":1372982400000,"IM":1346023,"MTM":11652104,"notional":18175825,"activeTrades":142}, -{"id":97,"date":1373068800000,"IM":1525355,"MTM":12390852,"notional":16229920,"activeTrades":125}, -{"id":98,"date":1373155200000,"IM":1814432,"MTM":19741306,"notional":19324354,"activeTrades":106}, -{"id":99,"date":1373241600000,"IM":1078593,"MTM":19733626,"notional":13112424,"activeTrades":111}, -{"id":100,"date":1373328000000,"IM":1027605,"MTM":15290426,"notional":10759456,"activeTrades":191}, -{"id":101,"date":1373414400000,"IM":1777779,"MTM":17402490,"notional":11633070,"activeTrades":141}, -{"id":102,"date":1373500800000,"IM":1925305,"MTM":17434204,"notional":18982278,"activeTrades":169}, -{"id":103,"date":1373587200000,"IM":1384115,"MTM":16585988,"notional":10586618,"activeTrades":179}, -{"id":104,"date":1373673600000,"IM":1358240,"MTM":16155187,"notional":10396943,"activeTrades":177}, -{"id":105,"date":1373760000000,"IM":1505403,"MTM":16371046,"notional":18175069,"activeTrades":113}, -{"id":106,"date":1373846400000,"IM":1342146,"MTM":12093818,"notional":16133722,"activeTrades":186}, -{"id":107,"date":1373932800000,"IM":1160663,"MTM":17121145,"notional":13869934,"activeTrades":165}, -{"id":108,"date":1374019200000,"IM":1027673,"MTM":17920112,"notional":19330173,"activeTrades":190}, -{"id":109,"date":1374105600000,"IM":1958570,"MTM":16634834,"notional":19195616,"activeTrades":180}, -{"id":110,"date":1374192000000,"IM":1901464,"MTM":15001703,"notional":19040958,"activeTrades":192}, -{"id":111,"date":1374278400000,"IM":1766018,"MTM":13959727,"notional":10634757,"activeTrades":150}, -{"id":112,"date":1374364800000,"IM":1060880,"MTM":15660127,"notional":10792556,"activeTrades":101}, -{"id":113,"date":1374451200000,"IM":1605316,"MTM":17494435,"notional":14208905,"activeTrades":190}, -{"id":114,"date":1374537600000,"IM":1272338,"MTM":18092095,"notional":16287295,"activeTrades":142}, -{"id":115,"date":1374624000000,"IM":1234338,"MTM":14233674,"notional":10768615,"activeTrades":124}, -{"id":116,"date":1374710400000,"IM":1510020,"MTM":10955846,"notional":13805108,"activeTrades":135}, -{"id":117,"date":1374796800000,"IM":1076130,"MTM":15451234,"notional":16576707,"activeTrades":149}, -{"id":118,"date":1374883200000,"IM":1378573,"MTM":18483786,"notional":18867271,"activeTrades":102}, -{"id":119,"date":1374969600000,"IM":1838040,"MTM":16399600,"notional":10748871,"activeTrades":113}, -{"id":120,"date":1375056000000,"IM":1341518,"MTM":16633027,"notional":17206798,"activeTrades":123}, -{"id":121,"date":1375142400000,"IM":1050586,"MTM":15093707,"notional":18509095,"activeTrades":150}, -{"id":122,"date":1375228800000,"IM":1735168,"MTM":18307911,"notional":13908415,"activeTrades":115}, -{"id":123,"date":1375315200000,"IM":1052617,"MTM":17064216,"notional":15994221,"activeTrades":191}, -{"id":124,"date":1375401600000,"IM":1875982,"MTM":10230834,"notional":13781017,"activeTrades":196}, -{"id":125,"date":1375488000000,"IM":1560214,"MTM":18522084,"notional":11258752,"activeTrades":105}, -{"id":126,"date":1375574400000,"IM":1068374,"MTM":13430320,"notional":19144732,"activeTrades":126}, -{"id":127,"date":1375660800000,"IM":1959256,"MTM":12053355,"notional":11064333,"activeTrades":193}, -{"id":128,"date":1375747200000,"IM":1973121,"MTM":18552421,"notional":10151200,"activeTrades":122}, -{"id":129,"date":1375833600000,"IM":1231572,"MTM":12401245,"notional":11668238,"activeTrades":104}, -{"id":130,"date":1375920000000,"IM":1548359,"MTM":15651645,"notional":19340712,"activeTrades":118}, -{"id":131,"date":1376006400000,"IM":1154542,"MTM":18826678,"notional":18397395,"activeTrades":200}, -{"id":132,"date":1376092800000,"IM":1684964,"MTM":15260090,"notional":12807754,"activeTrades":199}, -{"id":133,"date":1376179200000,"IM":1910688,"MTM":15523611,"notional":10565439,"activeTrades":102}, -{"id":134,"date":1376265600000,"IM":1983299,"MTM":13989748,"notional":16747310,"activeTrades":194}, -{"id":135,"date":1376352000000,"IM":1695794,"MTM":12294509,"notional":17437694,"activeTrades":195}, -{"id":136,"date":1376438400000,"IM":1825080,"MTM":18965430,"notional":13828262,"activeTrades":132}, -{"id":137,"date":1376524800000,"IM":1665118,"MTM":15655924,"notional":17830389,"activeTrades":132}, -{"id":138,"date":1376611200000,"IM":1006719,"MTM":18173888,"notional":11212738,"activeTrades":197}, -{"id":139,"date":1376697600000,"IM":1752186,"MTM":19903426,"notional":12354920,"activeTrades":139}, -{"id":140,"date":1376784000000,"IM":1447958,"MTM":17141758,"notional":17135268,"activeTrades":158}, -{"id":141,"date":1376870400000,"IM":1503110,"MTM":17975245,"notional":17810255,"activeTrades":177}, -{"id":142,"date":1376956800000,"IM":1561615,"MTM":10913341,"notional":10316911,"activeTrades":119}, -{"id":143,"date":1377043200000,"IM":1579463,"MTM":18461499,"notional":18942893,"activeTrades":178}, -{"id":144,"date":1377129600000,"IM":1380626,"MTM":16851479,"notional":12792639,"activeTrades":141}, -{"id":145,"date":1377216000000,"IM":1163352,"MTM":12334991,"notional":18262981,"activeTrades":104}, -{"id":146,"date":1377302400000,"IM":1810146,"MTM":19226087,"notional":10634402,"activeTrades":124}, -{"id":147,"date":1377388800000,"IM":1694769,"MTM":17489847,"notional":18775277,"activeTrades":116}, -{"id":148,"date":1377475200000,"IM":1607408,"MTM":15196138,"notional":18368675,"activeTrades":166}, -{"id":149,"date":1377561600000,"IM":1612091,"MTM":18797715,"notional":16685514,"activeTrades":100}, -{"id":150,"date":1377648000000,"IM":1860805,"MTM":11220462,"notional":12975752,"activeTrades":166}, -{"id":151,"date":1377734400000,"IM":1319602,"MTM":15887433,"notional":17350285,"activeTrades":192}, -{"id":152,"date":1377820800000,"IM":1554534,"MTM":11897490,"notional":10489842,"activeTrades":115}, -{"id":153,"date":1377907200000,"IM":1607456,"MTM":18143102,"notional":11694703,"activeTrades":129}, -{"id":154,"date":1377993600000,"IM":1801481,"MTM":15560135,"notional":17435656,"activeTrades":105}, -{"id":155,"date":1378080000000,"IM":1206691,"MTM":12555640,"notional":16951497,"activeTrades":175}, -{"id":156,"date":1378166400000,"IM":1313987,"MTM":15960292,"notional":10714662,"activeTrades":181}, -{"id":157,"date":1378252800000,"IM":1800758,"MTM":13302032,"notional":19445701,"activeTrades":138}, -{"id":158,"date":1378339200000,"IM":1262355,"MTM":14281330,"notional":13934127,"activeTrades":114}, -{"id":159,"date":1378425600000,"IM":1496365,"MTM":14977950,"notional":12407806,"activeTrades":140}, -{"id":160,"date":1378512000000,"IM":1768939,"MTM":15862153,"notional":17149379,"activeTrades":104}, -{"id":161,"date":1378598400000,"IM":1779252,"MTM":13141304,"notional":18974741,"activeTrades":149}, -{"id":162,"date":1378684800000,"IM":1553746,"MTM":18695375,"notional":14730620,"activeTrades":126}, -{"id":163,"date":1378771200000,"IM":1890136,"MTM":10526701,"notional":16643507,"activeTrades":169}, -{"id":164,"date":1378857600000,"IM":1434149,"MTM":16982873,"notional":16580260,"activeTrades":129}, -{"id":165,"date":1378944000000,"IM":1522736,"MTM":13111927,"notional":13294245,"activeTrades":117}, -{"id":166,"date":1379030400000,"IM":1879841,"MTM":11767438,"notional":15807603,"activeTrades":100}, -{"id":167,"date":1379116800000,"IM":1893817,"MTM":12752734,"notional":17311297,"activeTrades":126}, -{"id":168,"date":1379203200000,"IM":1372116,"MTM":10972635,"notional":13364451,"activeTrades":182}, -{"id":169,"date":1379289600000,"IM":1199330,"MTM":18301410,"notional":10184706,"activeTrades":187}, -{"id":170,"date":1379376000000,"IM":1382094,"MTM":12504254,"notional":12920227,"activeTrades":119}, -{"id":171,"date":1379462400000,"IM":1616453,"MTM":18256820,"notional":13893290,"activeTrades":178}, -{"id":172,"date":1379548800000,"IM":1652688,"MTM":18448673,"notional":19292585,"activeTrades":177}, -{"id":173,"date":1379635200000,"IM":1920550,"MTM":16237416,"notional":16897410,"activeTrades":107}, -{"id":174,"date":1379721600000,"IM":1695195,"MTM":19528390,"notional":14436354,"activeTrades":197}, -{"id":175,"date":1379808000000,"IM":1038836,"MTM":19403158,"notional":13364290,"activeTrades":100}, -{"id":176,"date":1379894400000,"IM":1216770,"MTM":15440156,"notional":16788452,"activeTrades":179}, -{"id":177,"date":1379980800000,"IM":1915697,"MTM":13808835,"notional":19449461,"activeTrades":148}, -{"id":178,"date":1380067200000,"IM":1857506,"MTM":18725008,"notional":14822120,"activeTrades":200}, -{"id":179,"date":1380153600000,"IM":1340949,"MTM":11690423,"notional":17190957,"activeTrades":113}, -{"id":180,"date":1380240000000,"IM":1708754,"MTM":13104294,"notional":15629812,"activeTrades":183}, -{"id":181,"date":1380326400000,"IM":1646662,"MTM":11823297,"notional":15188707,"activeTrades":100}, -{"id":182,"date":1380412800000,"IM":1693670,"MTM":11895086,"notional":13082099,"activeTrades":196}, -{"id":183,"date":1380499200000,"IM":1335201,"MTM":19672400,"notional":19522364,"activeTrades":134}, -{"id":184,"date":1380585600000,"IM":1789055,"MTM":14665795,"notional":13894001,"activeTrades":161}, -{"id":185,"date":1380672000000,"IM":1270270,"MTM":10401986,"notional":11154427,"activeTrades":139}, -{"id":186,"date":1380758400000,"IM":1250466,"MTM":11892101,"notional":18620811,"activeTrades":191}, -{"id":187,"date":1380844800000,"IM":1418632,"MTM":14781864,"notional":13827636,"activeTrades":194}, -{"id":188,"date":1380931200000,"IM":1168946,"MTM":15093486,"notional":12205386,"activeTrades":143}, -{"id":189,"date":1381017600000,"IM":1406496,"MTM":19527956,"notional":14304717,"activeTrades":177}, -{"id":190,"date":1381104000000,"IM":1625617,"MTM":11003848,"notional":14309309,"activeTrades":117}, -{"id":191,"date":1381190400000,"IM":1854536,"MTM":16042434,"notional":16505788,"activeTrades":179}, -{"id":192,"date":1381276800000,"IM":1286850,"MTM":18667165,"notional":16355095,"activeTrades":138}, -{"id":193,"date":1381363200000,"IM":1258825,"MTM":17996150,"notional":13244777,"activeTrades":195}, -{"id":194,"date":1381449600000,"IM":1676433,"MTM":15299261,"notional":16141232,"activeTrades":107}, -{"id":195,"date":1381536000000,"IM":1069151,"MTM":15505791,"notional":13007386,"activeTrades":123}, -{"id":196,"date":1381622400000,"IM":1529829,"MTM":15556028,"notional":17575914,"activeTrades":200}, -{"id":197,"date":1381708800000,"IM":1512884,"MTM":12896219,"notional":10274816,"activeTrades":167}, -{"id":198,"date":1381795200000,"IM":1018620,"MTM":16604665,"notional":19638979,"activeTrades":144}, -{"id":199,"date":1381881600000,"IM":1187892,"MTM":12639563,"notional":18003684,"activeTrades":154}, -{"id":200,"date":1381968000000,"IM":1432041,"MTM":19820908,"notional":15485740,"activeTrades":120}, -{"id":201,"date":1382054400000,"IM":1332482,"MTM":13324950,"notional":15463839,"activeTrades":119}, -{"id":202,"date":1382140800000,"IM":1130595,"MTM":13075287,"notional":15555617,"activeTrades":192}, -{"id":203,"date":1382227200000,"IM":1406188,"MTM":10324787,"notional":15908323,"activeTrades":194}, -{"id":204,"date":1382313600000,"IM":1360467,"MTM":15975841,"notional":13147523,"activeTrades":149}, -{"id":205,"date":1382400000000,"IM":1246013,"MTM":10572196,"notional":10353154,"activeTrades":141}, -{"id":206,"date":1382486400000,"IM":1852811,"MTM":12428544,"notional":13292949,"activeTrades":177}, -{"id":207,"date":1382572800000,"IM":1354527,"MTM":18658195,"notional":12347143,"activeTrades":194}, -{"id":208,"date":1382659200000,"IM":1829129,"MTM":19083526,"notional":13753360,"activeTrades":103}, -{"id":209,"date":1382745600000,"IM":1583304,"MTM":13932798,"notional":12172273,"activeTrades":176}, -{"id":210,"date":1382832000000,"IM":1103341,"MTM":11474576,"notional":19297623,"activeTrades":123}, -{"id":211,"date":1382918400000,"IM":1346970,"MTM":17833903,"notional":14581117,"activeTrades":129}, -{"id":212,"date":1383004800000,"IM":1928439,"MTM":17073709,"notional":18314169,"activeTrades":142}, -{"id":213,"date":1383091200000,"IM":1459492,"MTM":12742548,"notional":10431053,"activeTrades":183}, -{"id":214,"date":1383177600000,"IM":1676418,"MTM":11300304,"notional":19352813,"activeTrades":160}, -{"id":215,"date":1383264000000,"IM":1337265,"MTM":12284771,"notional":13287197,"activeTrades":118}, -{"id":216,"date":1383350400000,"IM":1699702,"MTM":17156450,"notional":10352273,"activeTrades":183}, -{"id":217,"date":1383436800000,"IM":1634305,"MTM":16034661,"notional":11790167,"activeTrades":177}, -{"id":218,"date":1383523200000,"IM":1859989,"MTM":10476336,"notional":10881021,"activeTrades":179}, -{"id":219,"date":1383609600000,"IM":1967472,"MTM":18191822,"notional":19894319,"activeTrades":115}, -{"id":220,"date":1383696000000,"IM":1697831,"MTM":14856106,"notional":10888376,"activeTrades":150}, -{"id":221,"date":1383782400000,"IM":1398974,"MTM":14730831,"notional":14406372,"activeTrades":115}, -{"id":222,"date":1383868800000,"IM":1747083,"MTM":12788102,"notional":18802836,"activeTrades":161}, -{"id":223,"date":1383955200000,"IM":1414171,"MTM":18428377,"notional":16720740,"activeTrades":163}, -{"id":224,"date":1384041600000,"IM":1606486,"MTM":17262543,"notional":17994665,"activeTrades":178}, -{"id":225,"date":1384128000000,"IM":1795367,"MTM":12365221,"notional":10736864,"activeTrades":140}, -{"id":226,"date":1384214400000,"IM":1538953,"MTM":15397343,"notional":10721856,"activeTrades":101}, -{"id":227,"date":1384300800000,"IM":1198301,"MTM":16900781,"notional":18020298,"activeTrades":118}, -{"id":228,"date":1384387200000,"IM":1448590,"MTM":14695147,"notional":11164746,"activeTrades":183}, -{"id":229,"date":1384473600000,"IM":1364115,"MTM":12326022,"notional":14933426,"activeTrades":175}, -{"id":230,"date":1384560000000,"IM":1422046,"MTM":17570995,"notional":13484781,"activeTrades":140}, -{"id":231,"date":1384646400000,"IM":1618283,"MTM":13689718,"notional":17048860,"activeTrades":108}, -{"id":232,"date":1384732800000,"IM":1610350,"MTM":18463428,"notional":12029148,"activeTrades":120}, -{"id":233,"date":1384819200000,"IM":1563556,"MTM":16181884,"notional":15185226,"activeTrades":107}, -{"id":234,"date":1384905600000,"IM":1854722,"MTM":12608706,"notional":14358753,"activeTrades":137}, -{"id":235,"date":1384992000000,"IM":1713541,"MTM":18538288,"notional":11912442,"activeTrades":180}, -{"id":236,"date":1385078400000,"IM":1884555,"MTM":16496856,"notional":16601787,"activeTrades":168}, -{"id":237,"date":1385164800000,"IM":1263718,"MTM":14711809,"notional":11853456,"activeTrades":178}, -{"id":238,"date":1385251200000,"IM":1431741,"MTM":16041314,"notional":13155772,"activeTrades":175}, -{"id":239,"date":1385337600000,"IM":1868024,"MTM":18523153,"notional":15391010,"activeTrades":121}, -{"id":240,"date":1385424000000,"IM":1688493,"MTM":14405894,"notional":17371939,"activeTrades":105}, -{"id":241,"date":1385510400000,"IM":1233800,"MTM":10134924,"notional":18185387,"activeTrades":135}, -{"id":242,"date":1385596800000,"IM":1158345,"MTM":16101242,"notional":11533771,"activeTrades":198}, -{"id":243,"date":1385683200000,"IM":1409180,"MTM":12198010,"notional":16003379,"activeTrades":130}, -{"id":244,"date":1385769600000,"IM":1248877,"MTM":12767572,"notional":18870619,"activeTrades":105}, -{"id":245,"date":1385856000000,"IM":1309430,"MTM":14284856,"notional":17668233,"activeTrades":171}, -{"id":246,"date":1385942400000,"IM":1692426,"MTM":17132717,"notional":15475543,"activeTrades":152}, -{"id":247,"date":1386028800000,"IM":1128005,"MTM":11656076,"notional":11195978,"activeTrades":130}, -{"id":248,"date":1386115200000,"IM":1259910,"MTM":19987950,"notional":10821530,"activeTrades":126}, -{"id":249,"date":1386201600000,"IM":1068911,"MTM":18560417,"notional":18767399,"activeTrades":179}, -{"id":250,"date":1386288000000,"IM":1660927,"MTM":11790582,"notional":15310289,"activeTrades":146}, -{"id":251,"date":1386374400000,"IM":1451772,"MTM":12596665,"notional":14862196,"activeTrades":132}, -{"id":252,"date":1386460800000,"IM":1043763,"MTM":18626563,"notional":18135719,"activeTrades":149}, -{"id":253,"date":1386547200000,"IM":1151661,"MTM":12726252,"notional":19168490,"activeTrades":181}, -{"id":254,"date":1386633600000,"IM":1815415,"MTM":15087040,"notional":16356628,"activeTrades":105}, -{"id":255,"date":1386720000000,"IM":1228218,"MTM":10381203,"notional":13148220,"activeTrades":200}, -{"id":256,"date":1386806400000,"IM":1424278,"MTM":14974831,"notional":14801154,"activeTrades":197}, -{"id":257,"date":1386892800000,"IM":1098882,"MTM":15512917,"notional":15250109,"activeTrades":103}, -{"id":258,"date":1386979200000,"IM":1961083,"MTM":18688007,"notional":18298764,"activeTrades":127}, -{"id":259,"date":1387065600000,"IM":1737582,"MTM":19654444,"notional":16109693,"activeTrades":147}, -{"id":260,"date":1387152000000,"IM":1152873,"MTM":15477800,"notional":15764681,"activeTrades":199}, -{"id":261,"date":1387238400000,"IM":1425774,"MTM":17553418,"notional":16934993,"activeTrades":195}, -{"id":262,"date":1387324800000,"IM":1145951,"MTM":16137460,"notional":13276041,"activeTrades":160}, -{"id":263,"date":1387411200000,"IM":1718512,"MTM":16344554,"notional":15479942,"activeTrades":178}, -{"id":264,"date":1387497600000,"IM":1403081,"MTM":14799836,"notional":14546524,"activeTrades":151}, -{"id":265,"date":1387584000000,"IM":1857700,"MTM":16500371,"notional":19867857,"activeTrades":100}, -{"id":266,"date":1387670400000,"IM":1850990,"MTM":19770696,"notional":12607152,"activeTrades":153}, -{"id":267,"date":1387756800000,"IM":1408170,"MTM":16593457,"notional":18103136,"activeTrades":114}, -{"id":268,"date":1387843200000,"IM":1656683,"MTM":15823984,"notional":12394339,"activeTrades":164}, -{"id":269,"date":1387929600000,"IM":1283263,"MTM":11289929,"notional":10621490,"activeTrades":154}, -{"id":270,"date":1388016000000,"IM":1659311,"MTM":13420148,"notional":11857988,"activeTrades":109}, -{"id":271,"date":1388102400000,"IM":1000309,"MTM":19516125,"notional":18345079,"activeTrades":146}, -{"id":272,"date":1388188800000,"IM":1685323,"MTM":19728774,"notional":14482527,"activeTrades":111}, -{"id":273,"date":1388275200000,"IM":1493410,"MTM":16108609,"notional":17871776,"activeTrades":138}, -{"id":274,"date":1388361600000,"IM":1630741,"MTM":19957365,"notional":11885201,"activeTrades":130}, -{"id":275,"date":1388448000000,"IM":1708095,"MTM":16515361,"notional":14072429,"activeTrades":186}, -{"id":276,"date":1388534400000,"IM":1248811,"MTM":14292763,"notional":16673572,"activeTrades":166}, -{"id":277,"date":1388620800000,"IM":1682259,"MTM":10142989,"notional":14078038,"activeTrades":164}, -{"id":278,"date":1388707200000,"IM":1314418,"MTM":16940564,"notional":12300847,"activeTrades":108}, -{"id":279,"date":1388793600000,"IM":1284284,"MTM":19955458,"notional":14042944,"activeTrades":126}, -{"id":280,"date":1388880000000,"IM":1473592,"MTM":13617638,"notional":15798224,"activeTrades":112}, -{"id":281,"date":1388966400000,"IM":1600795,"MTM":18214821,"notional":14343088,"activeTrades":177}, -{"id":282,"date":1389052800000,"IM":1483364,"MTM":12467955,"notional":19382597,"activeTrades":134}, -{"id":283,"date":1389139200000,"IM":1154121,"MTM":12099640,"notional":15243993,"activeTrades":163}, -{"id":284,"date":1389225600000,"IM":1034168,"MTM":19371989,"notional":11074026,"activeTrades":164}, -{"id":285,"date":1389312000000,"IM":1658430,"MTM":15276962,"notional":18781978,"activeTrades":190}, -{"id":286,"date":1389398400000,"IM":1972534,"MTM":10217468,"notional":19529450,"activeTrades":104}, -{"id":287,"date":1389484800000,"IM":1813700,"MTM":15392058,"notional":15105105,"activeTrades":129}, -{"id":288,"date":1389571200000,"IM":1919617,"MTM":10903730,"notional":14334976,"activeTrades":117}, -{"id":289,"date":1389657600000,"IM":1123526,"MTM":17466257,"notional":12879502,"activeTrades":165}, -{"id":290,"date":1389744000000,"IM":1355463,"MTM":18863460,"notional":15552586,"activeTrades":102}, -{"id":291,"date":1389830400000,"IM":1323398,"MTM":10904182,"notional":19231973,"activeTrades":164}, -{"id":292,"date":1389916800000,"IM":1629710,"MTM":14290198,"notional":11974648,"activeTrades":185}, -{"id":293,"date":1390003200000,"IM":1130136,"MTM":12169806,"notional":10895573,"activeTrades":185}, -{"id":294,"date":1390089600000,"IM":1434872,"MTM":19556835,"notional":18026854,"activeTrades":187}, -{"id":295,"date":1390176000000,"IM":1600812,"MTM":10057140,"notional":12074183,"activeTrades":104}, -{"id":296,"date":1390262400000,"IM":1400044,"MTM":11561920,"notional":12996151,"activeTrades":123}, -{"id":297,"date":1390348800000,"IM":1670067,"MTM":16291002,"notional":13778073,"activeTrades":168}, -{"id":298,"date":1390435200000,"IM":1511524,"MTM":18612973,"notional":12859135,"activeTrades":187}, -{"id":299,"date":1390521600000,"IM":1286802,"MTM":17262832,"notional":16275283,"activeTrades":119}, -{"id":300,"date":1390608000000,"IM":1433198,"MTM":12299672,"notional":17647227,"activeTrades":132}, -{"id":301,"date":1390694400000,"IM":1367476,"MTM":14189382,"notional":18102467,"activeTrades":158}, -{"id":302,"date":1390780800000,"IM":1273641,"MTM":10793342,"notional":11346916,"activeTrades":109}, -{"id":303,"date":1390867200000,"IM":1541736,"MTM":15227728,"notional":10284553,"activeTrades":186}, -{"id":304,"date":1390953600000,"IM":1644988,"MTM":17809239,"notional":13009402,"activeTrades":108}, -{"id":305,"date":1391040000000,"IM":1547724,"MTM":13843544,"notional":19734783,"activeTrades":131}, -{"id":306,"date":1391126400000,"IM":1400108,"MTM":18921490,"notional":14713445,"activeTrades":123}, -{"id":307,"date":1391212800000,"IM":1823375,"MTM":16978558,"notional":13313654,"activeTrades":125}, -{"id":308,"date":1391299200000,"IM":1102105,"MTM":10829524,"notional":19293951,"activeTrades":199}, -{"id":309,"date":1391385600000,"IM":1186075,"MTM":17380159,"notional":18512498,"activeTrades":133}, -{"id":310,"date":1391472000000,"IM":1904802,"MTM":14245224,"notional":11564056,"activeTrades":114}, -{"id":311,"date":1391558400000,"IM":1303807,"MTM":15406411,"notional":16359569,"activeTrades":145}, -{"id":312,"date":1391644800000,"IM":1058567,"MTM":13639903,"notional":15189585,"activeTrades":165}, -{"id":313,"date":1391731200000,"IM":1099816,"MTM":17470070,"notional":13699766,"activeTrades":119}, -{"id":314,"date":1391817600000,"IM":1064687,"MTM":15382627,"notional":17410119,"activeTrades":103}, -{"id":315,"date":1391904000000,"IM":1069338,"MTM":13503058,"notional":11019074,"activeTrades":154}, -{"id":316,"date":1391990400000,"IM":1274431,"MTM":16361437,"notional":15869590,"activeTrades":200}, -{"id":317,"date":1392076800000,"IM":1877664,"MTM":15417846,"notional":19510273,"activeTrades":136}, -{"id":318,"date":1392163200000,"IM":1096312,"MTM":18571072,"notional":11532353,"activeTrades":120}, -{"id":319,"date":1392249600000,"IM":1576894,"MTM":15575225,"notional":16430397,"activeTrades":159}, -{"id":320,"date":1392336000000,"IM":1532415,"MTM":13075284,"notional":11891273,"activeTrades":154}, -{"id":321,"date":1392422400000,"IM":1188226,"MTM":14740240,"notional":10411189,"activeTrades":189}, -{"id":322,"date":1392508800000,"IM":1212060,"MTM":13357863,"notional":19868572,"activeTrades":178}, -{"id":323,"date":1392595200000,"IM":1321554,"MTM":19514886,"notional":16289598,"activeTrades":120}, -{"id":324,"date":1392681600000,"IM":1016362,"MTM":14294721,"notional":13943037,"activeTrades":185}, -{"id":325,"date":1392768000000,"IM":1764731,"MTM":11610008,"notional":15503716,"activeTrades":150}, -{"id":326,"date":1392854400000,"IM":1900427,"MTM":19479804,"notional":13940418,"activeTrades":173}, -{"id":327,"date":1392940800000,"IM":1182230,"MTM":16872898,"notional":17394461,"activeTrades":184}, -{"id":328,"date":1393027200000,"IM":1653304,"MTM":12566848,"notional":14649124,"activeTrades":191}, -{"id":329,"date":1393113600000,"IM":1977384,"MTM":17654807,"notional":14888965,"activeTrades":179}, -{"id":330,"date":1393200000000,"IM":1285011,"MTM":11532602,"notional":16406255,"activeTrades":178}, -{"id":331,"date":1393286400000,"IM":1031182,"MTM":13409208,"notional":14312891,"activeTrades":129}, -{"id":332,"date":1393372800000,"IM":1091804,"MTM":12812826,"notional":10441864,"activeTrades":112}, -{"id":333,"date":1393459200000,"IM":1945368,"MTM":17175311,"notional":15655018,"activeTrades":183}, -{"id":334,"date":1393545600000,"IM":1997123,"MTM":12416848,"notional":19860026,"activeTrades":196}, -{"id":335,"date":1393632000000,"IM":1185233,"MTM":18877954,"notional":15740774,"activeTrades":111}, -{"id":336,"date":1393718400000,"IM":1917193,"MTM":17042642,"notional":15597292,"activeTrades":166}, -{"id":337,"date":1393804800000,"IM":1426523,"MTM":16091030,"notional":12702330,"activeTrades":171}, -{"id":338,"date":1393891200000,"IM":1155665,"MTM":19822700,"notional":17333676,"activeTrades":145}, -{"id":339,"date":1393977600000,"IM":1818513,"MTM":12921269,"notional":17553835,"activeTrades":190}, -{"id":340,"date":1394064000000,"IM":1750750,"MTM":15983052,"notional":12176875,"activeTrades":142}, -{"id":341,"date":1394150400000,"IM":1745917,"MTM":17978722,"notional":16626972,"activeTrades":101}, -{"id":342,"date":1394236800000,"IM":1622982,"MTM":12744665,"notional":11580148,"activeTrades":111}, -{"id":343,"date":1394323200000,"IM":1827959,"MTM":13068388,"notional":17756339,"activeTrades":182}, -{"id":344,"date":1394409600000,"IM":1778457,"MTM":17890591,"notional":15314222,"activeTrades":138}, -{"id":345,"date":1394496000000,"IM":1767374,"MTM":16465078,"notional":15833310,"activeTrades":177}, -{"id":346,"date":1394582400000,"IM":1068702,"MTM":15031064,"notional":14558682,"activeTrades":195}, -{"id":347,"date":1394668800000,"IM":1243731,"MTM":15185498,"notional":13230825,"activeTrades":112}, -{"id":348,"date":1394755200000,"IM":1533761,"MTM":13010731,"notional":18629214,"activeTrades":165}, -{"id":349,"date":1394841600000,"IM":1644968,"MTM":16310334,"notional":15003259,"activeTrades":162}, -{"id":350,"date":1394928000000,"IM":1784038,"MTM":15890423,"notional":16648312,"activeTrades":196}, -{"id":351,"date":1395014400000,"IM":1036791,"MTM":15199854,"notional":10646828,"activeTrades":173}, -{"id":352,"date":1395100800000,"IM":1551201,"MTM":19345032,"notional":12026516,"activeTrades":156}, -{"id":353,"date":1395187200000,"IM":1676149,"MTM":19425787,"notional":16319087,"activeTrades":105}, -{"id":354,"date":1395273600000,"IM":1210128,"MTM":19642114,"notional":10856487,"activeTrades":169}, -{"id":355,"date":1395360000000,"IM":1153753,"MTM":19988164,"notional":15046106,"activeTrades":155}, -{"id":356,"date":1395446400000,"IM":1866012,"MTM":19863870,"notional":11832158,"activeTrades":134}, -{"id":357,"date":1395532800000,"IM":1417341,"MTM":19165470,"notional":15957198,"activeTrades":186}, -{"id":358,"date":1395619200000,"IM":1308876,"MTM":19349304,"notional":15454165,"activeTrades":163}, -{"id":359,"date":1395705600000,"IM":1734671,"MTM":13856618,"notional":10498699,"activeTrades":196}, -{"id":360,"date":1395792000000,"IM":1654092,"MTM":15977452,"notional":16517177,"activeTrades":113}, -{"id":361,"date":1395878400000,"IM":1651306,"MTM":19801213,"notional":16514408,"activeTrades":121}, -{"id":362,"date":1395964800000,"IM":1956303,"MTM":13280430,"notional":12432282,"activeTrades":147}, -{"id":363,"date":1396051200000,"IM":1463107,"MTM":17594474,"notional":12927338,"activeTrades":184}, -{"id":364,"date":1396137600000,"IM":1323994,"MTM":18748311,"notional":15046296,"activeTrades":121}, -{"id":365,"date":1396224000000,"IM":1875298,"MTM":17510464,"notional":10733292,"activeTrades":173}, -{"id":366,"date":1396310400000,"IM":1455184,"MTM":11529594,"notional":16112080,"activeTrades":143}, -{"id":367,"date":1396396800000,"IM":1695739,"MTM":17946389,"notional":15817665,"activeTrades":148}, -{"id":368,"date":1396483200000,"IM":1622024,"MTM":13535106,"notional":18613279,"activeTrades":170}, -{"id":369,"date":1396569600000,"IM":1613936,"MTM":13720353,"notional":17941087,"activeTrades":143}, -{"id":370,"date":1396656000000,"IM":1187097,"MTM":16839239,"notional":16135402,"activeTrades":120}, -{"id":371,"date":1396742400000,"IM":1725221,"MTM":19706956,"notional":14545366,"activeTrades":180}, -{"id":372,"date":1396828800000,"IM":1282062,"MTM":10936506,"notional":14566338,"activeTrades":135}, -{"id":373,"date":1396915200000,"IM":1227922,"MTM":17086054,"notional":10505308,"activeTrades":182}, -{"id":374,"date":1397001600000,"IM":1164120,"MTM":14053124,"notional":19089615,"activeTrades":192}, -{"id":375,"date":1397088000000,"IM":1532825,"MTM":19837729,"notional":19891491,"activeTrades":191}, -{"id":376,"date":1397174400000,"IM":1032500,"MTM":10402592,"notional":15411175,"activeTrades":129}, -{"id":377,"date":1397260800000,"IM":1436416,"MTM":14695264,"notional":18694247,"activeTrades":163}, -{"id":378,"date":1397347200000,"IM":1726957,"MTM":12754225,"notional":18109622,"activeTrades":141}, -{"id":379,"date":1397433600000,"IM":1585563,"MTM":11735672,"notional":10081960,"activeTrades":111}, -{"id":380,"date":1397520000000,"IM":1521280,"MTM":14365810,"notional":15948454,"activeTrades":147}, -{"id":381,"date":1397606400000,"IM":1318209,"MTM":16852460,"notional":16558332,"activeTrades":132}, -{"id":382,"date":1397692800000,"IM":1080691,"MTM":14627198,"notional":19282166,"activeTrades":110}, -{"id":383,"date":1397779200000,"IM":1441304,"MTM":14821426,"notional":15720993,"activeTrades":142}, -{"id":384,"date":1397865600000,"IM":1109453,"MTM":11088145,"notional":13477254,"activeTrades":151}, -{"id":385,"date":1397952000000,"IM":1959583,"MTM":17799495,"notional":14327744,"activeTrades":123}, -{"id":386,"date":1398038400000,"IM":1630359,"MTM":18479471,"notional":13622323,"activeTrades":119}, -{"id":387,"date":1398124800000,"IM":1039646,"MTM":16890794,"notional":11701992,"activeTrades":115}, -{"id":388,"date":1398211200000,"IM":1802034,"MTM":10626649,"notional":12643340,"activeTrades":164}, -{"id":389,"date":1398297600000,"IM":1133655,"MTM":11745861,"notional":12800557,"activeTrades":103}, -{"id":390,"date":1398384000000,"IM":1627172,"MTM":14266219,"notional":10135142,"activeTrades":177}, -{"id":391,"date":1398470400000,"IM":1457897,"MTM":10851838,"notional":10437992,"activeTrades":118}, -{"id":392,"date":1398556800000,"IM":1486978,"MTM":10011440,"notional":18151343,"activeTrades":100}, -{"id":393,"date":1398643200000,"IM":1787867,"MTM":13535263,"notional":13451784,"activeTrades":158}, -{"id":394,"date":1398729600000,"IM":1719228,"MTM":11055182,"notional":17614271,"activeTrades":181}, -{"id":395,"date":1398816000000,"IM":1279612,"MTM":15465335,"notional":19159084,"activeTrades":176}, -{"id":396,"date":1398902400000,"IM":1505917,"MTM":17380155,"notional":16485017,"activeTrades":170}, -{"id":397,"date":1398988800000,"IM":1078634,"MTM":18629407,"notional":19631330,"activeTrades":124}, -{"id":398,"date":1399075200000,"IM":1486593,"MTM":11428163,"notional":18540003,"activeTrades":187}, -{"id":399,"date":1399161600000,"IM":1533158,"MTM":10181354,"notional":15527848,"activeTrades":159}, -{"id":400,"date":1399248000000,"IM":1711723,"MTM":12862652,"notional":19457269,"activeTrades":181}, -{"id":401,"date":1399334400000,"IM":1818187,"MTM":19165709,"notional":17350948,"activeTrades":159}, -{"id":402,"date":1399420800000,"IM":1894616,"MTM":15135985,"notional":16075632,"activeTrades":129}, -{"id":403,"date":1399507200000,"IM":1691378,"MTM":15492646,"notional":16631145,"activeTrades":105}, -{"id":404,"date":1399593600000,"IM":1953280,"MTM":14915323,"notional":10945036,"activeTrades":114}, -{"id":405,"date":1399680000000,"IM":1241727,"MTM":12977477,"notional":12954198,"activeTrades":102}, -{"id":406,"date":1399766400000,"IM":1724572,"MTM":18735614,"notional":11219087,"activeTrades":125}, -{"id":407,"date":1399852800000,"IM":1856831,"MTM":15285547,"notional":17583098,"activeTrades":107}, -{"id":408,"date":1399939200000,"IM":1677747,"MTM":14302669,"notional":13608564,"activeTrades":140}, -{"id":409,"date":1400025600000,"IM":1623982,"MTM":17991175,"notional":17824854,"activeTrades":110}, -{"id":410,"date":1400112000000,"IM":1737817,"MTM":15155409,"notional":14317319,"activeTrades":131}, -{"id":411,"date":1400198400000,"IM":1226936,"MTM":14108290,"notional":12647875,"activeTrades":139}, -{"id":412,"date":1400284800000,"IM":1914114,"MTM":14617229,"notional":14122024,"activeTrades":165}, -{"id":413,"date":1400371200000,"IM":1323414,"MTM":10570495,"notional":15480624,"activeTrades":167}, -{"id":414,"date":1400457600000,"IM":1951564,"MTM":17647787,"notional":18206064,"activeTrades":159}, -{"id":415,"date":1400544000000,"IM":1661382,"MTM":17718739,"notional":10211117,"activeTrades":121}, -{"id":416,"date":1400630400000,"IM":1949620,"MTM":19002725,"notional":10241132,"activeTrades":151}, -{"id":417,"date":1400716800000,"IM":1731511,"MTM":19616640,"notional":18404142,"activeTrades":102}, -{"id":418,"date":1400803200000,"IM":1207922,"MTM":13807122,"notional":16498582,"activeTrades":134}, -{"id":419,"date":1400889600000,"IM":1466782,"MTM":16622009,"notional":14858376,"activeTrades":125}, -{"id":420,"date":1400976000000,"IM":1667477,"MTM":16394615,"notional":13020328,"activeTrades":146}, -{"id":421,"date":1401062400000,"IM":1177958,"MTM":15454310,"notional":19860827,"activeTrades":125}, -{"id":422,"date":1401148800000,"IM":1571072,"MTM":10556637,"notional":10769223,"activeTrades":100}, -{"id":423,"date":1401235200000,"IM":1377863,"MTM":10248764,"notional":11196497,"activeTrades":165}, -{"id":424,"date":1401321600000,"IM":1760261,"MTM":10193074,"notional":10685546,"activeTrades":121}, -{"id":425,"date":1401408000000,"IM":1983578,"MTM":17650896,"notional":10506053,"activeTrades":191}, -{"id":426,"date":1401494400000,"IM":1754262,"MTM":10907262,"notional":18825192,"activeTrades":176}, -{"id":427,"date":1401580800000,"IM":1300488,"MTM":18101769,"notional":19538498,"activeTrades":182}, -{"id":428,"date":1401667200000,"IM":1982226,"MTM":13189455,"notional":15132594,"activeTrades":112}, -{"id":429,"date":1401753600000,"IM":1253400,"MTM":17970712,"notional":14759115,"activeTrades":176}, -{"id":430,"date":1401840000000,"IM":1651320,"MTM":11805335,"notional":12203561,"activeTrades":149}, -{"id":431,"date":1401926400000,"IM":1532656,"MTM":13079267,"notional":12341573,"activeTrades":149}, -{"id":432,"date":1402012800000,"IM":1122942,"MTM":10658548,"notional":15531714,"activeTrades":135}, -{"id":433,"date":1402099200000,"IM":1169330,"MTM":10166044,"notional":17675472,"activeTrades":144}, -{"id":434,"date":1402185600000,"IM":1332408,"MTM":13300234,"notional":11993918,"activeTrades":166}, -{"id":435,"date":1402272000000,"IM":1574598,"MTM":16891979,"notional":19366353,"activeTrades":167}, -{"id":436,"date":1402358400000,"IM":1671188,"MTM":17960339,"notional":19675944,"activeTrades":181}, -{"id":437,"date":1402444800000,"IM":1358238,"MTM":16139458,"notional":13041181,"activeTrades":182}, -{"id":438,"date":1402531200000,"IM":1533337,"MTM":14535421,"notional":16454503,"activeTrades":180}, -{"id":439,"date":1402617600000,"IM":1933261,"MTM":17507189,"notional":13479082,"activeTrades":153}, -{"id":440,"date":1402704000000,"IM":1156377,"MTM":18820027,"notional":10407722,"activeTrades":167}, -{"id":441,"date":1402790400000,"IM":1224658,"MTM":13737797,"notional":19456855,"activeTrades":137}, -{"id":442,"date":1402876800000,"IM":1283431,"MTM":12289956,"notional":16835995,"activeTrades":110}, -{"id":443,"date":1402963200000,"IM":1984829,"MTM":14303902,"notional":16738691,"activeTrades":164}, -{"id":444,"date":1403049600000,"IM":1003627,"MTM":15100996,"notional":15586736,"activeTrades":104}, -{"id":445,"date":1403136000000,"IM":1203031,"MTM":17430128,"notional":13521275,"activeTrades":183}, -{"id":446,"date":1403222400000,"IM":1720659,"MTM":14864040,"notional":11399651,"activeTrades":188}, -{"id":447,"date":1403308800000,"IM":1563030,"MTM":12529702,"notional":15123278,"activeTrades":146}, -{"id":448,"date":1403395200000,"IM":1841114,"MTM":14002505,"notional":18311249,"activeTrades":185}, -{"id":449,"date":1403481600000,"IM":1530834,"MTM":11037328,"notional":16331750,"activeTrades":119}, -{"id":450,"date":1403568000000,"IM":1713031,"MTM":10277437,"notional":19298629,"activeTrades":131}, -{"id":451,"date":1403654400000,"IM":1634945,"MTM":11119806,"notional":18204520,"activeTrades":162}, -{"id":452,"date":1403740800000,"IM":1416992,"MTM":11210067,"notional":16491632,"activeTrades":164}, -{"id":453,"date":1403827200000,"IM":1956390,"MTM":14183461,"notional":10962139,"activeTrades":130}, -{"id":454,"date":1403913600000,"IM":1373312,"MTM":19722224,"notional":19660333,"activeTrades":189}, -{"id":455,"date":1404000000000,"IM":1046777,"MTM":18488547,"notional":17905131,"activeTrades":183}, -{"id":456,"date":1404086400000,"IM":1143442,"MTM":17914107,"notional":10041135,"activeTrades":110}, -{"id":457,"date":1404172800000,"IM":1072864,"MTM":18773425,"notional":13228208,"activeTrades":112}, -{"id":458,"date":1404259200000,"IM":1876906,"MTM":13733369,"notional":17958187,"activeTrades":159}, -{"id":459,"date":1404345600000,"IM":1600986,"MTM":17486154,"notional":14717841,"activeTrades":101}, -{"id":460,"date":1404432000000,"IM":1029695,"MTM":14720714,"notional":16098185,"activeTrades":196}, -{"id":461,"date":1404518400000,"IM":1420469,"MTM":10810382,"notional":14262659,"activeTrades":191}, -{"id":462,"date":1404604800000,"IM":1388441,"MTM":12612609,"notional":19079197,"activeTrades":116}, -{"id":463,"date":1404691200000,"IM":1827396,"MTM":15239787,"notional":13151125,"activeTrades":173}, -{"id":464,"date":1404777600000,"IM":1950935,"MTM":13049603,"notional":17860863,"activeTrades":131}, -{"id":465,"date":1404864000000,"IM":1219162,"MTM":17357491,"notional":12824380,"activeTrades":174}, -{"id":466,"date":1404950400000,"IM":1954611,"MTM":15093619,"notional":13366087,"activeTrades":193}, -{"id":467,"date":1405036800000,"IM":1938167,"MTM":14196434,"notional":16548213,"activeTrades":123}, -{"id":468,"date":1405123200000,"IM":1473519,"MTM":14967119,"notional":19758448,"activeTrades":154}, -{"id":469,"date":1405209600000,"IM":1610146,"MTM":12846761,"notional":13922377,"activeTrades":182}, -{"id":470,"date":1405296000000,"IM":1113483,"MTM":15203369,"notional":12863527,"activeTrades":124}, -{"id":471,"date":1405382400000,"IM":1729222,"MTM":10464941,"notional":16465065,"activeTrades":184}, -{"id":472,"date":1405468800000,"IM":1609900,"MTM":11786147,"notional":18075654,"activeTrades":187}, -{"id":473,"date":1405555200000,"IM":1101634,"MTM":11427394,"notional":17184304,"activeTrades":134}, -{"id":474,"date":1405641600000,"IM":1437118,"MTM":15426284,"notional":12575078,"activeTrades":161}, -{"id":475,"date":1405728000000,"IM":1758052,"MTM":11331944,"notional":12832523,"activeTrades":120}, -{"id":476,"date":1405814400000,"IM":1749547,"MTM":19540333,"notional":19106174,"activeTrades":142}, -{"id":477,"date":1405900800000,"IM":1199695,"MTM":14516174,"notional":19296641,"activeTrades":187}, -{"id":478,"date":1405987200000,"IM":1870995,"MTM":14906774,"notional":10747386,"activeTrades":153}, -{"id":479,"date":1406073600000,"IM":1019419,"MTM":14703722,"notional":10381278,"activeTrades":111}, -{"id":480,"date":1406160000000,"IM":1284669,"MTM":19266276,"notional":14346156,"activeTrades":158}, -{"id":481,"date":1406246400000,"IM":1781221,"MTM":11888454,"notional":15344887,"activeTrades":125}, -{"id":482,"date":1406332800000,"IM":1941369,"MTM":11932382,"notional":18964987,"activeTrades":111}, -{"id":483,"date":1406419200000,"IM":1960600,"MTM":15156308,"notional":17311290,"activeTrades":200}, -{"id":484,"date":1406505600000,"IM":1260712,"MTM":12480387,"notional":19520822,"activeTrades":185}, -{"id":485,"date":1406592000000,"IM":1676321,"MTM":16743088,"notional":17013483,"activeTrades":104}, -{"id":486,"date":1406678400000,"IM":1517165,"MTM":17722259,"notional":14946554,"activeTrades":118}, -{"id":487,"date":1406764800000,"IM":1993491,"MTM":15602848,"notional":19784037,"activeTrades":117}, -{"id":488,"date":1406851200000,"IM":1689359,"MTM":15552199,"notional":14051102,"activeTrades":149}, -{"id":489,"date":1406937600000,"IM":1857638,"MTM":18565090,"notional":13107400,"activeTrades":107}, -{"id":490,"date":1407024000000,"IM":1464242,"MTM":13316804,"notional":14818212,"activeTrades":108}, -{"id":491,"date":1407110400000,"IM":1894270,"MTM":12696715,"notional":14910525,"activeTrades":113}, -{"id":492,"date":1407196800000,"IM":1551210,"MTM":15353891,"notional":16782951,"activeTrades":195}, -{"id":493,"date":1407283200000,"IM":1405881,"MTM":10810032,"notional":13554738,"activeTrades":143}, -{"id":494,"date":1407369600000,"IM":1528884,"MTM":15099633,"notional":15431243,"activeTrades":103}, -{"id":495,"date":1407456000000,"IM":1010993,"MTM":13542050,"notional":17556232,"activeTrades":132}, -{"id":496,"date":1407542400000,"IM":1463474,"MTM":16920542,"notional":19058312,"activeTrades":121}, -{"id":497,"date":1407628800000,"IM":1463596,"MTM":13563413,"notional":13142173,"activeTrades":176}, -{"id":498,"date":1407715200000,"IM":1097404,"MTM":11796662,"notional":12665166,"activeTrades":188}, -{"id":499,"date":1407801600000,"IM":1901063,"MTM":13711826,"notional":14877618,"activeTrades":183}, -{"id":500,"date":1407888000000,"IM":1407802,"MTM":19949332,"notional":11537756,"activeTrades":160}, -{"id":501,"date":1407974400000,"IM":1477585,"MTM":11859723,"notional":18104879,"activeTrades":107}, -{"id":502,"date":1408060800000,"IM":1826370,"MTM":19183247,"notional":13528584,"activeTrades":158}, -{"id":503,"date":1408147200000,"IM":1486407,"MTM":17061548,"notional":12680433,"activeTrades":109}, -{"id":504,"date":1408233600000,"IM":1155150,"MTM":13212635,"notional":19917792,"activeTrades":166}, -{"id":505,"date":1408320000000,"IM":1893327,"MTM":19722926,"notional":19051814,"activeTrades":174}, -{"id":506,"date":1408406400000,"IM":1955117,"MTM":17479663,"notional":14362938,"activeTrades":194}, -{"id":507,"date":1408492800000,"IM":1235633,"MTM":15343782,"notional":18267247,"activeTrades":138}, -{"id":508,"date":1408579200000,"IM":1185755,"MTM":10004028,"notional":14054841,"activeTrades":159}, -{"id":509,"date":1408665600000,"IM":1741555,"MTM":17660068,"notional":18959152,"activeTrades":192}, -{"id":510,"date":1408752000000,"IM":1331252,"MTM":12173221,"notional":16816741,"activeTrades":114}, -{"id":511,"date":1408838400000,"IM":1398151,"MTM":13129413,"notional":15182398,"activeTrades":123}, -{"id":512,"date":1408924800000,"IM":1061485,"MTM":14143629,"notional":18426628,"activeTrades":107}, -{"id":513,"date":1409011200000,"IM":1072369,"MTM":13294887,"notional":18256965,"activeTrades":101}, -{"id":514,"date":1409097600000,"IM":1684902,"MTM":19256173,"notional":13472648,"activeTrades":127}, -{"id":515,"date":1409184000000,"IM":1617225,"MTM":15136756,"notional":10224719,"activeTrades":110}, -{"id":516,"date":1409270400000,"IM":1698471,"MTM":16113199,"notional":12032057,"activeTrades":134}, -{"id":517,"date":1409356800000,"IM":1024071,"MTM":11934247,"notional":11937891,"activeTrades":177}, -{"id":518,"date":1409443200000,"IM":1021660,"MTM":18877631,"notional":17219181,"activeTrades":169}, -{"id":519,"date":1409529600000,"IM":1255868,"MTM":19879775,"notional":11291339,"activeTrades":131}, -{"id":520,"date":1409616000000,"IM":1956809,"MTM":16387499,"notional":15137868,"activeTrades":153}, -{"id":521,"date":1409702400000,"IM":1994758,"MTM":17854113,"notional":19706626,"activeTrades":171}, -{"id":522,"date":1409788800000,"IM":1745540,"MTM":11270350,"notional":10928937,"activeTrades":193}, -{"id":523,"date":1409875200000,"IM":1586167,"MTM":14095302,"notional":16130593,"activeTrades":191}, -{"id":524,"date":1409961600000,"IM":1497159,"MTM":15076984,"notional":13473244,"activeTrades":111}, -{"id":525,"date":1410048000000,"IM":1937636,"MTM":18925974,"notional":10345073,"activeTrades":119}, -{"id":526,"date":1410134400000,"IM":1444985,"MTM":14174392,"notional":11603703,"activeTrades":143}, -{"id":527,"date":1410220800000,"IM":1879071,"MTM":19903486,"notional":13788260,"activeTrades":152}, -{"id":528,"date":1410307200000,"IM":1778184,"MTM":14094664,"notional":14356354,"activeTrades":137}, -{"id":529,"date":1410393600000,"IM":1790222,"MTM":15340883,"notional":10573908,"activeTrades":119}, -{"id":530,"date":1410480000000,"IM":1029779,"MTM":16698947,"notional":11058920,"activeTrades":111}, -{"id":531,"date":1410566400000,"IM":1975356,"MTM":16310713,"notional":17693823,"activeTrades":179}, -{"id":532,"date":1410652800000,"IM":1791538,"MTM":13634258,"notional":11101920,"activeTrades":155}, -{"id":533,"date":1410739200000,"IM":1208569,"MTM":14189696,"notional":19201317,"activeTrades":186}, -{"id":534,"date":1410825600000,"IM":1154137,"MTM":14999994,"notional":18523076,"activeTrades":125}, -{"id":535,"date":1410912000000,"IM":1879443,"MTM":17728381,"notional":14225866,"activeTrades":129}, -{"id":536,"date":1410998400000,"IM":1080418,"MTM":15002649,"notional":11553230,"activeTrades":110}, -{"id":537,"date":1411084800000,"IM":1161618,"MTM":13073511,"notional":17176769,"activeTrades":112}, -{"id":538,"date":1411171200000,"IM":1663853,"MTM":14790133,"notional":11574551,"activeTrades":153}, -{"id":539,"date":1411257600000,"IM":1006177,"MTM":14830965,"notional":14806339,"activeTrades":150}, -{"id":540,"date":1411344000000,"IM":1069183,"MTM":19769610,"notional":18122559,"activeTrades":166}, -{"id":541,"date":1411430400000,"IM":1773815,"MTM":15097879,"notional":11951807,"activeTrades":176}, -{"id":542,"date":1411516800000,"IM":1549996,"MTM":10525175,"notional":14653949,"activeTrades":160}, -{"id":543,"date":1411603200000,"IM":1172496,"MTM":18222814,"notional":14364197,"activeTrades":173}, -{"id":544,"date":1411689600000,"IM":1630474,"MTM":14202416,"notional":13971502,"activeTrades":132}, -{"id":545,"date":1411776000000,"IM":1126270,"MTM":19775723,"notional":18632838,"activeTrades":107}, -{"id":546,"date":1411862400000,"IM":1847637,"MTM":11158001,"notional":17634822,"activeTrades":130}, -{"id":547,"date":1411948800000,"IM":1244425,"MTM":18249823,"notional":15446706,"activeTrades":163}, -{"id":548,"date":1412035200000,"IM":1313719,"MTM":11387495,"notional":14629588,"activeTrades":147}, -{"id":549,"date":1412121600000,"IM":1252323,"MTM":16297955,"notional":12661827,"activeTrades":115}, -{"id":550,"date":1412208000000,"IM":1636795,"MTM":12066431,"notional":18884774,"activeTrades":119}, -{"id":551,"date":1412294400000,"IM":1393975,"MTM":16688201,"notional":11010632,"activeTrades":176}, -{"id":552,"date":1412380800000,"IM":1431582,"MTM":15516037,"notional":12961349,"activeTrades":130}, -{"id":553,"date":1412467200000,"IM":1198486,"MTM":12840318,"notional":17203721,"activeTrades":108}, -{"id":554,"date":1412553600000,"IM":1967620,"MTM":18636031,"notional":12317670,"activeTrades":168}, -{"id":555,"date":1412640000000,"IM":1174359,"MTM":17328361,"notional":13553572,"activeTrades":185}, -{"id":556,"date":1412726400000,"IM":1308737,"MTM":12397497,"notional":10377440,"activeTrades":152}, -{"id":557,"date":1412812800000,"IM":1149765,"MTM":13340099,"notional":15679002,"activeTrades":192}, -{"id":558,"date":1412899200000,"IM":1570781,"MTM":12233447,"notional":10645549,"activeTrades":163}, -{"id":559,"date":1412985600000,"IM":1809891,"MTM":18272527,"notional":19931599,"activeTrades":181}, -{"id":560,"date":1413072000000,"IM":1744414,"MTM":14305804,"notional":19264509,"activeTrades":140}, -{"id":561,"date":1413158400000,"IM":1594615,"MTM":12077567,"notional":15836623,"activeTrades":129}, -{"id":562,"date":1413244800000,"IM":1189888,"MTM":19556512,"notional":19772555,"activeTrades":104}, -{"id":563,"date":1413331200000,"IM":1638401,"MTM":19925073,"notional":18822151,"activeTrades":183}, -{"id":564,"date":1413417600000,"IM":1205846,"MTM":11677822,"notional":14796643,"activeTrades":117}, -{"id":565,"date":1413504000000,"IM":1744546,"MTM":19062341,"notional":17320765,"activeTrades":111}, -{"id":566,"date":1413590400000,"IM":1548795,"MTM":15144868,"notional":19740749,"activeTrades":199}, -{"id":567,"date":1413676800000,"IM":1591436,"MTM":16004775,"notional":10502939,"activeTrades":144}, -{"id":568,"date":1413763200000,"IM":1523265,"MTM":18881747,"notional":17031031,"activeTrades":173}, -{"id":569,"date":1413849600000,"IM":1192038,"MTM":13633348,"notional":19987740,"activeTrades":114}, -{"id":570,"date":1413936000000,"IM":1232547,"MTM":12183734,"notional":15611627,"activeTrades":154}, -{"id":571,"date":1414022400000,"IM":1521808,"MTM":16411043,"notional":14488940,"activeTrades":115}, -{"id":572,"date":1414108800000,"IM":1368111,"MTM":17370719,"notional":16966989,"activeTrades":192}, -{"id":573,"date":1414195200000,"IM":1117190,"MTM":11610418,"notional":12235621,"activeTrades":168}, -{"id":574,"date":1414281600000,"IM":1528473,"MTM":10228420,"notional":16939924,"activeTrades":178}, -{"id":575,"date":1414368000000,"IM":1937691,"MTM":16822815,"notional":18917063,"activeTrades":178}, -{"id":576,"date":1414454400000,"IM":1345990,"MTM":18597672,"notional":11915067,"activeTrades":200}, -{"id":577,"date":1414540800000,"IM":1989146,"MTM":12799792,"notional":12249248,"activeTrades":185}, -{"id":578,"date":1414627200000,"IM":1771200,"MTM":10003411,"notional":11769601,"activeTrades":151}, -{"id":579,"date":1414713600000,"IM":1570653,"MTM":18332874,"notional":18093168,"activeTrades":107}, -{"id":580,"date":1414800000000,"IM":1821864,"MTM":15067687,"notional":19702931,"activeTrades":167}, -{"id":581,"date":1414886400000,"IM":1293330,"MTM":11289101,"notional":15394750,"activeTrades":179}, -{"id":582,"date":1414972800000,"IM":1146731,"MTM":17330668,"notional":13707649,"activeTrades":164}, -{"id":583,"date":1415059200000,"IM":1156946,"MTM":16684268,"notional":18515455,"activeTrades":187}, -{"id":584,"date":1415145600000,"IM":1419721,"MTM":11449218,"notional":13269748,"activeTrades":125}, -{"id":585,"date":1415232000000,"IM":1952379,"MTM":14876739,"notional":11768054,"activeTrades":127}, -{"id":586,"date":1415318400000,"IM":1094152,"MTM":14010859,"notional":10709470,"activeTrades":116}, -{"id":587,"date":1415404800000,"IM":1799507,"MTM":13546317,"notional":17337580,"activeTrades":129}, -{"id":588,"date":1415491200000,"IM":1089948,"MTM":14089581,"notional":17133678,"activeTrades":106}, -{"id":589,"date":1415577600000,"IM":1789405,"MTM":18103422,"notional":13931604,"activeTrades":112}, -{"id":590,"date":1415664000000,"IM":1472563,"MTM":10761437,"notional":10562296,"activeTrades":177}, -{"id":591,"date":1415750400000,"IM":1558023,"MTM":19116894,"notional":10423625,"activeTrades":187}, -{"id":592,"date":1415836800000,"IM":1406497,"MTM":16002235,"notional":18089218,"activeTrades":157}, -{"id":593,"date":1415923200000,"IM":1478873,"MTM":19174478,"notional":14871198,"activeTrades":126}, -{"id":594,"date":1416009600000,"IM":1403346,"MTM":19306271,"notional":18994082,"activeTrades":193}, -{"id":595,"date":1416096000000,"IM":1162029,"MTM":16326377,"notional":18456375,"activeTrades":110}, -{"id":596,"date":1416182400000,"IM":1332284,"MTM":10254947,"notional":10815106,"activeTrades":115}, -{"id":597,"date":1416268800000,"IM":1302500,"MTM":16989962,"notional":16991218,"activeTrades":124}, -{"id":598,"date":1416355200000,"IM":1686093,"MTM":16230276,"notional":11408662,"activeTrades":154}, -{"id":599,"date":1416441600000,"IM":1830697,"MTM":12027666,"notional":18928766,"activeTrades":188}, -{"id":600,"date":1416528000000,"IM":1473349,"MTM":12897629,"notional":14577859,"activeTrades":137}, -{"id":601,"date":1416614400000,"IM":1817475,"MTM":10756696,"notional":16862263,"activeTrades":126}, -{"id":602,"date":1416700800000,"IM":1537992,"MTM":11266460,"notional":12633302,"activeTrades":197}, -{"id":603,"date":1416787200000,"IM":1938191,"MTM":11627171,"notional":11526536,"activeTrades":129}, -{"id":604,"date":1416873600000,"IM":1027055,"MTM":19601716,"notional":10229221,"activeTrades":104}, -{"id":605,"date":1416960000000,"IM":1905392,"MTM":10788495,"notional":11631234,"activeTrades":165}, -{"id":606,"date":1417046400000,"IM":1903616,"MTM":17604102,"notional":12620139,"activeTrades":110}, -{"id":607,"date":1417132800000,"IM":1833919,"MTM":14931997,"notional":19646986,"activeTrades":147}, -{"id":608,"date":1417219200000,"IM":1961678,"MTM":12545559,"notional":11456863,"activeTrades":113}, -{"id":609,"date":1417305600000,"IM":1993988,"MTM":10769602,"notional":15122174,"activeTrades":181}, -{"id":610,"date":1417392000000,"IM":1882113,"MTM":18595560,"notional":19822028,"activeTrades":180}, -{"id":611,"date":1417478400000,"IM":1630876,"MTM":19778520,"notional":11723859,"activeTrades":162}, -{"id":612,"date":1417564800000,"IM":1016851,"MTM":12769834,"notional":15906332,"activeTrades":167}, -{"id":613,"date":1417651200000,"IM":1347856,"MTM":15748122,"notional":15683929,"activeTrades":126}, -{"id":614,"date":1417737600000,"IM":1709142,"MTM":16731532,"notional":18596026,"activeTrades":103}, -{"id":615,"date":1417824000000,"IM":1333628,"MTM":12390625,"notional":18558479,"activeTrades":123}, -{"id":616,"date":1417910400000,"IM":1200655,"MTM":10576819,"notional":19750254,"activeTrades":130}, -{"id":617,"date":1417996800000,"IM":1055374,"MTM":16237835,"notional":18104861,"activeTrades":187}, -{"id":618,"date":1418083200000,"IM":1061505,"MTM":14947423,"notional":12447889,"activeTrades":138}, -{"id":619,"date":1418169600000,"IM":1983924,"MTM":14085497,"notional":10172491,"activeTrades":183}, -{"id":620,"date":1418256000000,"IM":1271091,"MTM":16209874,"notional":12630051,"activeTrades":175}, -{"id":621,"date":1418342400000,"IM":1062043,"MTM":12771157,"notional":16993099,"activeTrades":139}, -{"id":622,"date":1418428800000,"IM":1569236,"MTM":10988596,"notional":17955993,"activeTrades":140}, -{"id":623,"date":1418515200000,"IM":1362752,"MTM":18439294,"notional":13661400,"activeTrades":194}, -{"id":624,"date":1418601600000,"IM":1164041,"MTM":15466802,"notional":15458573,"activeTrades":173}, -{"id":625,"date":1418688000000,"IM":1364130,"MTM":13866116,"notional":16390073,"activeTrades":127}, -{"id":626,"date":1418774400000,"IM":1034970,"MTM":10303011,"notional":17517474,"activeTrades":122}, -{"id":627,"date":1418860800000,"IM":1967191,"MTM":15964789,"notional":11069526,"activeTrades":115}, -{"id":628,"date":1418947200000,"IM":1733848,"MTM":15620814,"notional":15901975,"activeTrades":162}, -{"id":629,"date":1419033600000,"IM":1097063,"MTM":17804613,"notional":17065058,"activeTrades":116}, -{"id":630,"date":1419120000000,"IM":1844349,"MTM":19078213,"notional":11289796,"activeTrades":125}, -{"id":631,"date":1419206400000,"IM":1723101,"MTM":14723654,"notional":15754459,"activeTrades":120}, -{"id":632,"date":1419292800000,"IM":1840483,"MTM":15020106,"notional":18877733,"activeTrades":184}, -{"id":633,"date":1419379200000,"IM":1449234,"MTM":16255827,"notional":10192653,"activeTrades":144}, -{"id":634,"date":1419465600000,"IM":1784124,"MTM":18426201,"notional":19327277,"activeTrades":136}, -{"id":635,"date":1419552000000,"IM":1007837,"MTM":15952096,"notional":19257287,"activeTrades":123}, -{"id":636,"date":1419638400000,"IM":1630219,"MTM":12299668,"notional":11687834,"activeTrades":110}, -{"id":637,"date":1419724800000,"IM":1911956,"MTM":17599685,"notional":13236144,"activeTrades":128}, -{"id":638,"date":1419811200000,"IM":1673326,"MTM":19281037,"notional":13792176,"activeTrades":146}, -{"id":639,"date":1419897600000,"IM":1448203,"MTM":12880651,"notional":19651691,"activeTrades":134}, -{"id":640,"date":1419984000000,"IM":1357518,"MTM":18559254,"notional":17458463,"activeTrades":103}, -{"id":641,"date":1420070400000,"IM":1680321,"MTM":11717760,"notional":13299894,"activeTrades":109}, -{"id":642,"date":1420156800000,"IM":1823409,"MTM":16987767,"notional":15934938,"activeTrades":124}, -{"id":643,"date":1420243200000,"IM":1486906,"MTM":12313703,"notional":13006812,"activeTrades":115}, -{"id":644,"date":1420329600000,"IM":1546654,"MTM":11458495,"notional":11442549,"activeTrades":143}, -{"id":645,"date":1420416000000,"IM":1923446,"MTM":14054969,"notional":10122193,"activeTrades":200}, -{"id":646,"date":1420502400000,"IM":1571994,"MTM":11092471,"notional":11082682,"activeTrades":144}, -{"id":647,"date":1420588800000,"IM":1259676,"MTM":17850266,"notional":18267824,"activeTrades":186}, -{"id":648,"date":1420675200000,"IM":1325520,"MTM":15207708,"notional":10221060,"activeTrades":146}, -{"id":649,"date":1420761600000,"IM":1915568,"MTM":19032869,"notional":16621627,"activeTrades":122}, -{"id":650,"date":1420848000000,"IM":1166450,"MTM":18476545,"notional":18296428,"activeTrades":109}, -{"id":651,"date":1420934400000,"IM":1976817,"MTM":14103719,"notional":18762775,"activeTrades":173}, -{"id":652,"date":1421020800000,"IM":1407460,"MTM":18409065,"notional":11935530,"activeTrades":157}, -{"id":653,"date":1421107200000,"IM":1025822,"MTM":11411827,"notional":19073816,"activeTrades":166}, -{"id":654,"date":1421193600000,"IM":1227643,"MTM":11603949,"notional":12656045,"activeTrades":108}, -{"id":655,"date":1421280000000,"IM":1598751,"MTM":11517692,"notional":11455548,"activeTrades":198}, -{"id":656,"date":1421366400000,"IM":1723797,"MTM":10442948,"notional":10287539,"activeTrades":183}, -{"id":657,"date":1421452800000,"IM":1305462,"MTM":13046822,"notional":16288486,"activeTrades":113}, -{"id":658,"date":1421539200000,"IM":1227384,"MTM":13905157,"notional":11676723,"activeTrades":132}, -{"id":659,"date":1421625600000,"IM":1438924,"MTM":15751551,"notional":14723479,"activeTrades":154}, -{"id":660,"date":1421712000000,"IM":1897290,"MTM":15560001,"notional":12289376,"activeTrades":143}, -{"id":661,"date":1421798400000,"IM":1995375,"MTM":18299555,"notional":13213723,"activeTrades":159}, -{"id":662,"date":1421884800000,"IM":1607799,"MTM":13492763,"notional":19308245,"activeTrades":102}, -{"id":663,"date":1421971200000,"IM":1259373,"MTM":19605321,"notional":15224225,"activeTrades":144}, -{"id":664,"date":1422057600000,"IM":1392293,"MTM":10217410,"notional":10931477,"activeTrades":197}, -{"id":665,"date":1422144000000,"IM":1197187,"MTM":11004784,"notional":11885227,"activeTrades":174}, -{"id":666,"date":1422230400000,"IM":1265712,"MTM":19385771,"notional":16188598,"activeTrades":139}, -{"id":667,"date":1422316800000,"IM":1176151,"MTM":19119555,"notional":10169378,"activeTrades":169}, -{"id":668,"date":1422403200000,"IM":1271470,"MTM":18275614,"notional":10300808,"activeTrades":148}, -{"id":669,"date":1422489600000,"IM":1939001,"MTM":16590067,"notional":14532937,"activeTrades":171}, -{"id":670,"date":1422576000000,"IM":1608956,"MTM":14283840,"notional":14149221,"activeTrades":178}, -{"id":671,"date":1422662400000,"IM":1507074,"MTM":10992791,"notional":17415848,"activeTrades":124}, -{"id":672,"date":1422748800000,"IM":1997393,"MTM":14973425,"notional":12360919,"activeTrades":196}, -{"id":673,"date":1422835200000,"IM":1855378,"MTM":17917279,"notional":18846356,"activeTrades":164}, -{"id":674,"date":1422921600000,"IM":1839331,"MTM":17158899,"notional":12671518,"activeTrades":130}, -{"id":675,"date":1423008000000,"IM":1129626,"MTM":10269430,"notional":14238219,"activeTrades":100}, -{"id":676,"date":1423094400000,"IM":1798522,"MTM":17846115,"notional":18806898,"activeTrades":156}, -{"id":677,"date":1423180800000,"IM":1654995,"MTM":18448973,"notional":13840761,"activeTrades":159}, -{"id":678,"date":1423267200000,"IM":1196602,"MTM":14124199,"notional":14844992,"activeTrades":153}, -{"id":679,"date":1423353600000,"IM":1367741,"MTM":11971958,"notional":13071947,"activeTrades":116}, -{"id":680,"date":1423440000000,"IM":1424036,"MTM":15710991,"notional":18730087,"activeTrades":171}, -{"id":681,"date":1423526400000,"IM":1951714,"MTM":17833050,"notional":17387359,"activeTrades":176}, -{"id":682,"date":1423612800000,"IM":1983062,"MTM":11136259,"notional":19058676,"activeTrades":197}, -{"id":683,"date":1423699200000,"IM":1566446,"MTM":16413537,"notional":15170543,"activeTrades":122}, -{"id":684,"date":1423785600000,"IM":1508767,"MTM":13109641,"notional":14802878,"activeTrades":200}, -{"id":685,"date":1423872000000,"IM":1351183,"MTM":15725923,"notional":15794110,"activeTrades":192}, -{"id":686,"date":1423958400000,"IM":1384655,"MTM":15823367,"notional":17194059,"activeTrades":130}, -{"id":687,"date":1424044800000,"IM":1294290,"MTM":18510972,"notional":10074838,"activeTrades":199}, -{"id":688,"date":1424131200000,"IM":1664205,"MTM":18637907,"notional":19271312,"activeTrades":194}, -{"id":689,"date":1424217600000,"IM":1614971,"MTM":15100539,"notional":18282303,"activeTrades":108}, -{"id":690,"date":1424304000000,"IM":1129785,"MTM":15237496,"notional":12381978,"activeTrades":135}, -{"id":691,"date":1424390400000,"IM":1144805,"MTM":18601432,"notional":19531060,"activeTrades":122}, -{"id":692,"date":1424476800000,"IM":1258605,"MTM":17133693,"notional":18065577,"activeTrades":189}, -{"id":693,"date":1424563200000,"IM":1477639,"MTM":17475666,"notional":16225709,"activeTrades":102}, -{"id":694,"date":1424649600000,"IM":1496366,"MTM":18058609,"notional":14749053,"activeTrades":163}, -{"id":695,"date":1424736000000,"IM":1116883,"MTM":11993355,"notional":15194015,"activeTrades":105}, -{"id":696,"date":1424822400000,"IM":1709391,"MTM":10028642,"notional":15915785,"activeTrades":123}, -{"id":697,"date":1424908800000,"IM":1870972,"MTM":13534599,"notional":11941039,"activeTrades":181}, -{"id":698,"date":1424995200000,"IM":1457697,"MTM":10701017,"notional":11300320,"activeTrades":195}, -{"id":699,"date":1425081600000,"IM":1394758,"MTM":17740960,"notional":10106432,"activeTrades":178}, -{"id":700,"date":1425168000000,"IM":1134807,"MTM":15732672,"notional":18356397,"activeTrades":187}, -{"id":701,"date":1425254400000,"IM":1167729,"MTM":10345824,"notional":11247769,"activeTrades":104}, -{"id":702,"date":1425340800000,"IM":1666844,"MTM":12477340,"notional":12792934,"activeTrades":123}, -{"id":703,"date":1425427200000,"IM":1310193,"MTM":11247877,"notional":14255952,"activeTrades":136}, -{"id":704,"date":1425513600000,"IM":1732795,"MTM":15397364,"notional":17771819,"activeTrades":101}, -{"id":705,"date":1425600000000,"IM":1814600,"MTM":15133278,"notional":17550877,"activeTrades":186}, -{"id":706,"date":1425686400000,"IM":1120438,"MTM":10133706,"notional":12322828,"activeTrades":157}, -{"id":707,"date":1425772800000,"IM":1646328,"MTM":15247256,"notional":10735090,"activeTrades":158}, -{"id":708,"date":1425859200000,"IM":1497550,"MTM":10300192,"notional":10387412,"activeTrades":125}, -{"id":709,"date":1425945600000,"IM":1653241,"MTM":18293729,"notional":13004315,"activeTrades":127}, -{"id":710,"date":1426032000000,"IM":1593016,"MTM":11368524,"notional":15234799,"activeTrades":113}, -{"id":711,"date":1426118400000,"IM":1718188,"MTM":15827921,"notional":17246358,"activeTrades":185}, -{"id":712,"date":1426204800000,"IM":1529263,"MTM":19684160,"notional":18231899,"activeTrades":123}, -{"id":713,"date":1426291200000,"IM":1253364,"MTM":15041523,"notional":17606206,"activeTrades":119}, -{"id":714,"date":1426377600000,"IM":1972676,"MTM":11926109,"notional":16636350,"activeTrades":163}, -{"id":715,"date":1426464000000,"IM":1862776,"MTM":18962809,"notional":12499787,"activeTrades":183}, -{"id":716,"date":1426550400000,"IM":1900580,"MTM":10962577,"notional":12782791,"activeTrades":146}, -{"id":717,"date":1426636800000,"IM":1341272,"MTM":13616234,"notional":17296331,"activeTrades":190}, -{"id":718,"date":1426723200000,"IM":1625062,"MTM":15194646,"notional":16367579,"activeTrades":127}, -{"id":719,"date":1426809600000,"IM":1852631,"MTM":17985107,"notional":17496474,"activeTrades":179}, -{"id":720,"date":1426896000000,"IM":1433088,"MTM":13362505,"notional":10609681,"activeTrades":171}, -{"id":721,"date":1426982400000,"IM":1272933,"MTM":18404590,"notional":14970501,"activeTrades":112}, -{"id":722,"date":1427068800000,"IM":1893560,"MTM":18083568,"notional":12087374,"activeTrades":156}, -{"id":723,"date":1427155200000,"IM":1629680,"MTM":17784494,"notional":18013863,"activeTrades":155}, -{"id":724,"date":1427241600000,"IM":1750110,"MTM":17363739,"notional":11341432,"activeTrades":143}, -{"id":725,"date":1427328000000,"IM":1896250,"MTM":13446040,"notional":18023649,"activeTrades":173}, -{"id":726,"date":1427414400000,"IM":1969440,"MTM":16683274,"notional":18439841,"activeTrades":156}, -{"id":727,"date":1427500800000,"IM":1571965,"MTM":18097544,"notional":11684308,"activeTrades":186}, -{"id":728,"date":1427587200000,"IM":1290093,"MTM":14465856,"notional":17331862,"activeTrades":178}, -{"id":729,"date":1427673600000,"IM":1732005,"MTM":14598440,"notional":10134793,"activeTrades":144}, -{"id":730,"date":1427760000000,"IM":1840764,"MTM":11129364,"notional":19841088,"activeTrades":173}, -{"id":731,"date":1427846400000,"IM":1834783,"MTM":18251436,"notional":15109655,"activeTrades":169}, -{"id":732,"date":1427932800000,"IM":1876898,"MTM":11631995,"notional":10976063,"activeTrades":124}, -{"id":733,"date":1428019200000,"IM":1568920,"MTM":18675980,"notional":14088111,"activeTrades":148}, -{"id":734,"date":1428105600000,"IM":1890237,"MTM":16932110,"notional":18948056,"activeTrades":123}, -{"id":735,"date":1428192000000,"IM":1237274,"MTM":11137635,"notional":11547341,"activeTrades":180}, -{"id":736,"date":1428278400000,"IM":1098819,"MTM":16686355,"notional":10945502,"activeTrades":160}, -{"id":737,"date":1428364800000,"IM":1677670,"MTM":11689357,"notional":17171745,"activeTrades":194}, -{"id":738,"date":1428451200000,"IM":1690683,"MTM":19532400,"notional":16790465,"activeTrades":197}, -{"id":739,"date":1428537600000,"IM":1652067,"MTM":11225472,"notional":14441230,"activeTrades":166}, -{"id":740,"date":1428624000000,"IM":1778422,"MTM":15321422,"notional":15094936,"activeTrades":131}, -{"id":741,"date":1428710400000,"IM":1289462,"MTM":18231021,"notional":19316357,"activeTrades":149}, -{"id":742,"date":1428796800000,"IM":1073066,"MTM":15604814,"notional":18315716,"activeTrades":156}, -{"id":743,"date":1428883200000,"IM":1100217,"MTM":15314729,"notional":16013488,"activeTrades":200}, -{"id":744,"date":1428969600000,"IM":1102006,"MTM":13634017,"notional":13625738,"activeTrades":162}, -{"id":745,"date":1429056000000,"IM":1157141,"MTM":14577948,"notional":18208538,"activeTrades":171}, -{"id":746,"date":1429142400000,"IM":1203708,"MTM":11254139,"notional":12339532,"activeTrades":199}, -{"id":747,"date":1429228800000,"IM":1393669,"MTM":12591045,"notional":17388843,"activeTrades":142}, -{"id":748,"date":1429315200000,"IM":1297222,"MTM":17661531,"notional":11546392,"activeTrades":130}, -{"id":749,"date":1429401600000,"IM":1406195,"MTM":11499280,"notional":19018665,"activeTrades":103}, -{"id":750,"date":1429488000000,"IM":1619323,"MTM":16933799,"notional":12834331,"activeTrades":151}, -{"id":751,"date":1429574400000,"IM":1833074,"MTM":11220324,"notional":14325313,"activeTrades":103}, -{"id":752,"date":1429660800000,"IM":1902398,"MTM":19240066,"notional":16661302,"activeTrades":102}, -{"id":753,"date":1429747200000,"IM":1532248,"MTM":13611912,"notional":11338602,"activeTrades":138}, -{"id":754,"date":1429833600000,"IM":1786588,"MTM":19158705,"notional":13455157,"activeTrades":129}, -{"id":755,"date":1429920000000,"IM":1168080,"MTM":10734233,"notional":14975609,"activeTrades":124}, -{"id":756,"date":1430006400000,"IM":1605084,"MTM":10676109,"notional":17488986,"activeTrades":171}, -{"id":757,"date":1430092800000,"IM":1173888,"MTM":15718157,"notional":13669367,"activeTrades":109}, -{"id":758,"date":1430179200000,"IM":1295667,"MTM":18900294,"notional":11341578,"activeTrades":192}, -{"id":759,"date":1430265600000,"IM":1145377,"MTM":12566341,"notional":15389270,"activeTrades":136}, -{"id":760,"date":1430352000000,"IM":1225604,"MTM":16508200,"notional":14758545,"activeTrades":161}, -{"id":761,"date":1430438400000,"IM":1402726,"MTM":14875058,"notional":16937672,"activeTrades":114}, -{"id":762,"date":1430524800000,"IM":1893535,"MTM":11346912,"notional":13291242,"activeTrades":134}, -{"id":763,"date":1430611200000,"IM":1406635,"MTM":15416564,"notional":18457734,"activeTrades":180}, -{"id":764,"date":1430697600000,"IM":1157837,"MTM":12292814,"notional":14962433,"activeTrades":127}, -{"id":765,"date":1430784000000,"IM":1325658,"MTM":15867728,"notional":10707137,"activeTrades":146}, -{"id":766,"date":1430870400000,"IM":1919941,"MTM":10648254,"notional":17541602,"activeTrades":121}, -{"id":767,"date":1430956800000,"IM":1064076,"MTM":15082987,"notional":11224645,"activeTrades":179}, -{"id":768,"date":1431043200000,"IM":1301923,"MTM":15815396,"notional":11101457,"activeTrades":120}, -{"id":769,"date":1431129600000,"IM":1779729,"MTM":17125372,"notional":10103741,"activeTrades":163}, -{"id":770,"date":1431216000000,"IM":1689964,"MTM":16568197,"notional":14301724,"activeTrades":125}, -{"id":771,"date":1431302400000,"IM":1899435,"MTM":17807540,"notional":11591085,"activeTrades":150}, -{"id":772,"date":1431388800000,"IM":1086333,"MTM":10153388,"notional":12677931,"activeTrades":163}, -{"id":773,"date":1431475200000,"IM":1405880,"MTM":16529179,"notional":10396586,"activeTrades":141}, -{"id":774,"date":1431561600000,"IM":1313330,"MTM":15028173,"notional":15084509,"activeTrades":148}, -{"id":775,"date":1431648000000,"IM":1572637,"MTM":19908595,"notional":15367601,"activeTrades":145}, -{"id":776,"date":1431734400000,"IM":1107137,"MTM":15692188,"notional":17284388,"activeTrades":186}, -{"id":777,"date":1431820800000,"IM":1723140,"MTM":13275738,"notional":11581037,"activeTrades":172}, -{"id":778,"date":1431907200000,"IM":1144340,"MTM":18347834,"notional":10260155,"activeTrades":137}, -{"id":779,"date":1431993600000,"IM":1083852,"MTM":11948970,"notional":15425091,"activeTrades":126}, -{"id":780,"date":1432080000000,"IM":1513760,"MTM":19727157,"notional":14275785,"activeTrades":173}, -{"id":781,"date":1432166400000,"IM":1192770,"MTM":13686681,"notional":17267097,"activeTrades":120}, -{"id":782,"date":1432252800000,"IM":1627016,"MTM":16624703,"notional":12112405,"activeTrades":100}, -{"id":783,"date":1432339200000,"IM":1805995,"MTM":15923863,"notional":18828284,"activeTrades":170}, -{"id":784,"date":1432425600000,"IM":1011331,"MTM":12324743,"notional":10562064,"activeTrades":171}, -{"id":785,"date":1432512000000,"IM":1736757,"MTM":12086495,"notional":13505293,"activeTrades":108}, -{"id":786,"date":1432598400000,"IM":1153047,"MTM":15155376,"notional":19072155,"activeTrades":195}, -{"id":787,"date":1432684800000,"IM":1163757,"MTM":18064176,"notional":15125780,"activeTrades":144}, -{"id":788,"date":1432771200000,"IM":1454749,"MTM":16104899,"notional":19647409,"activeTrades":136}, -{"id":789,"date":1432857600000,"IM":1868373,"MTM":17948537,"notional":13893895,"activeTrades":110}, -{"id":790,"date":1432944000000,"IM":1397654,"MTM":15274006,"notional":17766951,"activeTrades":121}, -{"id":791,"date":1433030400000,"IM":1417825,"MTM":13352675,"notional":15172721,"activeTrades":150}, -{"id":792,"date":1433116800000,"IM":1933702,"MTM":11288226,"notional":11880382,"activeTrades":194}, -{"id":793,"date":1433203200000,"IM":1806333,"MTM":16511474,"notional":10055197,"activeTrades":130}, -{"id":794,"date":1433289600000,"IM":1149169,"MTM":12440284,"notional":10813390,"activeTrades":131}, -{"id":795,"date":1433376000000,"IM":1699966,"MTM":11688503,"notional":16729685,"activeTrades":151}, -{"id":796,"date":1433462400000,"IM":1116822,"MTM":12632445,"notional":15859211,"activeTrades":140}, -{"id":797,"date":1433548800000,"IM":1556619,"MTM":11022703,"notional":12000288,"activeTrades":125}, -{"id":798,"date":1433635200000,"IM":1693598,"MTM":11178058,"notional":18146544,"activeTrades":107}, -{"id":799,"date":1433721600000,"IM":1012010,"MTM":14513344,"notional":18660629,"activeTrades":198}, -{"id":800,"date":1433808000000,"IM":1094832,"MTM":13259475,"notional":12564101,"activeTrades":136}, -{"id":801,"date":1433894400000,"IM":1238688,"MTM":19040102,"notional":12809008,"activeTrades":198}, -{"id":802,"date":1433980800000,"IM":1770179,"MTM":18539547,"notional":10546010,"activeTrades":116}, -{"id":803,"date":1434067200000,"IM":1530562,"MTM":12813709,"notional":15427667,"activeTrades":181}, -{"id":804,"date":1434153600000,"IM":1007671,"MTM":17140468,"notional":15724018,"activeTrades":120}, -{"id":805,"date":1434240000000,"IM":1171532,"MTM":11910440,"notional":11735237,"activeTrades":143}, -{"id":806,"date":1434326400000,"IM":1255524,"MTM":19440966,"notional":11721873,"activeTrades":149}, -{"id":807,"date":1434412800000,"IM":1344380,"MTM":10647250,"notional":19471659,"activeTrades":102}, -{"id":808,"date":1434499200000,"IM":1730245,"MTM":17015858,"notional":19762983,"activeTrades":155}, -{"id":809,"date":1434585600000,"IM":1629634,"MTM":18382688,"notional":18254247,"activeTrades":139}, -{"id":810,"date":1434672000000,"IM":1597549,"MTM":17028574,"notional":14340939,"activeTrades":119}, -{"id":811,"date":1434758400000,"IM":1298310,"MTM":17649489,"notional":19372309,"activeTrades":123}, -{"id":812,"date":1434844800000,"IM":1753150,"MTM":18557876,"notional":16056224,"activeTrades":159}, -{"id":813,"date":1434931200000,"IM":1722666,"MTM":12202737,"notional":17485232,"activeTrades":105}, -{"id":814,"date":1435017600000,"IM":1012350,"MTM":17505137,"notional":15270944,"activeTrades":118}, -{"id":815,"date":1435104000000,"IM":1831765,"MTM":13505930,"notional":12583039,"activeTrades":133}, -{"id":816,"date":1435190400000,"IM":1094644,"MTM":17734319,"notional":17486174,"activeTrades":157}, -{"id":817,"date":1435276800000,"IM":1522942,"MTM":19293922,"notional":18786736,"activeTrades":101}, -{"id":818,"date":1435363200000,"IM":1690868,"MTM":18920886,"notional":11831368,"activeTrades":101}, -{"id":819,"date":1435449600000,"IM":1088630,"MTM":19696070,"notional":10285652,"activeTrades":113}, -{"id":820,"date":1435536000000,"IM":1399294,"MTM":19572892,"notional":12098200,"activeTrades":139}, -{"id":821,"date":1435622400000,"IM":1534588,"MTM":13355118,"notional":19409075,"activeTrades":173}, -{"id":822,"date":1435708800000,"IM":1673752,"MTM":16636889,"notional":14027493,"activeTrades":143}, -{"id":823,"date":1435795200000,"IM":1275528,"MTM":13870047,"notional":16504808,"activeTrades":125}, -{"id":824,"date":1435881600000,"IM":1232598,"MTM":13167232,"notional":17083096,"activeTrades":186}, -{"id":825,"date":1435968000000,"IM":1259175,"MTM":18204937,"notional":12995765,"activeTrades":107}, -{"id":826,"date":1436054400000,"IM":1610059,"MTM":12970437,"notional":15080247,"activeTrades":151}, -{"id":827,"date":1436140800000,"IM":1829545,"MTM":11666835,"notional":18464887,"activeTrades":113}, -{"id":828,"date":1436227200000,"IM":1787400,"MTM":17072877,"notional":12511478,"activeTrades":142}, -{"id":829,"date":1436313600000,"IM":1766554,"MTM":12724263,"notional":13647357,"activeTrades":198}, -{"id":830,"date":1436400000000,"IM":1437096,"MTM":17445924,"notional":19639767,"activeTrades":184}, -{"id":831,"date":1436486400000,"IM":1915942,"MTM":11259925,"notional":10383167,"activeTrades":119}, -{"id":832,"date":1436572800000,"IM":1453408,"MTM":18092793,"notional":17964838,"activeTrades":131}, -{"id":833,"date":1436659200000,"IM":1720987,"MTM":17609902,"notional":17033968,"activeTrades":190}, -{"id":834,"date":1436745600000,"IM":1263831,"MTM":16782977,"notional":10207570,"activeTrades":157}, -{"id":835,"date":1436832000000,"IM":1535637,"MTM":11823027,"notional":15657602,"activeTrades":146}, -{"id":836,"date":1436918400000,"IM":1300703,"MTM":18349294,"notional":12660893,"activeTrades":179}, -{"id":837,"date":1437004800000,"IM":1677325,"MTM":15378197,"notional":10990427,"activeTrades":126}, -{"id":838,"date":1437091200000,"IM":1842345,"MTM":16524561,"notional":14256898,"activeTrades":174}, -{"id":839,"date":1437177600000,"IM":1493087,"MTM":10802045,"notional":16024324,"activeTrades":117}, -{"id":840,"date":1437264000000,"IM":1401563,"MTM":11197672,"notional":17104230,"activeTrades":107}, -{"id":841,"date":1437350400000,"IM":1419613,"MTM":19506467,"notional":10039720,"activeTrades":151}, -{"id":842,"date":1437436800000,"IM":1064916,"MTM":15778250,"notional":19028722,"activeTrades":111}, -{"id":843,"date":1437523200000,"IM":1981426,"MTM":12367066,"notional":13564954,"activeTrades":173}, -{"id":844,"date":1437609600000,"IM":1707526,"MTM":15371771,"notional":19766824,"activeTrades":154}, -{"id":845,"date":1437696000000,"IM":1596397,"MTM":19782246,"notional":19140185,"activeTrades":145}, -{"id":846,"date":1437782400000,"IM":1332516,"MTM":19162250,"notional":18641394,"activeTrades":130}, -{"id":847,"date":1437868800000,"IM":1511190,"MTM":15628446,"notional":17925968,"activeTrades":185}, -{"id":848,"date":1437955200000,"IM":1486398,"MTM":13857110,"notional":19322681,"activeTrades":137}, -{"id":849,"date":1438041600000,"IM":1073912,"MTM":10530346,"notional":19388816,"activeTrades":120}, -{"id":850,"date":1438128000000,"IM":1959763,"MTM":16517445,"notional":13947400,"activeTrades":170}, -{"id":851,"date":1438214400000,"IM":1569515,"MTM":19912197,"notional":15973884,"activeTrades":111}, -{"id":852,"date":1438300800000,"IM":1491423,"MTM":12583919,"notional":15641141,"activeTrades":196}, -{"id":853,"date":1438387200000,"IM":1878535,"MTM":17897911,"notional":12647891,"activeTrades":141}, -{"id":854,"date":1438473600000,"IM":1000679,"MTM":18815547,"notional":19792576,"activeTrades":145}, -{"id":855,"date":1438560000000,"IM":1149340,"MTM":17806634,"notional":19573793,"activeTrades":175}, -{"id":856,"date":1438646400000,"IM":1510066,"MTM":11983902,"notional":15782822,"activeTrades":132}, -{"id":857,"date":1438732800000,"IM":1354149,"MTM":13072473,"notional":11708195,"activeTrades":109}, -{"id":858,"date":1438819200000,"IM":1170246,"MTM":10144644,"notional":13359423,"activeTrades":194}, -{"id":859,"date":1438905600000,"IM":1743183,"MTM":13448184,"notional":11917152,"activeTrades":158}, -{"id":860,"date":1438992000000,"IM":1862851,"MTM":10337948,"notional":14947003,"activeTrades":150}, -{"id":861,"date":1439078400000,"IM":1308620,"MTM":16163871,"notional":16306417,"activeTrades":176}, -{"id":862,"date":1439164800000,"IM":1898000,"MTM":10587999,"notional":18453653,"activeTrades":157}, -{"id":863,"date":1439251200000,"IM":1691467,"MTM":12879725,"notional":15049519,"activeTrades":158}, -{"id":864,"date":1439337600000,"IM":1647298,"MTM":17338706,"notional":18855773,"activeTrades":159}, -{"id":865,"date":1439424000000,"IM":1700568,"MTM":18072974,"notional":18253015,"activeTrades":162}, -{"id":866,"date":1439510400000,"IM":1055540,"MTM":13986852,"notional":17844136,"activeTrades":165}, -{"id":867,"date":1439596800000,"IM":1717971,"MTM":12576207,"notional":13511778,"activeTrades":143}, -{"id":868,"date":1439683200000,"IM":1190522,"MTM":17666809,"notional":16744690,"activeTrades":200}, -{"id":869,"date":1439769600000,"IM":1188995,"MTM":17413285,"notional":17872199,"activeTrades":117}, -{"id":870,"date":1439856000000,"IM":1127823,"MTM":19555532,"notional":12828955,"activeTrades":146}, -{"id":871,"date":1439942400000,"IM":1501615,"MTM":16687483,"notional":15902253,"activeTrades":197}, -{"id":872,"date":1440028800000,"IM":1723792,"MTM":11442646,"notional":12986693,"activeTrades":123}, -{"id":873,"date":1440115200000,"IM":1823366,"MTM":17891888,"notional":16974630,"activeTrades":134}, -{"id":874,"date":1440201600000,"IM":1057195,"MTM":12978414,"notional":18833994,"activeTrades":143}, -{"id":875,"date":1440288000000,"IM":1038343,"MTM":11524292,"notional":14659646,"activeTrades":107}, -{"id":876,"date":1440374400000,"IM":1504790,"MTM":17988333,"notional":14016156,"activeTrades":139}, -{"id":877,"date":1440460800000,"IM":1323019,"MTM":11550981,"notional":19456174,"activeTrades":144}, -{"id":878,"date":1440547200000,"IM":1105618,"MTM":18092097,"notional":17596198,"activeTrades":116}, -{"id":879,"date":1440633600000,"IM":1691078,"MTM":12280767,"notional":10542296,"activeTrades":159}, -{"id":880,"date":1440720000000,"IM":1359688,"MTM":16432768,"notional":11993089,"activeTrades":125}, -{"id":881,"date":1440806400000,"IM":1024232,"MTM":17937772,"notional":11498945,"activeTrades":111}, -{"id":882,"date":1440892800000,"IM":1183978,"MTM":12167954,"notional":13853601,"activeTrades":164}, -{"id":883,"date":1440979200000,"IM":1131555,"MTM":14276374,"notional":11304405,"activeTrades":113}, -{"id":884,"date":1441065600000,"IM":1799398,"MTM":11408687,"notional":10805693,"activeTrades":125}, -{"id":885,"date":1441152000000,"IM":1031966,"MTM":10372965,"notional":10572419,"activeTrades":137}, -{"id":886,"date":1441238400000,"IM":1635637,"MTM":14017592,"notional":11406735,"activeTrades":129}, -{"id":887,"date":1441324800000,"IM":1078359,"MTM":12797229,"notional":15238666,"activeTrades":144}, -{"id":888,"date":1441411200000,"IM":1415141,"MTM":19025303,"notional":10177035,"activeTrades":130}, -{"id":889,"date":1441497600000,"IM":1775784,"MTM":11418666,"notional":18527421,"activeTrades":136}, -{"id":890,"date":1441584000000,"IM":1575263,"MTM":14423848,"notional":14078412,"activeTrades":121}, -{"id":891,"date":1441670400000,"IM":1085372,"MTM":10551552,"notional":10475709,"activeTrades":102}, -{"id":892,"date":1441756800000,"IM":1139374,"MTM":12236268,"notional":19431270,"activeTrades":186}, -{"id":893,"date":1441843200000,"IM":1615819,"MTM":11456977,"notional":10855417,"activeTrades":125}, -{"id":894,"date":1441929600000,"IM":1327802,"MTM":19239065,"notional":14345805,"activeTrades":119}, -{"id":895,"date":1442016000000,"IM":1109663,"MTM":10465356,"notional":18658615,"activeTrades":184}, -{"id":896,"date":1442102400000,"IM":1042823,"MTM":16313138,"notional":17050148,"activeTrades":106}, -{"id":897,"date":1442188800000,"IM":1345752,"MTM":11958461,"notional":15143230,"activeTrades":168}, -{"id":898,"date":1442275200000,"IM":1120711,"MTM":18060215,"notional":19404204,"activeTrades":194}, -{"id":899,"date":1442361600000,"IM":1203501,"MTM":12060624,"notional":16031862,"activeTrades":158}, -{"id":900,"date":1442448000000,"IM":1078044,"MTM":12695558,"notional":14575865,"activeTrades":152}, -{"id":901,"date":1442534400000,"IM":1395970,"MTM":14495491,"notional":12075051,"activeTrades":121}, -{"id":902,"date":1442620800000,"IM":1310636,"MTM":19001421,"notional":11453784,"activeTrades":125}, -{"id":903,"date":1442707200000,"IM":1905284,"MTM":14492696,"notional":13398097,"activeTrades":138}, -{"id":904,"date":1442793600000,"IM":1933834,"MTM":11124924,"notional":17104793,"activeTrades":165}, -{"id":905,"date":1442880000000,"IM":1489095,"MTM":10716426,"notional":12304731,"activeTrades":148}, -{"id":906,"date":1442966400000,"IM":1360806,"MTM":14222095,"notional":11913993,"activeTrades":122}, -{"id":907,"date":1443052800000,"IM":1071878,"MTM":14482266,"notional":13702537,"activeTrades":169}, -{"id":908,"date":1443139200000,"IM":1737044,"MTM":11543551,"notional":10541761,"activeTrades":100}, -{"id":909,"date":1443225600000,"IM":1012046,"MTM":12780474,"notional":19144367,"activeTrades":104}, -{"id":910,"date":1443312000000,"IM":1556024,"MTM":18223244,"notional":15190045,"activeTrades":129}, -{"id":911,"date":1443398400000,"IM":1945046,"MTM":12577536,"notional":18833786,"activeTrades":106}, -{"id":912,"date":1443484800000,"IM":1196463,"MTM":13194045,"notional":11206368,"activeTrades":116}, -{"id":913,"date":1443571200000,"IM":1686719,"MTM":13701615,"notional":12034566,"activeTrades":135}, -{"id":914,"date":1443657600000,"IM":1059516,"MTM":18279468,"notional":18576881,"activeTrades":185}, -{"id":915,"date":1443744000000,"IM":1576173,"MTM":13880092,"notional":16354546,"activeTrades":119}, -{"id":916,"date":1443830400000,"IM":1817383,"MTM":16832895,"notional":11657797,"activeTrades":157}, -{"id":917,"date":1443916800000,"IM":1363983,"MTM":17604808,"notional":15393331,"activeTrades":130}, -{"id":918,"date":1444003200000,"IM":1224517,"MTM":18258995,"notional":14298597,"activeTrades":144}, -{"id":919,"date":1444089600000,"IM":1453808,"MTM":19314436,"notional":12290793,"activeTrades":169}, -{"id":920,"date":1444176000000,"IM":1724974,"MTM":16029185,"notional":10385073,"activeTrades":132}, -{"id":921,"date":1444262400000,"IM":1356497,"MTM":18330987,"notional":16926034,"activeTrades":126}, -{"id":922,"date":1444348800000,"IM":1156477,"MTM":13730342,"notional":19022924,"activeTrades":194}, -{"id":923,"date":1444435200000,"IM":1632880,"MTM":10881526,"notional":17346886,"activeTrades":161}, -{"id":924,"date":1444521600000,"IM":1066220,"MTM":19786220,"notional":18640435,"activeTrades":159}, -{"id":925,"date":1444608000000,"IM":1302202,"MTM":16782908,"notional":13334407,"activeTrades":142}, -{"id":926,"date":1444694400000,"IM":1261905,"MTM":19004536,"notional":18597377,"activeTrades":125}, -{"id":927,"date":1444780800000,"IM":1406829,"MTM":13602531,"notional":16179351,"activeTrades":103}, -{"id":928,"date":1444867200000,"IM":1865267,"MTM":13117005,"notional":18654684,"activeTrades":135}, -{"id":929,"date":1444953600000,"IM":1242206,"MTM":11674659,"notional":10862071,"activeTrades":193}, -{"id":930,"date":1445040000000,"IM":1409824,"MTM":12572213,"notional":18574852,"activeTrades":148}, -{"id":931,"date":1445126400000,"IM":1051744,"MTM":19528057,"notional":10316484,"activeTrades":124}, -{"id":932,"date":1445212800000,"IM":1443725,"MTM":11390976,"notional":16369986,"activeTrades":102}, -{"id":933,"date":1445299200000,"IM":1528765,"MTM":12379656,"notional":16632077,"activeTrades":120}, -{"id":934,"date":1445385600000,"IM":1066824,"MTM":17370885,"notional":15963332,"activeTrades":183}, -{"id":935,"date":1445472000000,"IM":1972606,"MTM":19675428,"notional":11018977,"activeTrades":169}, -{"id":936,"date":1445558400000,"IM":1918880,"MTM":10979863,"notional":13052900,"activeTrades":156}, -{"id":937,"date":1445644800000,"IM":1898199,"MTM":15790988,"notional":19957057,"activeTrades":177}, -{"id":938,"date":1445731200000,"IM":1348201,"MTM":15541760,"notional":11681891,"activeTrades":125}, -{"id":939,"date":1445817600000,"IM":1291212,"MTM":14228143,"notional":17046487,"activeTrades":140}, -{"id":940,"date":1445904000000,"IM":1758888,"MTM":12284152,"notional":16380770,"activeTrades":126}, -{"id":941,"date":1445990400000,"IM":1704751,"MTM":19071174,"notional":10813660,"activeTrades":200}, -{"id":942,"date":1446076800000,"IM":1582688,"MTM":14898866,"notional":13737716,"activeTrades":166}, -{"id":943,"date":1446163200000,"IM":1385323,"MTM":12337746,"notional":16260915,"activeTrades":134}, -{"id":944,"date":1446249600000,"IM":1564812,"MTM":10309955,"notional":15757102,"activeTrades":163}, -{"id":945,"date":1446336000000,"IM":1798008,"MTM":12458748,"notional":13944180,"activeTrades":143}, -{"id":946,"date":1446422400000,"IM":1868684,"MTM":15629500,"notional":11280994,"activeTrades":193}, -{"id":947,"date":1446508800000,"IM":1430005,"MTM":19424022,"notional":16926972,"activeTrades":113}, -{"id":948,"date":1446595200000,"IM":1911677,"MTM":12512023,"notional":10214211,"activeTrades":124}, -{"id":949,"date":1446681600000,"IM":1983986,"MTM":11424372,"notional":17810511,"activeTrades":199}, -{"id":950,"date":1446768000000,"IM":1279793,"MTM":11279159,"notional":17916606,"activeTrades":131}, -{"id":951,"date":1446854400000,"IM":1384671,"MTM":11483892,"notional":15705103,"activeTrades":190}, -{"id":952,"date":1446940800000,"IM":1781041,"MTM":16673217,"notional":17000749,"activeTrades":140}, -{"id":953,"date":1447027200000,"IM":1116783,"MTM":15468998,"notional":13473120,"activeTrades":121}, -{"id":954,"date":1447113600000,"IM":1569288,"MTM":13517530,"notional":19760382,"activeTrades":173}, -{"id":955,"date":1447200000000,"IM":1898323,"MTM":14335882,"notional":18165859,"activeTrades":162}, -{"id":956,"date":1447286400000,"IM":1397413,"MTM":19176243,"notional":19441555,"activeTrades":110}, -{"id":957,"date":1447372800000,"IM":1219753,"MTM":18990095,"notional":15964609,"activeTrades":155}, -{"id":958,"date":1447459200000,"IM":1281008,"MTM":18160522,"notional":19264778,"activeTrades":189}, -{"id":959,"date":1447545600000,"IM":1203401,"MTM":10782158,"notional":17993316,"activeTrades":110}, -{"id":960,"date":1447632000000,"IM":1580346,"MTM":15461521,"notional":14834836,"activeTrades":125}, -{"id":961,"date":1447718400000,"IM":1821838,"MTM":18056025,"notional":19770217,"activeTrades":129}, -{"id":962,"date":1447804800000,"IM":1858720,"MTM":16220542,"notional":14755159,"activeTrades":197}, -{"id":963,"date":1447891200000,"IM":1035648,"MTM":12583897,"notional":15494004,"activeTrades":127}, -{"id":964,"date":1447977600000,"IM":1792513,"MTM":15128523,"notional":14878454,"activeTrades":159}, -{"id":965,"date":1448064000000,"IM":1053880,"MTM":17329669,"notional":10683656,"activeTrades":163}, -{"id":966,"date":1448150400000,"IM":1623292,"MTM":17327793,"notional":17675582,"activeTrades":165}, -{"id":967,"date":1448236800000,"IM":1592698,"MTM":18857530,"notional":11798453,"activeTrades":128}, -{"id":968,"date":1448323200000,"IM":1859183,"MTM":12491148,"notional":19180927,"activeTrades":162}, -{"id":969,"date":1448409600000,"IM":1758408,"MTM":15452396,"notional":19013830,"activeTrades":115}, -{"id":970,"date":1448496000000,"IM":1811599,"MTM":11032453,"notional":19794960,"activeTrades":112}, -{"id":971,"date":1448582400000,"IM":1571857,"MTM":18588849,"notional":15242798,"activeTrades":127}, -{"id":972,"date":1448668800000,"IM":1798531,"MTM":10864950,"notional":13384876,"activeTrades":156}, -{"id":973,"date":1448755200000,"IM":1206635,"MTM":15444782,"notional":16501689,"activeTrades":109}, -{"id":974,"date":1448841600000,"IM":1946329,"MTM":16251841,"notional":12616812,"activeTrades":148}, -{"id":975,"date":1448928000000,"IM":1465687,"MTM":13669875,"notional":12906598,"activeTrades":143}, -{"id":976,"date":1449014400000,"IM":1845312,"MTM":11671293,"notional":16654703,"activeTrades":145}, -{"id":977,"date":1449100800000,"IM":1095552,"MTM":15813894,"notional":17567222,"activeTrades":111}, -{"id":978,"date":1449187200000,"IM":1696836,"MTM":17495985,"notional":13104998,"activeTrades":142}, -{"id":979,"date":1449273600000,"IM":1609107,"MTM":15428127,"notional":15218136,"activeTrades":138}, -{"id":980,"date":1449360000000,"IM":1760216,"MTM":18343232,"notional":14841968,"activeTrades":195}, -{"id":981,"date":1449446400000,"IM":1008994,"MTM":18967457,"notional":13134694,"activeTrades":128}, -{"id":982,"date":1449532800000,"IM":1220269,"MTM":15741143,"notional":18128519,"activeTrades":142}, -{"id":983,"date":1449619200000,"IM":1024742,"MTM":11551853,"notional":15413173,"activeTrades":182}, -{"id":984,"date":1449705600000,"IM":1797136,"MTM":15579139,"notional":19140708,"activeTrades":146}, -{"id":985,"date":1449792000000,"IM":1902954,"MTM":18228278,"notional":13702829,"activeTrades":147}, -{"id":986,"date":1449878400000,"IM":1273732,"MTM":14380707,"notional":13162812,"activeTrades":170}, -{"id":987,"date":1449964800000,"IM":1606767,"MTM":15821462,"notional":19853612,"activeTrades":117}, -{"id":988,"date":1450051200000,"IM":1605292,"MTM":13860120,"notional":19255064,"activeTrades":148}, -{"id":989,"date":1450137600000,"IM":1204252,"MTM":12536519,"notional":11392382,"activeTrades":130}, -{"id":990,"date":1450224000000,"IM":1904355,"MTM":15514337,"notional":10934429,"activeTrades":177}, -{"id":991,"date":1450310400000,"IM":1778234,"MTM":15748452,"notional":13512366,"activeTrades":120}, -{"id":992,"date":1450396800000,"IM":1020930,"MTM":14948248,"notional":15494284,"activeTrades":200}, -{"id":993,"date":1450483200000,"IM":1987429,"MTM":16062942,"notional":17002836,"activeTrades":175}, -{"id":994,"date":1450569600000,"IM":1957490,"MTM":14239607,"notional":19195768,"activeTrades":166}, -{"id":995,"date":1450656000000,"IM":1003434,"MTM":12959537,"notional":11492913,"activeTrades":197}, -{"id":996,"date":1450742400000,"IM":1161196,"MTM":10038502,"notional":13350481,"activeTrades":162}, -{"id":997,"date":1450828800000,"IM":1462516,"MTM":11173256,"notional":12077187,"activeTrades":183}, -{"id":998,"date":1450915200000,"IM":1786710,"MTM":14832990,"notional":12704601,"activeTrades":132}, -{"id":999,"date":1451001600000,"IM":1824435,"MTM":19327760,"notional":13080800,"activeTrades":126}, -{"id":1000,"date":1451088000000,"IM":1372215,"MTM":16507571,"notional":19705095,"activeTrades":200}] \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/valuations b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/valuations deleted file mode 100644 index 915f2d44e8..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/portfolio/valuations +++ /dev/null @@ -1,90 +0,0 @@ -{ - "businessDate": "2016-09-31", - "portfolio": { - "baseCurrency": "EUR", - "IRFX": 250, - "commodity": 0, - "equity": 0, - "credit": 0, - "total": 250, - "agreed": true - }, - "marketData": { - "yieldCurves": { - "name": "EUR", - "values": [{ - "tenor": "1M", - "rate": 0.001535 - }, { - "tenor": "2M", - "rate": 0.001535 - }] - }, - "fixings": { - "name": "EURIBOR", - "values": [{ - "tenor": "1M", - "rate": 0.001535 - }, { - "tenor": "2M", - "rate": 0.001535 - }] - }, - "agreed": true - }, - "sensitivities": { - "curves" : { - "EUR-DSCON-BIMM" : { - "3M" : 0.0, - "6M" : 1.9, - "1Y" : 78.52, - "2Y" : 163.24, - "3Y" : 325.84, - "5Y" : 196.82, - "10Y" : 0.0, - "15Y" : 0.0, - "20Y" : 0.0, - "30Y" : 0.0 - }, - "EUR-EURIBOR3M-BIMM" : { - "3M" : -1280.7, - "6M" : -93.43, - "1Y" : -12.98, - "2Y" : -26.06, - "3Y" : 7886.01, - "5Y" : 13643.5, - "10Y" : 0.0, - "15Y" : 0.0, - "20Y" : 0.0, - "30Y" : 0.0 - } - }, - "currency" : [ { - "currency" : "EUR", - "amount" : -294.26 - } ], - "agreed": true - }, - "initialMargin": { - "baseCurrency": "EUR", - "post": { - "IRFX": 123123, - "commodity": 0, - "equity": 0, - "credit": 0, - "total": 123123 - }, - "call": { - "IRFX": 123123, - "commodity": 0, - "equity": 0, - "credit": 0, - "total": 123123 - }, - "agreed": true - }, - "confirmation": { - "hash": "dfdec888b72151965a34b4b59031290adfdec888b72151965a34b4b59031290a", - "agreed": true - } -} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/trades b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/trades deleted file mode 100644 index 053d22bed0..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/intesa/trades +++ /dev/null @@ -1,251 +0,0 @@ -[{ "id": 1, "product": "Vanilla IRS", "tradeDate": "2015-04-12", "effectiveDate": "2015-06-17", "maturityDate": "2015-02-28", "currency": "EUR", "notional": 412635, "IM": 220198, "MTM": 202628, "margined": true }, - { "id": 2, "product": "Vanilla IRS", "tradeDate": "2015-05-02", "effectiveDate": "2015-07-13", "maturityDate": "2015-09-22", "currency": "EUR", "notional": 991617, "IM": 529635, "MTM": 349846, "margined": true }, - { "id": 3, "product": "Vanilla IRS", "tradeDate": "2015-07-17", "effectiveDate": "2016-06-25", "maturityDate": "2015-12-07", "currency": "EUR", "notional": 155853, "IM": 187289, "MTM": 970997, "margined": true }, - { "id": 4, "product": "Vanilla IRS", "tradeDate": "2016-02-17", "effectiveDate": "2015-07-06", "maturityDate": "2015-08-11", "currency": "EUR", "notional": 613642, "IM": 445632, "MTM": 947813, "margined": true }, - { "id": 5, "product": "Vanilla IRS", "tradeDate": "2016-04-15", "effectiveDate": "2015-03-14", "maturityDate": "2015-09-13", "currency": "EUR", "notional": 435814, "IM": 779103, "MTM": 333973, "margined": true }, - { "id": 6, "product": "Vanilla IRS", "tradeDate": "2015-06-19", "effectiveDate": "2015-09-28", "maturityDate": "2015-12-17", "currency": "EUR", "notional": 194337, "IM": 619829, "MTM": 140152, "margined": true }, - { "id": 7, "product": "Vanilla IRS", "tradeDate": "2015-02-27", "effectiveDate": "2015-08-26", "maturityDate": "2015-06-04", "currency": "EUR", "notional": 542126, "IM": 992362, "MTM": 249949, "margined": true }, - { "id": 8, "product": "Vanilla IRS", "tradeDate": "2016-05-13", "effectiveDate": "2015-11-14", "maturityDate": "2016-07-27", "currency": "EUR", "notional": 306804, "IM": 874015, "MTM": 948942, "margined": true }, - { "id": 9, "product": "Vanilla IRS", "tradeDate": "2015-10-03", "effectiveDate": "2016-07-15", "maturityDate": "2015-05-16", "currency": "EUR", "notional": 326788, "IM": 848773, "MTM": 978794, "margined": true }, - { "id": 10, "product": "Vanilla IRS", "tradeDate": "2016-07-27", "effectiveDate": "2015-11-23", "maturityDate": "2016-03-11", "currency": "EUR", "notional": 570214, "IM": 837692, "MTM": 628570, "margined": true }, - { "id": 11, "product": "Vanilla IRS", "tradeDate": "2015-10-26", "effectiveDate": "2015-04-17", "maturityDate": "2016-01-08", "currency": "EUR", "notional": 244588, "IM": 789380, "MTM": 212465, "margined": true }, - { "id": 12, "product": "Vanilla IRS", "tradeDate": "2016-03-12", "effectiveDate": "2016-05-10", "maturityDate": "2015-10-18", "currency": "EUR", "notional": 919551, "IM": 307343, "MTM": 518336, "margined": true }, - { "id": 13, "product": "Vanilla IRS", "tradeDate": "2016-05-10", "effectiveDate": "2015-04-13", "maturityDate": "2016-02-28", "currency": "EUR", "notional": 782611, "IM": 925088, "MTM": 138428, "margined": true }, - { "id": 14, "product": "Vanilla IRS", "tradeDate": "2015-08-20", "effectiveDate": "2016-04-14", "maturityDate": "2015-01-06", "currency": "EUR", "notional": 909907, "IM": 915080, "MTM": 538727, "margined": true }, - { "id": 15, "product": "Vanilla IRS", "tradeDate": "2016-05-03", "effectiveDate": "2016-04-04", "maturityDate": "2015-01-26", "currency": "EUR", "notional": 434821, "IM": 960567, "MTM": 989740, "margined": true }, - { "id": 16, "product": "Vanilla IRS", "tradeDate": "2016-05-05", "effectiveDate": "2016-03-17", "maturityDate": "2015-02-10", "currency": "EUR", "notional": 320688, "IM": 507161, "MTM": 568978, "margined": true }, - { "id": 17, "product": "Vanilla IRS", "tradeDate": "2016-06-24", "effectiveDate": "2016-02-29", "maturityDate": "2015-02-23", "currency": "EUR", "notional": 129519, "IM": 619991, "MTM": 929157, "margined": true }, - { "id": 18, "product": "Vanilla IRS", "tradeDate": "2016-04-28", "effectiveDate": "2015-10-04", "maturityDate": "2016-06-22", "currency": "EUR", "notional": 365617, "IM": 309962, "MTM": 408331, "margined": true }, - { "id": 19, "product": "Vanilla IRS", "tradeDate": "2016-03-26", "effectiveDate": "2015-04-20", "maturityDate": "2015-07-07", "currency": "EUR", "notional": 453024, "IM": 423071, "MTM": 465584, "margined": true }, - { "id": 20, "product": "Vanilla IRS", "tradeDate": "2015-02-08", "effectiveDate": "2016-04-16", "maturityDate": "2015-04-17", "currency": "EUR", "notional": 695786, "IM": 258930, "MTM": 674095, "margined": true }, - { "id": 21, "product": "Vanilla IRS", "tradeDate": "2015-07-02", "effectiveDate": "2016-07-29", "maturityDate": "2016-03-09", "currency": "EUR", "notional": 951507, "IM": 792502, "MTM": 534024, "margined": true }, - { "id": 22, "product": "Vanilla IRS", "tradeDate": "2016-03-02", "effectiveDate": "2015-05-05", "maturityDate": "2016-06-13", "currency": "EUR", "notional": 922463, "IM": 257644, "MTM": 450006, "margined": true }, - { "id": 23, "product": "Vanilla IRS", "tradeDate": "2016-01-13", "effectiveDate": "2015-04-15", "maturityDate": "2015-11-17", "currency": "EUR", "notional": 647626, "IM": 172138, "MTM": 604392, "margined": true }, - { "id": 24, "product": "Vanilla IRS", "tradeDate": "2015-05-15", "effectiveDate": "2016-01-28", "maturityDate": "2015-09-17", "currency": "EUR", "notional": 373674, "IM": 913095, "MTM": 159760, "margined": true }, - { "id": 25, "product": "Vanilla IRS", "tradeDate": "2016-05-02", "effectiveDate": "2015-02-04", "maturityDate": "2015-01-04", "currency": "EUR", "notional": 188489, "IM": 421218, "MTM": 916206, "margined": true }, - { "id": 26, "product": "Vanilla IRS", "tradeDate": "2015-06-06", "effectiveDate": "2015-11-17", "maturityDate": "2015-12-30", "currency": "EUR", "notional": 765553, "IM": 706932, "MTM": 102424, "margined": true }, - { "id": 27, "product": "Vanilla IRS", "tradeDate": "2015-08-20", "effectiveDate": "2016-03-29", "maturityDate": "2015-07-14", "currency": "EUR", "notional": 974790, "IM": 401997, "MTM": 841680, "margined": true }, - { "id": 28, "product": "Vanilla IRS", "tradeDate": "2015-10-29", "effectiveDate": "2015-07-31", "maturityDate": "2015-10-17", "currency": "EUR", "notional": 258179, "IM": 891115, "MTM": 392606, "margined": true }, - { "id": 29, "product": "Vanilla IRS", "tradeDate": "2016-07-13", "effectiveDate": "2015-02-20", "maturityDate": "2015-10-17", "currency": "EUR", "notional": 911896, "IM": 475511, "MTM": 140150, "margined": true }, - { "id": 30, "product": "Vanilla IRS", "tradeDate": "2015-06-25", "effectiveDate": "2015-01-26", "maturityDate": "2015-04-21", "currency": "EUR", "notional": 264670, "IM": 234038, "MTM": 568187, "margined": true }, - { "id": 31, "product": "Vanilla IRS", "tradeDate": "2015-04-26", "effectiveDate": "2015-09-23", "maturityDate": "2016-02-07", "currency": "EUR", "notional": 636459, "IM": 158656, "MTM": 699455, "margined": true }, - { "id": 32, "product": "Vanilla IRS", "tradeDate": "2015-10-24", "effectiveDate": "2015-09-16", "maturityDate": "2015-10-31", "currency": "EUR", "notional": 681530, "IM": 648655, "MTM": 916337, "margined": true }, - { "id": 33, "product": "Vanilla IRS", "tradeDate": "2015-10-29", "effectiveDate": "2016-05-08", "maturityDate": "2016-05-11", "currency": "EUR", "notional": 787217, "IM": 529471, "MTM": 676102, "margined": true }, - { "id": 34, "product": "Vanilla IRS", "tradeDate": "2015-12-29", "effectiveDate": "2016-06-01", "maturityDate": "2016-01-14", "currency": "EUR", "notional": 520313, "IM": 204439, "MTM": 476755, "margined": true }, - { "id": 35, "product": "Vanilla IRS", "tradeDate": "2015-11-15", "effectiveDate": "2016-03-05", "maturityDate": "2016-01-08", "currency": "EUR", "notional": 527037, "IM": 366062, "MTM": 787085, "margined": true }, - { "id": 36, "product": "Vanilla IRS", "tradeDate": "2015-06-12", "effectiveDate": "2015-03-08", "maturityDate": "2015-03-04", "currency": "EUR", "notional": 865165, "IM": 336671, "MTM": 767545, "margined": true }, - { "id": 37, "product": "Vanilla IRS", "tradeDate": "2016-04-20", "effectiveDate": "2015-07-22", "maturityDate": "2015-06-14", "currency": "EUR", "notional": 903893, "IM": 971569, "MTM": 701808, "margined": true }, - { "id": 38, "product": "Vanilla IRS", "tradeDate": "2016-07-27", "effectiveDate": "2015-03-08", "maturityDate": "2015-08-27", "currency": "EUR", "notional": 943185, "IM": 293936, "MTM": 452331, "margined": true }, - { "id": 39, "product": "Vanilla IRS", "tradeDate": "2016-04-17", "effectiveDate": "2015-07-21", "maturityDate": "2016-03-05", "currency": "EUR", "notional": 553489, "IM": 756055, "MTM": 395011, "margined": true }, - { "id": 40, "product": "Vanilla IRS", "tradeDate": "2015-05-25", "effectiveDate": "2015-06-25", "maturityDate": "2016-06-29", "currency": "EUR", "notional": 405675, "IM": 873088, "MTM": 893424, "margined": true }, - { "id": 41, "product": "Vanilla IRS", "tradeDate": "2016-01-08", "effectiveDate": "2015-12-14", "maturityDate": "2016-07-07", "currency": "EUR", "notional": 252387, "IM": 503456, "MTM": 313937, "margined": true }, - { "id": 42, "product": "Vanilla IRS", "tradeDate": "2015-07-22", "effectiveDate": "2016-04-19", "maturityDate": "2015-12-10", "currency": "EUR", "notional": 998005, "IM": 140280, "MTM": 872329, "margined": true }, - { "id": 43, "product": "Vanilla IRS", "tradeDate": "2016-04-05", "effectiveDate": "2015-05-29", "maturityDate": "2015-02-20", "currency": "EUR", "notional": 631930, "IM": 908918, "MTM": 185664, "margined": true }, - { "id": 44, "product": "Vanilla IRS", "tradeDate": "2015-12-28", "effectiveDate": "2015-03-28", "maturityDate": "2015-05-30", "currency": "EUR", "notional": 104303, "IM": 430988, "MTM": 312870, "margined": true }, - { "id": 45, "product": "Vanilla IRS", "tradeDate": "2015-08-11", "effectiveDate": "2016-04-13", "maturityDate": "2015-08-12", "currency": "EUR", "notional": 772367, "IM": 522537, "MTM": 371207, "margined": true }, - { "id": 46, "product": "Vanilla IRS", "tradeDate": "2016-03-30", "effectiveDate": "2015-01-23", "maturityDate": "2015-10-17", "currency": "EUR", "notional": 219610, "IM": 465520, "MTM": 452064, "margined": true }, - { "id": 47, "product": "Vanilla IRS", "tradeDate": "2015-02-22", "effectiveDate": "2016-03-20", "maturityDate": "2016-02-03", "currency": "EUR", "notional": 147083, "IM": 665313, "MTM": 767328, "margined": true }, - { "id": 48, "product": "Vanilla IRS", "tradeDate": "2015-06-07", "effectiveDate": "2015-12-17", "maturityDate": "2016-06-19", "currency": "EUR", "notional": 567630, "IM": 566645, "MTM": 478010, "margined": true }, - { "id": 49, "product": "Vanilla IRS", "tradeDate": "2015-07-21", "effectiveDate": "2015-02-09", "maturityDate": "2016-01-14", "currency": "EUR", "notional": 906750, "IM": 167162, "MTM": 236401, "margined": true }, - { "id": 50, "product": "Vanilla IRS", "tradeDate": "2015-03-30", "effectiveDate": "2015-04-09", "maturityDate": "2015-12-16", "currency": "EUR", "notional": 811931, "IM": 985568, "MTM": 618986, "margined": true }, - { "id": 51, "product": "Vanilla IRS", "tradeDate": "2016-01-31", "effectiveDate": "2015-07-17", "maturityDate": "2015-09-14", "currency": "EUR", "notional": 649060, "IM": 295786, "MTM": 854341, "margined": true }, - { "id": 52, "product": "Vanilla IRS", "tradeDate": "2015-11-13", "effectiveDate": "2016-06-06", "maturityDate": "2016-07-22", "currency": "EUR", "notional": 592192, "IM": 843888, "MTM": 155178, "margined": true }, - { "id": 53, "product": "Vanilla IRS", "tradeDate": "2015-06-03", "effectiveDate": "2016-08-07", "maturityDate": "2015-07-21", "currency": "EUR", "notional": 987109, "IM": 423246, "MTM": 325790, "margined": true }, - { "id": 54, "product": "Vanilla IRS", "tradeDate": "2015-02-17", "effectiveDate": "2015-12-22", "maturityDate": "2016-05-21", "currency": "EUR", "notional": 952745, "IM": 820303, "MTM": 864346, "margined": true }, - { "id": 55, "product": "Vanilla IRS", "tradeDate": "2015-07-03", "effectiveDate": "2016-02-06", "maturityDate": "2016-03-19", "currency": "EUR", "notional": 382065, "IM": 857237, "MTM": 381295, "margined": true }, - { "id": 56, "product": "Vanilla IRS", "tradeDate": "2015-01-02", "effectiveDate": "2015-04-08", "maturityDate": "2016-05-24", "currency": "EUR", "notional": 544155, "IM": 300622, "MTM": 679556, "margined": true }, - { "id": 57, "product": "Vanilla IRS", "tradeDate": "2016-03-26", "effectiveDate": "2016-04-29", "maturityDate": "2016-08-05", "currency": "EUR", "notional": 687942, "IM": 974396, "MTM": 148158, "margined": true }, - { "id": 58, "product": "Vanilla IRS", "tradeDate": "2016-05-29", "effectiveDate": "2015-09-30", "maturityDate": "2015-12-16", "currency": "EUR", "notional": 560539, "IM": 236338, "MTM": 998649, "margined": true }, - { "id": 59, "product": "Vanilla IRS", "tradeDate": "2016-03-25", "effectiveDate": "2016-07-26", "maturityDate": "2015-06-23", "currency": "EUR", "notional": 365279, "IM": 568942, "MTM": 291595, "margined": true }, - { "id": 60, "product": "Vanilla IRS", "tradeDate": "2016-06-30", "effectiveDate": "2015-12-13", "maturityDate": "2015-02-04", "currency": "EUR", "notional": 194907, "IM": 202232, "MTM": 917041, "margined": true }, - { "id": 61, "product": "Vanilla IRS", "tradeDate": "2015-04-09", "effectiveDate": "2015-04-30", "maturityDate": "2015-01-02", "currency": "EUR", "notional": 668912, "IM": 244367, "MTM": 723349, "margined": true }, - { "id": 62, "product": "Vanilla IRS", "tradeDate": "2016-02-09", "effectiveDate": "2016-06-04", "maturityDate": "2015-10-28", "currency": "EUR", "notional": 972691, "IM": 382644, "MTM": 180389, "margined": true }, - { "id": 63, "product": "Vanilla IRS", "tradeDate": "2015-07-28", "effectiveDate": "2015-09-24", "maturityDate": "2015-05-30", "currency": "EUR", "notional": 597122, "IM": 430418, "MTM": 791489, "margined": true }, - { "id": 64, "product": "Vanilla IRS", "tradeDate": "2016-05-23", "effectiveDate": "2015-03-24", "maturityDate": "2015-03-04", "currency": "EUR", "notional": 968238, "IM": 877378, "MTM": 848620, "margined": true }, - { "id": 65, "product": "Vanilla IRS", "tradeDate": "2015-01-09", "effectiveDate": "2016-07-07", "maturityDate": "2015-07-31", "currency": "EUR", "notional": 903958, "IM": 205853, "MTM": 571657, "margined": true }, - { "id": 66, "product": "Vanilla IRS", "tradeDate": "2016-03-12", "effectiveDate": "2015-10-31", "maturityDate": "2015-10-31", "currency": "EUR", "notional": 188736, "IM": 461935, "MTM": 822384, "margined": true }, - { "id": 67, "product": "Vanilla IRS", "tradeDate": "2015-01-25", "effectiveDate": "2015-10-08", "maturityDate": "2015-01-16", "currency": "EUR", "notional": 962336, "IM": 513634, "MTM": 733075, "margined": true }, - { "id": 68, "product": "Vanilla IRS", "tradeDate": "2016-01-04", "effectiveDate": "2015-02-23", "maturityDate": "2015-06-11", "currency": "EUR", "notional": 609579, "IM": 423560, "MTM": 759168, "margined": true }, - { "id": 69, "product": "Vanilla IRS", "tradeDate": "2016-01-13", "effectiveDate": "2015-01-11", "maturityDate": "2015-03-02", "currency": "EUR", "notional": 388417, "IM": 865220, "MTM": 178423, "margined": true }, - { "id": 70, "product": "Vanilla IRS", "tradeDate": "2016-06-11", "effectiveDate": "2015-05-29", "maturityDate": "2015-02-27", "currency": "EUR", "notional": 224777, "IM": 158658, "MTM": 693122, "margined": true }, - { "id": 71, "product": "Vanilla IRS", "tradeDate": "2016-04-29", "effectiveDate": "2015-03-29", "maturityDate": "2015-09-02", "currency": "EUR", "notional": 468703, "IM": 218005, "MTM": 823936, "margined": true }, - { "id": 72, "product": "Vanilla IRS", "tradeDate": "2016-06-29", "effectiveDate": "2015-04-30", "maturityDate": "2015-04-17", "currency": "EUR", "notional": 482529, "IM": 743895, "MTM": 264517, "margined": true }, - { "id": 73, "product": "Vanilla IRS", "tradeDate": "2015-10-11", "effectiveDate": "2015-03-23", "maturityDate": "2015-04-12", "currency": "EUR", "notional": 295342, "IM": 531494, "MTM": 132281, "margined": true }, - { "id": 74, "product": "Vanilla IRS", "tradeDate": "2015-06-02", "effectiveDate": "2016-05-07", "maturityDate": "2016-06-14", "currency": "EUR", "notional": 661543, "IM": 744609, "MTM": 101296, "margined": true }, - { "id": 75, "product": "Vanilla IRS", "tradeDate": "2015-02-19", "effectiveDate": "2016-03-19", "maturityDate": "2016-01-02", "currency": "EUR", "notional": 346826, "IM": 946055, "MTM": 174511, "margined": true }, - { "id": 76, "product": "Vanilla IRS", "tradeDate": "2016-04-01", "effectiveDate": "2015-05-14", "maturityDate": "2015-01-28", "currency": "EUR", "notional": 757444, "IM": 658801, "MTM": 116593, "margined": true }, - { "id": 77, "product": "Vanilla IRS", "tradeDate": "2015-01-08", "effectiveDate": "2016-08-01", "maturityDate": "2015-11-23", "currency": "EUR", "notional": 898786, "IM": 934450, "MTM": 289189, "margined": true }, - { "id": 78, "product": "Vanilla IRS", "tradeDate": "2015-05-12", "effectiveDate": "2015-01-24", "maturityDate": "2015-02-13", "currency": "EUR", "notional": 933987, "IM": 800231, "MTM": 611516, "margined": true }, - { "id": 79, "product": "Vanilla IRS", "tradeDate": "2016-04-25", "effectiveDate": "2015-12-19", "maturityDate": "2015-01-14", "currency": "EUR", "notional": 224700, "IM": 647032, "MTM": 241266, "margined": true }, - { "id": 80, "product": "Vanilla IRS", "tradeDate": "2016-07-22", "effectiveDate": "2016-02-07", "maturityDate": "2016-01-21", "currency": "EUR", "notional": 387451, "IM": 899733, "MTM": 952651, "margined": true }, - { "id": 81, "product": "Vanilla IRS", "tradeDate": "2016-03-31", "effectiveDate": "2015-11-15", "maturityDate": "2016-05-31", "currency": "EUR", "notional": 217045, "IM": 854232, "MTM": 908217, "margined": true }, - { "id": 82, "product": "Vanilla IRS", "tradeDate": "2015-02-01", "effectiveDate": "2015-07-19", "maturityDate": "2015-11-07", "currency": "EUR", "notional": 685897, "IM": 969476, "MTM": 585324, "margined": true }, - { "id": 83, "product": "Vanilla IRS", "tradeDate": "2015-05-18", "effectiveDate": "2016-04-17", "maturityDate": "2016-03-23", "currency": "EUR", "notional": 251978, "IM": 912297, "MTM": 866737, "margined": true }, - { "id": 84, "product": "Vanilla IRS", "tradeDate": "2016-02-01", "effectiveDate": "2015-08-09", "maturityDate": "2015-02-18", "currency": "EUR", "notional": 636547, "IM": 527708, "MTM": 226993, "margined": true }, - { "id": 85, "product": "Vanilla IRS", "tradeDate": "2016-04-01", "effectiveDate": "2015-12-10", "maturityDate": "2015-07-26", "currency": "EUR", "notional": 486196, "IM": 389526, "MTM": 929739, "margined": true }, - { "id": 86, "product": "Vanilla IRS", "tradeDate": "2015-01-28", "effectiveDate": "2016-03-04", "maturityDate": "2015-06-22", "currency": "EUR", "notional": 235919, "IM": 496494, "MTM": 441327, "margined": true }, - { "id": 87, "product": "Vanilla IRS", "tradeDate": "2016-04-22", "effectiveDate": "2015-04-06", "maturityDate": "2015-04-18", "currency": "EUR", "notional": 786225, "IM": 722842, "MTM": 230096, "margined": true }, - { "id": 88, "product": "Vanilla IRS", "tradeDate": "2016-04-28", "effectiveDate": "2016-05-11", "maturityDate": "2015-09-17", "currency": "EUR", "notional": 552619, "IM": 974468, "MTM": 629125, "margined": true }, - { "id": 89, "product": "Vanilla IRS", "tradeDate": "2015-06-21", "effectiveDate": "2016-06-08", "maturityDate": "2015-10-22", "currency": "EUR", "notional": 560361, "IM": 111221, "MTM": 915744, "margined": true }, - { "id": 90, "product": "Vanilla IRS", "tradeDate": "2015-09-22", "effectiveDate": "2016-05-02", "maturityDate": "2015-03-23", "currency": "EUR", "notional": 810742, "IM": 130153, "MTM": 147710, "margined": true }, - { "id": 91, "product": "Vanilla IRS", "tradeDate": "2015-11-27", "effectiveDate": "2015-02-22", "maturityDate": "2015-11-30", "currency": "EUR", "notional": 587393, "IM": 767297, "MTM": 606429, "margined": true }, - { "id": 92, "product": "Vanilla IRS", "tradeDate": "2016-03-02", "effectiveDate": "2015-07-26", "maturityDate": "2016-06-21", "currency": "EUR", "notional": 514336, "IM": 516141, "MTM": 760234, "margined": true }, - { "id": 93, "product": "Vanilla IRS", "tradeDate": "2015-12-21", "effectiveDate": "2015-08-14", "maturityDate": "2015-03-08", "currency": "EUR", "notional": 590518, "IM": 333868, "MTM": 560569, "margined": true }, - { "id": 94, "product": "Vanilla IRS", "tradeDate": "2015-07-11", "effectiveDate": "2015-01-20", "maturityDate": "2016-02-10", "currency": "EUR", "notional": 987847, "IM": 562739, "MTM": 294382, "margined": true }, - { "id": 95, "product": "Vanilla IRS", "tradeDate": "2016-01-31", "effectiveDate": "2015-08-14", "maturityDate": "2015-12-16", "currency": "EUR", "notional": 966938, "IM": 221472, "MTM": 272958, "margined": true }, - { "id": 96, "product": "Vanilla IRS", "tradeDate": "2016-05-19", "effectiveDate": "2015-09-26", "maturityDate": "2016-06-04", "currency": "EUR", "notional": 759071, "IM": 698888, "MTM": 532787, "margined": true }, - { "id": 97, "product": "Vanilla IRS", "tradeDate": "2015-06-26", "effectiveDate": "2016-06-21", "maturityDate": "2016-03-27", "currency": "EUR", "notional": 935679, "IM": 843537, "MTM": 642175, "margined": true }, - { "id": 98, "product": "Vanilla IRS", "tradeDate": "2016-03-16", "effectiveDate": "2015-02-01", "maturityDate": "2015-12-18", "currency": "EUR", "notional": 806869, "IM": 484674, "MTM": 922438, "margined": true }, - { "id": 99, "product": "Vanilla IRS", "tradeDate": "2016-07-31", "effectiveDate": "2015-06-26", "maturityDate": "2015-12-21", "currency": "EUR", "notional": 408572, "IM": 190131, "MTM": 853413, "margined": true }, - { "id": 100, "product": "Vanilla IRS", "tradeDate": "2016-06-09", "effectiveDate": "2016-06-05", "maturityDate": "2015-01-22", "currency": "EUR", "notional": 412238, "IM": 984470, "MTM": 985533, "margined": true }, - { "id": 101, "product": "Vanilla IRS", "tradeDate": "2016-08-01", "effectiveDate": "2016-03-23", "maturityDate": "2016-01-07", "currency": "EUR", "notional": 546072, "IM": 315970, "MTM": 349503, "margined": true }, - { "id": 102, "product": "Vanilla IRS", "tradeDate": "2015-10-05", "effectiveDate": "2015-05-18", "maturityDate": "2015-05-02", "currency": "EUR", "notional": 214745, "IM": 986582, "MTM": 601064, "margined": true }, - { "id": 103, "product": "Vanilla IRS", "tradeDate": "2015-09-30", "effectiveDate": "2015-11-17", "maturityDate": "2016-05-09", "currency": "EUR", "notional": 700660, "IM": 482203, "MTM": 642691, "margined": true }, - { "id": 104, "product": "Vanilla IRS", "tradeDate": "2015-06-28", "effectiveDate": "2015-09-19", "maturityDate": "2015-05-01", "currency": "EUR", "notional": 310164, "IM": 279695, "MTM": 101184, "margined": true }, - { "id": 105, "product": "Vanilla IRS", "tradeDate": "2015-05-11", "effectiveDate": "2015-05-27", "maturityDate": "2015-11-11", "currency": "EUR", "notional": 136152, "IM": 499598, "MTM": 475848, "margined": true }, - { "id": 106, "product": "Vanilla IRS", "tradeDate": "2015-01-04", "effectiveDate": "2016-04-28", "maturityDate": "2016-01-28", "currency": "EUR", "notional": 400091, "IM": 391025, "MTM": 695634, "margined": true }, - { "id": 107, "product": "Vanilla IRS", "tradeDate": "2015-08-16", "effectiveDate": "2015-10-15", "maturityDate": "2016-05-14", "currency": "EUR", "notional": 309938, "IM": 910954, "MTM": 172185, "margined": true }, - { "id": 108, "product": "Vanilla IRS", "tradeDate": "2015-04-27", "effectiveDate": "2016-04-22", "maturityDate": "2015-12-08", "currency": "EUR", "notional": 297996, "IM": 537206, "MTM": 862323, "margined": true }, - { "id": 109, "product": "Vanilla IRS", "tradeDate": "2016-01-10", "effectiveDate": "2016-05-22", "maturityDate": "2015-10-19", "currency": "EUR", "notional": 249748, "IM": 194151, "MTM": 519673, "margined": true }, - { "id": 110, "product": "Vanilla IRS", "tradeDate": "2015-09-26", "effectiveDate": "2015-06-07", "maturityDate": "2015-11-19", "currency": "EUR", "notional": 561282, "IM": 826315, "MTM": 198056, "margined": true }, - { "id": 111, "product": "Vanilla IRS", "tradeDate": "2015-02-04", "effectiveDate": "2015-09-11", "maturityDate": "2015-06-24", "currency": "EUR", "notional": 448493, "IM": 245577, "MTM": 913277, "margined": true }, - { "id": 112, "product": "Vanilla IRS", "tradeDate": "2015-06-08", "effectiveDate": "2016-02-18", "maturityDate": "2016-02-07", "currency": "EUR", "notional": 615203, "IM": 328146, "MTM": 135685, "margined": true }, - { "id": 113, "product": "Vanilla IRS", "tradeDate": "2016-05-07", "effectiveDate": "2015-10-14", "maturityDate": "2016-02-27", "currency": "EUR", "notional": 620023, "IM": 699913, "MTM": 415927, "margined": true }, - { "id": 114, "product": "Vanilla IRS", "tradeDate": "2015-08-26", "effectiveDate": "2015-12-19", "maturityDate": "2016-04-03", "currency": "EUR", "notional": 340478, "IM": 402913, "MTM": 562916, "margined": true }, - { "id": 115, "product": "Vanilla IRS", "tradeDate": "2015-10-02", "effectiveDate": "2015-03-20", "maturityDate": "2016-02-12", "currency": "EUR", "notional": 892882, "IM": 850747, "MTM": 850541, "margined": true }, - { "id": 116, "product": "Vanilla IRS", "tradeDate": "2015-08-04", "effectiveDate": "2015-11-07", "maturityDate": "2015-04-10", "currency": "EUR", "notional": 794859, "IM": 698272, "MTM": 955492, "margined": true }, - { "id": 117, "product": "Vanilla IRS", "tradeDate": "2015-03-12", "effectiveDate": "2015-10-01", "maturityDate": "2016-04-06", "currency": "EUR", "notional": 600549, "IM": 851640, "MTM": 385577, "margined": true }, - { "id": 118, "product": "Vanilla IRS", "tradeDate": "2015-08-30", "effectiveDate": "2015-03-28", "maturityDate": "2015-10-26", "currency": "EUR", "notional": 826873, "IM": 741611, "MTM": 884304, "margined": true }, - { "id": 119, "product": "Vanilla IRS", "tradeDate": "2016-07-05", "effectiveDate": "2016-07-11", "maturityDate": "2015-12-06", "currency": "EUR", "notional": 979330, "IM": 937091, "MTM": 875872, "margined": true }, - { "id": 120, "product": "Vanilla IRS", "tradeDate": "2016-04-30", "effectiveDate": "2015-06-13", "maturityDate": "2015-06-11", "currency": "EUR", "notional": 239697, "IM": 357071, "MTM": 251466, "margined": true }, - { "id": 121, "product": "Vanilla IRS", "tradeDate": "2015-12-12", "effectiveDate": "2015-09-22", "maturityDate": "2015-08-08", "currency": "EUR", "notional": 722074, "IM": 901989, "MTM": 289056, "margined": true }, - { "id": 122, "product": "Vanilla IRS", "tradeDate": "2015-06-25", "effectiveDate": "2015-01-21", "maturityDate": "2016-01-03", "currency": "EUR", "notional": 500608, "IM": 482342, "MTM": 846734, "margined": true }, - { "id": 123, "product": "Vanilla IRS", "tradeDate": "2015-04-01", "effectiveDate": "2015-05-28", "maturityDate": "2015-12-05", "currency": "EUR", "notional": 651599, "IM": 583475, "MTM": 327991, "margined": true }, - { "id": 124, "product": "Vanilla IRS", "tradeDate": "2016-06-27", "effectiveDate": "2015-04-20", "maturityDate": "2015-03-05", "currency": "EUR", "notional": 215841, "IM": 410855, "MTM": 366544, "margined": true }, - { "id": 125, "product": "Vanilla IRS", "tradeDate": "2016-03-25", "effectiveDate": "2015-01-02", "maturityDate": "2015-01-10", "currency": "EUR", "notional": 716527, "IM": 883155, "MTM": 220571, "margined": true }, - { "id": 126, "product": "Vanilla IRS", "tradeDate": "2015-05-14", "effectiveDate": "2015-12-09", "maturityDate": "2015-09-14", "currency": "EUR", "notional": 105418, "IM": 574622, "MTM": 143564, "margined": true }, - { "id": 127, "product": "Vanilla IRS", "tradeDate": "2015-05-06", "effectiveDate": "2016-04-16", "maturityDate": "2016-02-23", "currency": "EUR", "notional": 116009, "IM": 967616, "MTM": 535563, "margined": true }, - { "id": 128, "product": "Vanilla IRS", "tradeDate": "2016-04-14", "effectiveDate": "2015-05-04", "maturityDate": "2016-05-05", "currency": "EUR", "notional": 540968, "IM": 364140, "MTM": 975653, "margined": true }, - { "id": 129, "product": "Vanilla IRS", "tradeDate": "2016-04-14", "effectiveDate": "2015-08-13", "maturityDate": "2015-11-24", "currency": "EUR", "notional": 411104, "IM": 253857, "MTM": 720853, "margined": true }, - { "id": 130, "product": "Vanilla IRS", "tradeDate": "2016-04-09", "effectiveDate": "2016-01-18", "maturityDate": "2015-08-09", "currency": "EUR", "notional": 583399, "IM": 412118, "MTM": 427745, "margined": true }, - { "id": 131, "product": "Vanilla IRS", "tradeDate": "2015-03-24", "effectiveDate": "2015-07-11", "maturityDate": "2016-03-05", "currency": "EUR", "notional": 889992, "IM": 824272, "MTM": 261164, "margined": true }, - { "id": 132, "product": "Vanilla IRS", "tradeDate": "2015-01-09", "effectiveDate": "2015-11-07", "maturityDate": "2016-06-18", "currency": "EUR", "notional": 496400, "IM": 958631, "MTM": 551478, "margined": true }, - { "id": 133, "product": "Vanilla IRS", "tradeDate": "2015-07-02", "effectiveDate": "2016-08-10", "maturityDate": "2015-04-21", "currency": "EUR", "notional": 261882, "IM": 591246, "MTM": 418401, "margined": true }, - { "id": 134, "product": "Vanilla IRS", "tradeDate": "2016-01-28", "effectiveDate": "2015-04-05", "maturityDate": "2016-04-08", "currency": "EUR", "notional": 802889, "IM": 677586, "MTM": 284210, "margined": true }, - { "id": 135, "product": "Vanilla IRS", "tradeDate": "2015-10-02", "effectiveDate": "2015-05-19", "maturityDate": "2015-12-10", "currency": "EUR", "notional": 740101, "IM": 663650, "MTM": 434636, "margined": true }, - { "id": 136, "product": "Vanilla IRS", "tradeDate": "2015-09-05", "effectiveDate": "2016-07-19", "maturityDate": "2015-01-05", "currency": "EUR", "notional": 733243, "IM": 587233, "MTM": 598627, "margined": true }, - { "id": 137, "product": "Vanilla IRS", "tradeDate": "2016-06-25", "effectiveDate": "2016-01-20", "maturityDate": "2015-03-11", "currency": "EUR", "notional": 418294, "IM": 629891, "MTM": 536725, "margined": true }, - { "id": 138, "product": "Vanilla IRS", "tradeDate": "2016-01-22", "effectiveDate": "2015-12-14", "maturityDate": "2015-01-05", "currency": "EUR", "notional": 518410, "IM": 708590, "MTM": 166919, "margined": true }, - { "id": 139, "product": "Vanilla IRS", "tradeDate": "2015-07-16", "effectiveDate": "2016-06-10", "maturityDate": "2016-04-19", "currency": "EUR", "notional": 457485, "IM": 897172, "MTM": 315665, "margined": true }, - { "id": 140, "product": "Vanilla IRS", "tradeDate": "2015-01-13", "effectiveDate": "2015-11-24", "maturityDate": "2016-01-04", "currency": "EUR", "notional": 667083, "IM": 498684, "MTM": 246029, "margined": true }, - { "id": 141, "product": "Vanilla IRS", "tradeDate": "2015-01-15", "effectiveDate": "2015-09-15", "maturityDate": "2016-01-10", "currency": "EUR", "notional": 429600, "IM": 961982, "MTM": 158419, "margined": true }, - { "id": 142, "product": "Vanilla IRS", "tradeDate": "2016-02-06", "effectiveDate": "2016-06-21", "maturityDate": "2015-01-10", "currency": "EUR", "notional": 457053, "IM": 964223, "MTM": 342736, "margined": true }, - { "id": 143, "product": "Vanilla IRS", "tradeDate": "2015-04-08", "effectiveDate": "2015-06-02", "maturityDate": "2015-09-11", "currency": "EUR", "notional": 494190, "IM": 909598, "MTM": 639050, "margined": true }, - { "id": 144, "product": "Vanilla IRS", "tradeDate": "2016-01-22", "effectiveDate": "2015-04-05", "maturityDate": "2015-11-23", "currency": "EUR", "notional": 591175, "IM": 436518, "MTM": 553257, "margined": true }, - { "id": 145, "product": "Vanilla IRS", "tradeDate": "2016-01-04", "effectiveDate": "2015-06-25", "maturityDate": "2016-05-10", "currency": "EUR", "notional": 587997, "IM": 818296, "MTM": 330833, "margined": true }, - { "id": 146, "product": "Vanilla IRS", "tradeDate": "2015-09-21", "effectiveDate": "2016-07-01", "maturityDate": "2015-08-07", "currency": "EUR", "notional": 738341, "IM": 692334, "MTM": 535245, "margined": true }, - { "id": 147, "product": "Vanilla IRS", "tradeDate": "2016-03-08", "effectiveDate": "2015-03-29", "maturityDate": "2016-02-09", "currency": "EUR", "notional": 533964, "IM": 928866, "MTM": 251161, "margined": true }, - { "id": 148, "product": "Vanilla IRS", "tradeDate": "2015-11-27", "effectiveDate": "2015-05-22", "maturityDate": "2016-05-11", "currency": "EUR", "notional": 429256, "IM": 124353, "MTM": 615337, "margined": true }, - { "id": 149, "product": "Vanilla IRS", "tradeDate": "2015-06-10", "effectiveDate": "2015-04-30", "maturityDate": "2016-04-04", "currency": "EUR", "notional": 492814, "IM": 358759, "MTM": 328220, "margined": true }, - { "id": 150, "product": "Vanilla IRS", "tradeDate": "2015-11-05", "effectiveDate": "2015-01-14", "maturityDate": "2015-04-14", "currency": "EUR", "notional": 458195, "IM": 673661, "MTM": 102822, "margined": true }, - { "id": 151, "product": "Vanilla IRS", "tradeDate": "2016-03-09", "effectiveDate": "2015-05-30", "maturityDate": "2015-07-15", "currency": "EUR", "notional": 799377, "IM": 321548, "MTM": 170088, "margined": true }, - { "id": 152, "product": "Vanilla IRS", "tradeDate": "2015-06-14", "effectiveDate": "2015-08-08", "maturityDate": "2015-11-19", "currency": "EUR", "notional": 560486, "IM": 909576, "MTM": 526008, "margined": true }, - { "id": 153, "product": "Vanilla IRS", "tradeDate": "2016-03-10", "effectiveDate": "2016-02-24", "maturityDate": "2016-06-29", "currency": "EUR", "notional": 554001, "IM": 677908, "MTM": 792632, "margined": true }, - { "id": 154, "product": "Vanilla IRS", "tradeDate": "2015-06-23", "effectiveDate": "2016-03-29", "maturityDate": "2015-02-25", "currency": "EUR", "notional": 488226, "IM": 830617, "MTM": 229793, "margined": true }, - { "id": 155, "product": "Vanilla IRS", "tradeDate": "2015-11-10", "effectiveDate": "2015-08-25", "maturityDate": "2015-06-17", "currency": "EUR", "notional": 956292, "IM": 592106, "MTM": 470188, "margined": true }, - { "id": 156, "product": "Vanilla IRS", "tradeDate": "2015-10-10", "effectiveDate": "2015-03-09", "maturityDate": "2015-02-20", "currency": "EUR", "notional": 675850, "IM": 618180, "MTM": 720764, "margined": true }, - { "id": 157, "product": "Vanilla IRS", "tradeDate": "2015-01-16", "effectiveDate": "2015-10-04", "maturityDate": "2016-07-14", "currency": "EUR", "notional": 928714, "IM": 822216, "MTM": 708302, "margined": true }, - { "id": 158, "product": "Vanilla IRS", "tradeDate": "2015-05-22", "effectiveDate": "2015-04-05", "maturityDate": "2016-05-28", "currency": "EUR", "notional": 372239, "IM": 504115, "MTM": 372251, "margined": true }, - { "id": 159, "product": "Vanilla IRS", "tradeDate": "2015-08-26", "effectiveDate": "2016-04-06", "maturityDate": "2016-01-27", "currency": "EUR", "notional": 961430, "IM": 262052, "MTM": 341645, "margined": true }, - { "id": 160, "product": "Vanilla IRS", "tradeDate": "2016-07-03", "effectiveDate": "2015-02-08", "maturityDate": "2015-04-07", "currency": "EUR", "notional": 647189, "IM": 249492, "MTM": 909632, "margined": true }, - { "id": 161, "product": "Vanilla IRS", "tradeDate": "2015-05-27", "effectiveDate": "2016-03-25", "maturityDate": "2015-10-26", "currency": "EUR", "notional": 408599, "IM": 611120, "MTM": 208086, "margined": true }, - { "id": 162, "product": "Vanilla IRS", "tradeDate": "2015-10-29", "effectiveDate": "2016-02-26", "maturityDate": "2016-05-01", "currency": "EUR", "notional": 311743, "IM": 862977, "MTM": 146733, "margined": true }, - { "id": 163, "product": "Vanilla IRS", "tradeDate": "2015-10-27", "effectiveDate": "2015-06-04", "maturityDate": "2016-02-03", "currency": "EUR", "notional": 856835, "IM": 773924, "MTM": 432452, "margined": true }, - { "id": 164, "product": "Vanilla IRS", "tradeDate": "2015-03-22", "effectiveDate": "2015-08-29", "maturityDate": "2015-02-13", "currency": "EUR", "notional": 383925, "IM": 575637, "MTM": 152902, "margined": true }, - { "id": 165, "product": "Vanilla IRS", "tradeDate": "2016-06-09", "effectiveDate": "2016-05-29", "maturityDate": "2015-07-29", "currency": "EUR", "notional": 105221, "IM": 229112, "MTM": 792243, "margined": true }, - { "id": 166, "product": "Vanilla IRS", "tradeDate": "2015-07-20", "effectiveDate": "2015-02-05", "maturityDate": "2015-08-03", "currency": "EUR", "notional": 878905, "IM": 596680, "MTM": 871082, "margined": true }, - { "id": 167, "product": "Vanilla IRS", "tradeDate": "2016-01-06", "effectiveDate": "2016-07-17", "maturityDate": "2015-12-13", "currency": "EUR", "notional": 726006, "IM": 804728, "MTM": 304741, "margined": true }, - { "id": 168, "product": "Vanilla IRS", "tradeDate": "2015-04-09", "effectiveDate": "2015-01-22", "maturityDate": "2016-01-21", "currency": "EUR", "notional": 255406, "IM": 220203, "MTM": 604974, "margined": true }, - { "id": 169, "product": "Vanilla IRS", "tradeDate": "2015-05-15", "effectiveDate": "2015-12-07", "maturityDate": "2015-02-24", "currency": "EUR", "notional": 304450, "IM": 557361, "MTM": 584761, "margined": true }, - { "id": 170, "product": "Vanilla IRS", "tradeDate": "2016-01-06", "effectiveDate": "2015-08-03", "maturityDate": "2016-06-02", "currency": "EUR", "notional": 100616, "IM": 893556, "MTM": 743254, "margined": true }, - { "id": 171, "product": "Vanilla IRS", "tradeDate": "2015-07-21", "effectiveDate": "2015-02-07", "maturityDate": "2015-11-25", "currency": "EUR", "notional": 345686, "IM": 873977, "MTM": 333411, "margined": true }, - { "id": 172, "product": "Vanilla IRS", "tradeDate": "2015-10-24", "effectiveDate": "2015-01-03", "maturityDate": "2016-01-03", "currency": "EUR", "notional": 836105, "IM": 767815, "MTM": 935004, "margined": true }, - { "id": 173, "product": "Vanilla IRS", "tradeDate": "2015-09-18", "effectiveDate": "2015-04-03", "maturityDate": "2015-09-02", "currency": "EUR", "notional": 661662, "IM": 708441, "MTM": 456366, "margined": true }, - { "id": 174, "product": "Vanilla IRS", "tradeDate": "2015-08-06", "effectiveDate": "2016-06-10", "maturityDate": "2015-10-31", "currency": "EUR", "notional": 157353, "IM": 766286, "MTM": 730801, "margined": true }, - { "id": 175, "product": "Vanilla IRS", "tradeDate": "2016-06-13", "effectiveDate": "2016-04-16", "maturityDate": "2016-07-19", "currency": "EUR", "notional": 839059, "IM": 190749, "MTM": 808524, "margined": true }, - { "id": 176, "product": "Vanilla IRS", "tradeDate": "2016-01-11", "effectiveDate": "2015-06-04", "maturityDate": "2016-04-13", "currency": "EUR", "notional": 789202, "IM": 594706, "MTM": 567356, "margined": true }, - { "id": 177, "product": "Vanilla IRS", "tradeDate": "2015-08-25", "effectiveDate": "2016-05-19", "maturityDate": "2016-01-31", "currency": "EUR", "notional": 379031, "IM": 904713, "MTM": 450396, "margined": true }, - { "id": 178, "product": "Vanilla IRS", "tradeDate": "2015-06-25", "effectiveDate": "2015-06-03", "maturityDate": "2015-04-12", "currency": "EUR", "notional": 940060, "IM": 287058, "MTM": 880702, "margined": true }, - { "id": 179, "product": "Vanilla IRS", "tradeDate": "2015-09-27", "effectiveDate": "2015-11-16", "maturityDate": "2015-07-12", "currency": "EUR", "notional": 670492, "IM": 657712, "MTM": 167421, "margined": true }, - { "id": 180, "product": "Vanilla IRS", "tradeDate": "2015-06-25", "effectiveDate": "2015-09-09", "maturityDate": "2015-07-26", "currency": "EUR", "notional": 174007, "IM": 401349, "MTM": 450600, "margined": true }, - { "id": 181, "product": "Vanilla IRS", "tradeDate": "2015-04-03", "effectiveDate": "2016-03-07", "maturityDate": "2016-07-31", "currency": "EUR", "notional": 186725, "IM": 526345, "MTM": 452121, "margined": true }, - { "id": 182, "product": "Vanilla IRS", "tradeDate": "2016-03-22", "effectiveDate": "2016-02-21", "maturityDate": "2015-09-23", "currency": "EUR", "notional": 188751, "IM": 869079, "MTM": 822196, "margined": true }, - { "id": 183, "product": "Vanilla IRS", "tradeDate": "2016-04-26", "effectiveDate": "2015-12-01", "maturityDate": "2016-06-07", "currency": "EUR", "notional": 973098, "IM": 473726, "MTM": 177995, "margined": true }, - { "id": 184, "product": "Vanilla IRS", "tradeDate": "2015-10-21", "effectiveDate": "2015-09-07", "maturityDate": "2015-05-04", "currency": "EUR", "notional": 400072, "IM": 911641, "MTM": 493517, "margined": true }, - { "id": 185, "product": "Vanilla IRS", "tradeDate": "2015-06-03", "effectiveDate": "2016-04-16", "maturityDate": "2016-02-13", "currency": "EUR", "notional": 564387, "IM": 536191, "MTM": 615698, "margined": true }, - { "id": 186, "product": "Vanilla IRS", "tradeDate": "2015-05-31", "effectiveDate": "2016-04-17", "maturityDate": "2016-02-11", "currency": "EUR", "notional": 953502, "IM": 779813, "MTM": 418724, "margined": true }, - { "id": 187, "product": "Vanilla IRS", "tradeDate": "2015-01-15", "effectiveDate": "2016-02-01", "maturityDate": "2015-11-27", "currency": "EUR", "notional": 268569, "IM": 820702, "MTM": 142024, "margined": true }, - { "id": 188, "product": "Vanilla IRS", "tradeDate": "2015-05-27", "effectiveDate": "2016-06-12", "maturityDate": "2016-02-05", "currency": "EUR", "notional": 576125, "IM": 503024, "MTM": 822738, "margined": true }, - { "id": 189, "product": "Vanilla IRS", "tradeDate": "2015-07-26", "effectiveDate": "2016-01-09", "maturityDate": "2015-03-27", "currency": "EUR", "notional": 634085, "IM": 310451, "MTM": 534049, "margined": true }, - { "id": 190, "product": "Vanilla IRS", "tradeDate": "2016-07-02", "effectiveDate": "2015-12-02", "maturityDate": "2016-02-22", "currency": "EUR", "notional": 566206, "IM": 595796, "MTM": 934467, "margined": true }, - { "id": 191, "product": "Vanilla IRS", "tradeDate": "2016-03-09", "effectiveDate": "2015-10-12", "maturityDate": "2016-04-09", "currency": "EUR", "notional": 416499, "IM": 325436, "MTM": 382781, "margined": true }, - { "id": 192, "product": "Vanilla IRS", "tradeDate": "2015-12-25", "effectiveDate": "2016-06-25", "maturityDate": "2016-07-06", "currency": "EUR", "notional": 930796, "IM": 213404, "MTM": 607939, "margined": true }, - { "id": 193, "product": "Vanilla IRS", "tradeDate": "2015-07-30", "effectiveDate": "2015-07-30", "maturityDate": "2015-08-11", "currency": "EUR", "notional": 902350, "IM": 981277, "MTM": 190211, "margined": true }, - { "id": 194, "product": "Vanilla IRS", "tradeDate": "2015-07-20", "effectiveDate": "2015-01-18", "maturityDate": "2015-01-26", "currency": "EUR", "notional": 382296, "IM": 784039, "MTM": 328903, "margined": true }, - { "id": 195, "product": "Vanilla IRS", "tradeDate": "2015-12-23", "effectiveDate": "2015-09-01", "maturityDate": "2015-09-04", "currency": "EUR", "notional": 877076, "IM": 399413, "MTM": 462875, "margined": true }, - { "id": 196, "product": "Vanilla IRS", "tradeDate": "2016-07-05", "effectiveDate": "2016-07-10", "maturityDate": "2016-02-07", "currency": "EUR", "notional": 702100, "IM": 163429, "MTM": 430960, "margined": true }, - { "id": 197, "product": "Vanilla IRS", "tradeDate": "2015-03-01", "effectiveDate": "2016-01-31", "maturityDate": "2016-03-24", "currency": "EUR", "notional": 228779, "IM": 492958, "MTM": 594003, "margined": true }, - { "id": 198, "product": "Vanilla IRS", "tradeDate": "2015-10-21", "effectiveDate": "2015-01-23", "maturityDate": "2015-11-12", "currency": "EUR", "notional": 217611, "IM": 652240, "MTM": 891288, "margined": true }, - { "id": 199, "product": "Vanilla IRS", "tradeDate": "2015-01-29", "effectiveDate": "2015-04-14", "maturityDate": "2015-08-08", "currency": "EUR", "notional": 644597, "IM": 743391, "MTM": 674038, "margined": true }, - { "id": 200, "product": "Vanilla IRS", "tradeDate": "2016-04-14", "effectiveDate": "2016-05-19", "maturityDate": "2015-07-04", "currency": "EUR", "notional": 288472, "IM": 421471, "MTM": 210602, "margined": true }, - { "id": 201, "product": "Vanilla IRS", "tradeDate": "2015-05-01", "effectiveDate": "2015-05-26", "maturityDate": "2016-08-02", "currency": "EUR", "notional": 362318, "IM": 662997, "MTM": 626969, "margined": true }, - { "id": 202, "product": "Vanilla IRS", "tradeDate": "2016-03-03", "effectiveDate": "2015-10-13", "maturityDate": "2016-07-06", "currency": "EUR", "notional": 614133, "IM": 751660, "MTM": 179650, "margined": true }, - { "id": 203, "product": "Vanilla IRS", "tradeDate": "2015-07-29", "effectiveDate": "2016-01-25", "maturityDate": "2016-04-28", "currency": "EUR", "notional": 903244, "IM": 684572, "MTM": 224151, "margined": true }, - { "id": 204, "product": "Vanilla IRS", "tradeDate": "2016-03-30", "effectiveDate": "2015-02-04", "maturityDate": "2016-04-28", "currency": "EUR", "notional": 979598, "IM": 697549, "MTM": 131770, "margined": true }, - { "id": 205, "product": "Vanilla IRS", "tradeDate": "2015-11-12", "effectiveDate": "2015-10-11", "maturityDate": "2015-12-07", "currency": "EUR", "notional": 117017, "IM": 482465, "MTM": 737898, "margined": true }, - { "id": 206, "product": "Vanilla IRS", "tradeDate": "2016-05-30", "effectiveDate": "2016-06-02", "maturityDate": "2016-04-30", "currency": "EUR", "notional": 264434, "IM": 268979, "MTM": 712167, "margined": true }, - { "id": 207, "product": "Vanilla IRS", "tradeDate": "2016-06-20", "effectiveDate": "2015-05-03", "maturityDate": "2016-04-12", "currency": "EUR", "notional": 992026, "IM": 284356, "MTM": 757995, "margined": true }, - { "id": 208, "product": "Vanilla IRS", "tradeDate": "2016-06-22", "effectiveDate": "2015-12-15", "maturityDate": "2015-05-15", "currency": "EUR", "notional": 419746, "IM": 853922, "MTM": 710178, "margined": true }, - { "id": 209, "product": "Vanilla IRS", "tradeDate": "2015-10-04", "effectiveDate": "2015-08-13", "maturityDate": "2015-07-31", "currency": "EUR", "notional": 291125, "IM": 412472, "MTM": 372940, "margined": true }, - { "id": 210, "product": "Vanilla IRS", "tradeDate": "2015-11-29", "effectiveDate": "2016-08-02", "maturityDate": "2015-09-23", "currency": "EUR", "notional": 536194, "IM": 136809, "MTM": 281171, "margined": true }, - { "id": 211, "product": "Vanilla IRS", "tradeDate": "2015-10-21", "effectiveDate": "2016-07-12", "maturityDate": "2016-03-18", "currency": "EUR", "notional": 934223, "IM": 351034, "MTM": 487163, "margined": true }, - { "id": 212, "product": "Vanilla IRS", "tradeDate": "2015-12-25", "effectiveDate": "2016-05-16", "maturityDate": "2016-01-10", "currency": "EUR", "notional": 797492, "IM": 892800, "MTM": 787978, "margined": true }, - { "id": 213, "product": "Vanilla IRS", "tradeDate": "2015-06-11", "effectiveDate": "2015-10-11", "maturityDate": "2016-07-26", "currency": "EUR", "notional": 421248, "IM": 344354, "MTM": 661007, "margined": true }, - { "id": 214, "product": "Vanilla IRS", "tradeDate": "2015-08-23", "effectiveDate": "2016-01-03", "maturityDate": "2016-03-13", "currency": "EUR", "notional": 440343, "IM": 312837, "MTM": 821691, "margined": true }, - { "id": 215, "product": "Vanilla IRS", "tradeDate": "2015-07-18", "effectiveDate": "2016-01-20", "maturityDate": "2016-05-13", "currency": "EUR", "notional": 880098, "IM": 276209, "MTM": 899954, "margined": true }, - { "id": 216, "product": "Vanilla IRS", "tradeDate": "2015-01-11", "effectiveDate": "2016-06-02", "maturityDate": "2015-08-19", "currency": "EUR", "notional": 689688, "IM": 103759, "MTM": 235593, "margined": true }, - { "id": 217, "product": "Vanilla IRS", "tradeDate": "2015-08-05", "effectiveDate": "2015-09-22", "maturityDate": "2016-03-10", "currency": "EUR", "notional": 972199, "IM": 726960, "MTM": 737267, "margined": true }, - { "id": 218, "product": "Vanilla IRS", "tradeDate": "2015-09-11", "effectiveDate": "2016-04-09", "maturityDate": "2015-06-27", "currency": "EUR", "notional": 730809, "IM": 550555, "MTM": 333598, "margined": true }, - { "id": 219, "product": "Vanilla IRS", "tradeDate": "2015-01-19", "effectiveDate": "2015-01-02", "maturityDate": "2015-04-29", "currency": "EUR", "notional": 981261, "IM": 778630, "MTM": 867025, "margined": true }, - { "id": 220, "product": "Vanilla IRS", "tradeDate": "2016-06-09", "effectiveDate": "2016-06-21", "maturityDate": "2016-03-17", "currency": "EUR", "notional": 882725, "IM": 136682, "MTM": 958822, "margined": true }, - { "id": 221, "product": "Vanilla IRS", "tradeDate": "2015-07-31", "effectiveDate": "2015-04-07", "maturityDate": "2015-08-09", "currency": "EUR", "notional": 191589, "IM": 273161, "MTM": 146433, "margined": true }, - { "id": 222, "product": "Vanilla IRS", "tradeDate": "2016-07-17", "effectiveDate": "2016-05-14", "maturityDate": "2015-12-26", "currency": "EUR", "notional": 633076, "IM": 468565, "MTM": 455419, "margined": true }, - { "id": 223, "product": "Vanilla IRS", "tradeDate": "2015-01-19", "effectiveDate": "2015-12-12", "maturityDate": "2015-07-26", "currency": "EUR", "notional": 310134, "IM": 714847, "MTM": 704467, "margined": true }, - { "id": 224, "product": "Vanilla IRS", "tradeDate": "2016-01-25", "effectiveDate": "2015-11-15", "maturityDate": "2016-05-23", "currency": "EUR", "notional": 408632, "IM": 899069, "MTM": 574721, "margined": true }, - { "id": 225, "product": "Vanilla IRS", "tradeDate": "2015-10-05", "effectiveDate": "2015-06-05", "maturityDate": "2015-05-23", "currency": "EUR", "notional": 353649, "IM": 734570, "MTM": 105834, "margined": true }, - { "id": 226, "product": "Vanilla IRS", "tradeDate": "2016-03-02", "effectiveDate": "2015-11-13", "maturityDate": "2015-10-13", "currency": "EUR", "notional": 903567, "IM": 954087, "MTM": 415821, "margined": true }, - { "id": 227, "product": "Vanilla IRS", "tradeDate": "2015-10-14", "effectiveDate": "2016-02-27", "maturityDate": "2016-05-23", "currency": "EUR", "notional": 675864, "IM": 712992, "MTM": 195279, "margined": true }, - { "id": 228, "product": "Vanilla IRS", "tradeDate": "2015-11-29", "effectiveDate": "2015-11-30", "maturityDate": "2015-07-29", "currency": "EUR", "notional": 945431, "IM": 334813, "MTM": 137353, "margined": true }, - { "id": 229, "product": "Vanilla IRS", "tradeDate": "2016-07-23", "effectiveDate": "2016-02-19", "maturityDate": "2015-12-08", "currency": "EUR", "notional": 225714, "IM": 877507, "MTM": 652143, "margined": true }, - { "id": 230, "product": "Vanilla IRS", "tradeDate": "2015-09-26", "effectiveDate": "2015-08-24", "maturityDate": "2016-04-09", "currency": "EUR", "notional": 194343, "IM": 267164, "MTM": 195041, "margined": true }, - { "id": 231, "product": "Vanilla IRS", "tradeDate": "2015-10-02", "effectiveDate": "2015-05-14", "maturityDate": "2015-12-11", "currency": "EUR", "notional": 790346, "IM": 535420, "MTM": 945042, "margined": true }, - { "id": 232, "product": "Vanilla IRS", "tradeDate": "2015-04-08", "effectiveDate": "2015-09-19", "maturityDate": "2015-04-01", "currency": "EUR", "notional": 615677, "IM": 173929, "MTM": 294668, "margined": true }, - { "id": 233, "product": "Vanilla IRS", "tradeDate": "2015-12-10", "effectiveDate": "2015-06-29", "maturityDate": "2015-04-03", "currency": "EUR", "notional": 518644, "IM": 147326, "MTM": 377699, "margined": true }, - { "id": 234, "product": "Vanilla IRS", "tradeDate": "2016-04-15", "effectiveDate": "2015-03-07", "maturityDate": "2015-08-30", "currency": "EUR", "notional": 442264, "IM": 913861, "MTM": 896907, "margined": true }, - { "id": 235, "product": "Vanilla IRS", "tradeDate": "2015-12-27", "effectiveDate": "2016-06-14", "maturityDate": "2016-06-21", "currency": "EUR", "notional": 784365, "IM": 722225, "MTM": 817415, "margined": true }, - { "id": 236, "product": "Vanilla IRS", "tradeDate": "2015-04-16", "effectiveDate": "2015-04-07", "maturityDate": "2016-07-24", "currency": "EUR", "notional": 132956, "IM": 905856, "MTM": 275847, "margined": true }, - { "id": 237, "product": "Vanilla IRS", "tradeDate": "2015-11-17", "effectiveDate": "2015-05-27", "maturityDate": "2015-05-18", "currency": "EUR", "notional": 821311, "IM": 256587, "MTM": 314452, "margined": true }, - { "id": 238, "product": "Vanilla IRS", "tradeDate": "2015-07-29", "effectiveDate": "2016-07-15", "maturityDate": "2016-03-21", "currency": "EUR", "notional": 183992, "IM": 173355, "MTM": 419058, "margined": true }, - { "id": 239, "product": "Vanilla IRS", "tradeDate": "2015-09-23", "effectiveDate": "2015-05-16", "maturityDate": "2016-08-01", "currency": "EUR", "notional": 418216, "IM": 308428, "MTM": 943864, "margined": true }, - { "id": 240, "product": "Vanilla IRS", "tradeDate": "2015-03-03", "effectiveDate": "2015-08-18", "maturityDate": "2016-04-27", "currency": "EUR", "notional": 646306, "IM": 985232, "MTM": 401204, "margined": true }, - { "id": 241, "product": "Vanilla IRS", "tradeDate": "2015-06-05", "effectiveDate": "2015-06-17", "maturityDate": "2016-06-18", "currency": "EUR", "notional": 440467, "IM": 698885, "MTM": 588865, "margined": true }, - { "id": 242, "product": "Vanilla IRS", "tradeDate": "2015-02-12", "effectiveDate": "2016-02-03", "maturityDate": "2016-05-08", "currency": "EUR", "notional": 111369, "IM": 487792, "MTM": 592719, "margined": true }, - { "id": 243, "product": "Vanilla IRS", "tradeDate": "2015-02-09", "effectiveDate": "2016-03-02", "maturityDate": "2015-04-21", "currency": "EUR", "notional": 713984, "IM": 981192, "MTM": 743011, "margined": true }, - { "id": 244, "product": "Vanilla IRS", "tradeDate": "2015-04-06", "effectiveDate": "2016-04-02", "maturityDate": "2015-07-29", "currency": "EUR", "notional": 919287, "IM": 867388, "MTM": 293209, "margined": true }, - { "id": 245, "product": "Vanilla IRS", "tradeDate": "2015-07-16", "effectiveDate": "2015-12-09", "maturityDate": "2016-02-23", "currency": "EUR", "notional": 439397, "IM": 412975, "MTM": 971273, "margined": true }, - { "id": 246, "product": "Vanilla IRS", "tradeDate": "2015-01-05", "effectiveDate": "2015-03-12", "maturityDate": "2015-10-13", "currency": "EUR", "notional": 476150, "IM": 517482, "MTM": 401020, "margined": true }, - { "id": 247, "product": "Vanilla IRS", "tradeDate": "2015-10-02", "effectiveDate": "2015-07-01", "maturityDate": "2016-06-16", "currency": "EUR", "notional": 408434, "IM": 588103, "MTM": 159215, "margined": true }, - { "id": 248, "product": "Vanilla IRS", "tradeDate": "2015-05-09", "effectiveDate": "2015-11-17", "maturityDate": "2015-11-15", "currency": "EUR", "notional": 787899, "IM": 971975, "MTM": 352116, "margined": true }, - { "id": 249, "product": "Vanilla IRS", "tradeDate": "2016-04-28", "effectiveDate": "2015-11-15", "maturityDate": "2016-07-21", "currency": "EUR", "notional": 767073, "IM": 628497, "MTM": 650553, "margined": true }, - { "id": 250, "product": "Vanilla IRS", "tradeDate": "2016-03-04", "effectiveDate": "2016-10-19", "maturityDate": "2015-07-13", "currency": "EUR", "notional": 538953, "IM": null, "MTM": null, "margined": false } -] diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/whoami b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/whoami deleted file mode 100644 index a74aab7940..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/api/vega/whoami +++ /dev/null @@ -1,14 +0,0 @@ -{ - "self": { - "id": "r3bank", - "text": "R3 Bank" - }, - "counterparties": [{ - "id": "intesa", - "text": "Intesa" - }, - { - "id": "bank-c", - "text": "Bank C" - }] -} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js deleted file mode 100644 index da05a5de3c..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js +++ /dev/null @@ -1,101 +0,0 @@ -"use strict"; -var FixedLegModel_1 = require('./model/FixedLegModel'); -var FloatingLegModel_1 = require('./model/FloatingLegModel'); -var CommonModel_1 = require('./model/CommonModel'); -var _ = require('underscore'); -var calculationModel = { - expression: "( fixedLeg.notional.quantity * (fixedLeg.fixedRate.ratioUnit.value)) - (floatingLeg.notional.quantity * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))", - floatingLegPaymentSchedule: {}, - fixedLegPaymentSchedule: {} -}; -var fixedRateModel = { - ratioUnit: { - value: 0.01 // % - } -}; -var indexLookup = { - "GBP": "ICE LIBOR", - "USD": "ICE LIBOR", - "EUR": "EURIBOR" -}; -var calendarLookup = { - "GBP": "London", - "USD": "NewYork", - "EUR": "London" -}; -var now = function () { - return new Date(); -}; -// Copy the value of the field from b to a if it exists on both objects. -var unionMerge = function (a, b) { - for (var key in b) { - if (a.hasOwnProperty(key)) { - a[key] = b[key]; - } - } -}; -var Deal = (function () { - function Deal(dealViewModel, nodeService, irsService) { - var _this = this; - this.dealViewModel = dealViewModel; - this.nodeService = nodeService; - this.irsService = irsService; - this.tradeId = "T" + now().getUTCFullYear() + "-" + now().getUTCMonth() + "-" + now().getUTCDate() + "." + now().getUTCHours() + ":" + now().getUTCMinutes() + ":" + now().getUTCSeconds() + ":" + now().getUTCMilliseconds(); - this.toFixedLegModel = function (fixedLegVM, commonVM) { - var fixedLeg = new FixedLegModel_1.FixedLegModel(); - unionMerge(fixedLeg, fixedLegVM); - fixedLeg.notional.token = commonVM.baseCurrency; - fixedLeg.effectiveDate = commonVM.effectiveDate; - fixedLeg.terminationDate = commonVM.terminationDate; - fixedLeg.fixedRate = { ratioUnit: { value: Number(fixedLegVM.fixedRate) / 100 } }; - fixedLeg.dayCountBasisDay = _this.irsService.lookupDayCountBasis(fixedLegVM.dayCountBasis).day; - fixedLeg.dayCountBasisYear = _this.irsService.lookupDayCountBasis(fixedLegVM.dayCountBasis).year; - fixedLeg.paymentCalendar = calendarLookup[commonVM.baseCurrency]; - return fixedLeg; - }; - this.toFloatingLegModel = function (floatingLegVM, commonVM) { - var floatingLeg = new FloatingLegModel_1.FloatingLegModel(); - unionMerge(floatingLeg, floatingLegVM); - floatingLeg.notional.token = commonVM.baseCurrency; - floatingLeg.effectiveDate = commonVM.effectiveDate; - floatingLeg.terminationDate = commonVM.terminationDate; - floatingLeg.dayCountBasisDay = _this.irsService.lookupDayCountBasis(floatingLegVM.dayCountBasis).day; - floatingLeg.dayCountBasisYear = _this.irsService.lookupDayCountBasis(floatingLegVM.dayCountBasis).year; - floatingLeg.index = indexLookup[commonVM.baseCurrency]; - floatingLeg.fixingCalendar = [calendarLookup[commonVM.baseCurrency]]; - floatingLeg.paymentCalendar = [calendarLookup[commonVM.baseCurrency]]; - return floatingLeg; - }; - this.toCommonModel = function (commonVM) { - var common = new CommonModel_1.CommonModel(); - unionMerge(common, commonVM); - common.tradeID = _this.tradeId; - common.eligibleCurrency = commonVM.baseCurrency; - common.independentAmounts.token = commonVM.baseCurrency; - common.threshold.token = commonVM.baseCurrency; - common.minimumTransferAmount.token = commonVM.baseCurrency; - common.rounding.token = commonVM.baseCurrency; - return common; - }; - this.toJson = function () { - var commonVM = _this.dealViewModel.common; - var floatingLegVM = _this.dealViewModel.floatingLeg; - var fixedLegVM = _this.dealViewModel.fixedLeg; - var fixedLeg = _this.toFixedLegModel(fixedLegVM, commonVM); - var floatingLeg = _this.toFloatingLegModel(floatingLegVM, commonVM); - var common = _this.toCommonModel(commonVM); - _.assign(fixedLeg.fixedRate, fixedRateModel); - var json = { - fixedLeg: fixedLeg, - floatingLeg: floatingLeg, - calculation: calculationModel, - common: common - }; - return json; - }; - } - return Deal; -}()); -exports.Deal = Deal; -; -//# sourceMappingURL=Deal.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js.map deleted file mode 100644 index da51d02cc7..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/Deal.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"Deal.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/Deal.ts"],"names":[],"mappings":";AAGA,8BAA8B,uBAAuB,CAAC,CAAA;AACtD,iCAAiC,0BAA0B,CAAC,CAAA;AAC5D,4BAA4B,qBAAqB,CAAC,CAAA;AAIlD,IAAY,CAAC,WAAM,YAAY,CAAC,CAAA;AAEhC,IAAI,gBAAgB,GAAG;IACrB,UAAU,EAAE,gMAAgM;IAC5M,0BAA0B,EAAE,EAE3B;IACD,uBAAuB,EAAE,EAExB;CACF,CAAC;AAEF,IAAI,cAAc,GAAG;IACnB,SAAS,EAAE;QACT,KAAK,EAAE,IAAI,CAAC,IAAI;KACjB;CACF,CAAC;AAEF,IAAI,WAAW,GAAG;IAChB,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,WAAW;IAClB,KAAK,EAAE,SAAS;CACjB,CAAC;AAEF,IAAI,cAAc,GAAG;IACnB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,SAAS;IAChB,KAAK,EAAE,QAAQ;CAChB,CAAC;AAEF,IAAI,GAAG,GAAG;IACR,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;AACpB,CAAC,CAAA;AAED,wEAAwE;AACxE,IAAI,UAAU,GAAG,UAAC,CAAC,EAAE,CAAC;IACpB,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAC1B,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED;IAGE,cAAoB,aAA4B,EAAU,WAAwB,EAAU,UAAsB;QAHpH,iBAwEC;QArEqB,kBAAa,GAAb,aAAa,CAAe;QAAU,gBAAW,GAAX,WAAW,CAAa;QAAU,eAAU,GAAV,UAAU,CAAY;QAFlH,YAAO,GAAG,MAAI,GAAG,EAAE,CAAC,cAAc,EAAE,SAAI,GAAG,EAAE,CAAC,WAAW,EAAE,SAAI,GAAG,EAAE,CAAC,UAAU,EAAE,SAAI,GAAG,EAAE,CAAC,WAAW,EAAE,SAAI,GAAG,EAAE,CAAC,aAAa,EAAE,SAAI,GAAG,EAAE,CAAC,aAAa,EAAE,SAAI,GAAG,EAAE,CAAC,kBAAkB,EAAI,CAAA;QAI1L,oBAAe,GAAG,UAAC,UAA6B,EAAE,QAAyB;YACzE,IAAI,QAAQ,GAAG,IAAI,6BAAa,EAAE,CAAC;YAEnC,UAAU,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAEjC,QAAQ,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YAChD,QAAQ,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;YAChD,QAAQ,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;YACpD,QAAQ,CAAC,SAAS,GAAG,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC;YAClF,QAAQ,CAAC,gBAAgB,GAAG,KAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC;YAC9F,QAAQ,CAAC,iBAAiB,GAAG,KAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC;YAChG,QAAQ,CAAC,eAAe,GAAG,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YAEjE,MAAM,CAAC,QAAQ,CAAC;QAClB,CAAC,CAAC;QAEF,uBAAkB,GAAG,UAAC,aAAmC,EAAE,QAAyB;YAClF,IAAI,WAAW,GAAG,IAAI,mCAAgB,EAAE,CAAC;YAEzC,UAAU,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;YAEvC,WAAW,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YACnD,WAAW,CAAC,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC;YACnD,WAAW,CAAC,eAAe,GAAG,QAAQ,CAAC,eAAe,CAAC;YACvD,WAAW,CAAC,gBAAgB,GAAG,KAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,GAAG,CAAC;YACpG,WAAW,CAAC,iBAAiB,GAAG,KAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC;YACtG,WAAW,CAAC,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;YACvD,WAAW,CAAC,cAAc,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;YACrE,WAAW,CAAC,eAAe,GAAG,CAAC,cAAc,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;YAEtE,MAAM,CAAC,WAAW,CAAC;QACrB,CAAC,CAAC;QAEF,kBAAa,GAAG,UAAC,QAAyB;YACxC,IAAI,MAAM,GAAG,IAAI,yBAAW,EAAE,CAAC;YAE/B,UAAU,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAE7B,MAAM,CAAC,OAAO,GAAG,KAAI,CAAC,OAAO,CAAC;YAC9B,MAAM,CAAC,gBAAgB,GAAG,QAAQ,CAAC,YAAY,CAAC;YAChD,MAAM,CAAC,kBAAkB,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YACxD,MAAM,CAAC,SAAS,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YAC/C,MAAM,CAAC,qBAAqB,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YAC3D,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,QAAQ,CAAC,YAAY,CAAC;YAE9C,MAAM,CAAC,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,WAAM,GAAG;YACP,IAAI,QAAQ,GAAG,KAAI,CAAC,aAAa,CAAC,MAAM,CAAC;YACzC,IAAI,aAAa,GAAG,KAAI,CAAC,aAAa,CAAC,WAAW,CAAC;YACnD,IAAI,UAAU,GAAG,KAAI,CAAC,aAAa,CAAC,QAAQ,CAAC;YAE7C,IAAI,QAAQ,GAAG,KAAI,CAAC,eAAe,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;YAC1D,IAAI,WAAW,GAAG,KAAI,CAAC,kBAAkB,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;YACnE,IAAI,MAAM,GAAG,KAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;YAC1C,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAE7C,IAAI,IAAI,GAAG;gBACT,QAAQ,EAAE,QAAQ;gBAClB,WAAW,EAAE,WAAW;gBACxB,WAAW,EAAE,gBAAgB;gBAC7B,MAAM,EAAE,MAAM;aACf,CAAA;YAED,MAAM,CAAC,IAAI,CAAC;QACd,CAAC,CAAC;IApEmH,CAAC;IAqExH,WAAC;AAAD,CAAC,AAxED,IAwEC;AAxEY,YAAI,OAwEhB,CAAA;AAAA,CAAC","sourcesContent":["import { DealViewModel } from './viewmodel/DealViewModel';\nimport { NodeService } from './node.service';\nimport { IRSService } from './irs.service';\nimport { FixedLegModel } from './model/FixedLegModel';\nimport { FloatingLegModel } from './model/FloatingLegModel';\nimport { CommonModel } from './model/CommonModel';\nimport { FixedLegViewModel } from './viewmodel/FixedLegViewModel';\nimport { FloatingLegViewModel } from './viewmodel/FloatingLegViewModel';\nimport { CommonViewModel } from './viewmodel/CommonViewModel';\nimport * as _ from 'underscore';\n\nlet calculationModel = {\n expression: \"( fixedLeg.notional.quantity * (fixedLeg.fixedRate.ratioUnit.value)) - (floatingLeg.notional.quantity * (calculation.fixingSchedule.get(context.getDate('currentDate')).rate.ratioUnit.value))\",\n floatingLegPaymentSchedule: {\n\n },\n fixedLegPaymentSchedule: {\n\n }\n};\n\nlet fixedRateModel = {\n ratioUnit: {\n value: 0.01 // %\n }\n};\n\nlet indexLookup = {\n \"GBP\": \"ICE LIBOR\",\n \"USD\": \"ICE LIBOR\",\n \"EUR\": \"EURIBOR\"\n};\n\nlet calendarLookup = {\n \"GBP\": \"London\",\n \"USD\": \"NewYork\",\n \"EUR\": \"London\"\n};\n\nlet now = () => {\n return new Date();\n}\n\n// Copy the value of the field from b to a if it exists on both objects.\nlet unionMerge = (a, b) => {\n for (let key in b) {\n if (a.hasOwnProperty(key)) {\n a[key] = b[key];\n }\n }\n}\n\nexport class Deal {\n tradeId = `T${now().getUTCFullYear()}-${now().getUTCMonth()}-${now().getUTCDate()}.${now().getUTCHours()}:${now().getUTCMinutes()}:${now().getUTCSeconds()}:${now().getUTCMilliseconds()}`\n\n constructor(private dealViewModel: DealViewModel, private nodeService: NodeService, private irsService: IRSService) {}\n\n toFixedLegModel = (fixedLegVM: FixedLegViewModel, commonVM: CommonViewModel) => {\n let fixedLeg = new FixedLegModel();\n\n unionMerge(fixedLeg, fixedLegVM);\n\n fixedLeg.notional.token = commonVM.baseCurrency;\n fixedLeg.effectiveDate = commonVM.effectiveDate;\n fixedLeg.terminationDate = commonVM.terminationDate;\n fixedLeg.fixedRate = { ratioUnit: { value: Number(fixedLegVM.fixedRate) / 100 } };\n fixedLeg.dayCountBasisDay = this.irsService.lookupDayCountBasis(fixedLegVM.dayCountBasis).day;\n fixedLeg.dayCountBasisYear = this.irsService.lookupDayCountBasis(fixedLegVM.dayCountBasis).year;\n fixedLeg.paymentCalendar = calendarLookup[commonVM.baseCurrency];\n\n return fixedLeg;\n };\n\n toFloatingLegModel = (floatingLegVM: FloatingLegViewModel, commonVM: CommonViewModel) => {\n let floatingLeg = new FloatingLegModel();\n\n unionMerge(floatingLeg, floatingLegVM);\n\n floatingLeg.notional.token = commonVM.baseCurrency;\n floatingLeg.effectiveDate = commonVM.effectiveDate;\n floatingLeg.terminationDate = commonVM.terminationDate;\n floatingLeg.dayCountBasisDay = this.irsService.lookupDayCountBasis(floatingLegVM.dayCountBasis).day;\n floatingLeg.dayCountBasisYear = this.irsService.lookupDayCountBasis(floatingLegVM.dayCountBasis).year;\n floatingLeg.index = indexLookup[commonVM.baseCurrency];\n floatingLeg.fixingCalendar = [calendarLookup[commonVM.baseCurrency]];\n floatingLeg.paymentCalendar = [calendarLookup[commonVM.baseCurrency]];\n\n return floatingLeg;\n };\n\n toCommonModel = (commonVM: CommonViewModel) => {\n let common = new CommonModel();\n\n unionMerge(common, commonVM);\n\n common.tradeID = this.tradeId;\n common.eligibleCurrency = commonVM.baseCurrency;\n common.independentAmounts.token = commonVM.baseCurrency;\n common.threshold.token = commonVM.baseCurrency;\n common.minimumTransferAmount.token = commonVM.baseCurrency;\n common.rounding.token = commonVM.baseCurrency;\n\n return common;\n };\n\n toJson = () => {\n let commonVM = this.dealViewModel.common;\n let floatingLegVM = this.dealViewModel.floatingLeg;\n let fixedLegVM = this.dealViewModel.fixedLeg;\n\n let fixedLeg = this.toFixedLegModel(fixedLegVM, commonVM);\n let floatingLeg = this.toFloatingLegModel(floatingLegVM, commonVM);\n let common = this.toCommonModel(commonVM);\n _.assign(fixedLeg.fixedRate, fixedRateModel);\n\n let json = {\n fixedLeg: fixedLeg,\n floatingLeg: floatingLeg,\n calculation: calculationModel,\n common: common\n }\n\n return json;\n };\n};\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.css b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.css deleted file mode 100644 index e0d7911f27..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.css +++ /dev/null @@ -1,37 +0,0 @@ -/* demo only */ - -.r3-bank-demo-header * { - color: #ec1d24 !important; -} - - -/* end demo only */ - - -/* sticky footer */ - -html { - position: relative; - min-height: 100%; -} - -body { - /* Margin bottom by footer height */ - margin-bottom: 60px; -} - -.footer { - position: absolute; - bottom: 0; - width: 100%; - /* Set the fixed height of the footer here */ - height: 60px; - background-color: #f5f5f5; -} - -.container .text-muted { - margin: 20px 0; -} - - -/* end sticky footer */ diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.html deleted file mode 100644 index d5f771cb36..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.html +++ /dev/null @@ -1,50 +0,0 @@ - - -
-
-
-
-
- - -
-
-
- - -
-
- - -
- -
-
- -
-
-

Developed by the really cool people at OpenGamma, Intesa and R3

-
-
diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js deleted file mode 100644 index 228f606b8e..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js +++ /dev/null @@ -1,73 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var router_1 = require('@angular/router'); -var common_1 = require('@angular/common'); -var ng2_select_1 = require('ng2-select/ng2-select'); -var http_wrapper_service_1 = require('./http-wrapper.service'); -var AppComponent = (function () { - function AppComponent(httpWrapperService) { - this.httpWrapperService = httpWrapperService; - this.counterParties = []; - this.counterparty = null; - } - AppComponent.prototype.selected = function (value) { }; - ; - AppComponent.prototype.refreshValue = function (value) { - this.counterparty = this.httpWrapperService.setCounterparty(value.id); - }; - AppComponent.prototype.renderX500Name = function (x500Name) { - var name = x500Name; - x500Name.split(',').forEach(function (element) { - var keyValue = element.split('='); - if (keyValue[0].toUpperCase() == 'CN') { - name = keyValue[1]; - } - }); - return name; - }; - AppComponent.prototype.ngOnInit = function () { - var _this = this; - this.httpWrapperService.getAbsolute("whoami").toPromise().then(function (data) { - _this.whoAmI = _this.renderX500Name(data.self.text); - _this.counterParties = data.counterparties.map(function (x) { - return { - id: x.id, - text: this.renderX500Name(x.text) - }; - }); - if (_this.counterParties.length == 0) { - console.log("/whoami is returning no counterparties, the whole app won't run", data); - } - }).catch(function (error) { - console.log("Error loading who am i (this is really bad, the whole app will not work)", error); - }); - }; - AppComponent = __decorate([ - core_1.Component({ - moduleId: module.id, - selector: 'app-root', - templateUrl: 'app.component.html', - styleUrls: ['app.component.css', '../vendor/ng2-select/components/css/ng2-select.css'], - directives: [ - router_1.ROUTER_DIRECTIVES, - common_1.NgClass, - ng2_select_1.SELECT_DIRECTIVES - ], - encapsulation: core_1.ViewEncapsulation.None, - providers: [http_wrapper_service_1.HttpWrapperService] // don't declare in children, so that it's a "singleton" - }), - __metadata('design:paramtypes', [http_wrapper_service_1.HttpWrapperService]) - ], AppComponent); - return AppComponent; -}()); -exports.AppComponent = AppComponent; -//# sourceMappingURL=app.component.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js.map deleted file mode 100644 index ab4cbebd9e..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"app.component.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/app.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAA6C,eAAe,CAAC,CAAA;AAC7D,uBAAkC,iBAAiB,CAAC,CAAA;AACpD,uBAA+C,iBAAiB,CAAC,CAAA;AACjE,2BAAkC,uBAAuB,CAAC,CAAA;AAE1D,qCAAmC,wBAAwB,CAAC,CAAA;AAgB5D;IAEE,sBAAoB,kBAAsC;QAAtC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAInD,mBAAc,GAAkB,EAAE,CAAC;QAmBlC,iBAAY,GAAQ,IAAI,CAAC;IAvB4B,CAAC;IAMvD,+BAAQ,GAAf,UAAgB,KAAU,IAAS,CAAC;;IAE7B,mCAAY,GAAnB,UAAoB,KAAU;QAC5B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAEM,qCAAc,GAArB,UAAsB,QAAQ;QAC5B,IAAI,IAAI,GAAG,QAAQ,CAAC;QACpB,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,UAAU,OAAO;YACzC,IAAI,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,CAAC,CAAC;gBACpC,IAAI,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;YACvB,CAAC;QACL,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC;IACd,CAAC;IAID,+BAAQ,GAAR;QAAA,iBAeC;QAdC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;YAClE,KAAI,CAAC,MAAM,GAAG,KAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAClD,KAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,UAAU,CAAC;gBACrD,MAAM,CAAC;oBACH,EAAE,EAAE,CAAC,CAAC,EAAE;oBACR,IAAI,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC;iBACpC,CAAC;YACN,CAAC,CAAC,CAAC;YACH,EAAE,CAAC,CAAC,KAAI,CAAC,cAAc,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpC,OAAO,CAAC,GAAG,CAAC,iEAAiE,EAAE,IAAI,CAAC,CAAC;YACvF,CAAC;QACH,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACb,OAAO,CAAC,GAAG,CAAC,0EAA0E,EAAE,KAAK,CAAC,CAAC;QACjG,CAAC,CAAC,CAAC;IACL,CAAC;IAxDH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,UAAU;YACpB,WAAW,EAAE,oBAAoB;YACjC,SAAS,EAAE,CAAC,mBAAmB,EAAE,oDAAoD,CAAC;YACtF,UAAU,EAAE;gBACV,0BAAiB;gBACjB,gBAAO;gBACP,8BAAiB;aAClB;YACD,aAAa,EAAE,wBAAiB,CAAC,IAAI;YACrC,SAAS,EAAE,CAAC,yCAAkB,CAAC,CAAC,wDAAwD;SACzF,CAAC;;oBAAA;IA6CF,mBAAC;AAAD,CAAC,AA3CD,IA2CC;AA3CY,oBAAY,eA2CxB,CAAA","sourcesContent":["import { Component, ViewEncapsulation } from '@angular/core';\nimport { ROUTER_DIRECTIVES } from '@angular/router';\nimport { CORE_DIRECTIVES, NgClass, NgIf } from '@angular/common';\nimport { SELECT_DIRECTIVES } from 'ng2-select/ng2-select';\nimport * as moment from 'moment';\nimport { HttpWrapperService } from './http-wrapper.service';\n\n@Component({\n moduleId: module.id,\n selector: 'app-root',\n templateUrl: 'app.component.html',\n styleUrls: ['app.component.css', '../vendor/ng2-select/components/css/ng2-select.css'],\n directives: [\n ROUTER_DIRECTIVES,\n NgClass,\n SELECT_DIRECTIVES\n ],\n encapsulation: ViewEncapsulation.None, // allow external CSS\n providers: [HttpWrapperService] // don't declare in children, so that it's a \"singleton\"\n})\n\nexport class AppComponent {\n\n constructor(private httpWrapperService: HttpWrapperService) {}\n\n public whoAmI: string; // name\n public counterParty: string; // id\n public counterParties: Array < any > = [];\n\n public selected(value: any): void {};\n\n public refreshValue(value: any): void {\n this.counterparty = this.httpWrapperService.setCounterparty(value.id);\n }\n\n public renderX500Name(x500Name) {\n var name = x500Name;\n x500Name.split(',').forEach(function (element) {\n var keyValue = element.split('=');\n if (keyValue[0].toUpperCase() == 'CN') {\n name = keyValue[1];\n }\n });\n return name;\n }\n\n private counterparty: any = null;\n\n ngOnInit() {\n this.httpWrapperService.getAbsolute(\"whoami\").toPromise().then((data) => {\n this.whoAmI = this.renderX500Name(data.self.text);\n this.counterParties = data.counterparties.map(function (x) {\n return {\n id: x.id,\n text: this.renderX500Name(x.text)\n };\n });\n if (this.counterParties.length == 0) {\n console.log(\"/whoami is returning no counterparties, the whole app won't run\", data);\n }\n }).catch((error) => {\n console.log(\"Error loading who am i (this is really bad, the whole app will not work)\", error);\n });\n }\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js deleted file mode 100644 index 97b6582bcb..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -var testing_1 = require('@angular/core/testing'); -var app_component_1 = require('./app.component'); -describe('App: Vega', function () { - beforeEach(function () { - testing_1.addProviders([app_component_1.AppComponent]); - }); - it('should create the app', testing_1.inject([app_component_1.AppComponent], function (app) { - expect(app).toBeTruthy(); - })); -}); -//# sourceMappingURL=app.component.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js.map deleted file mode 100644 index cd3dcb1f5a..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.component.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"app.component.spec.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/app.component.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAEvC,wBAA4C,uBAAuB,CAAC,CAAA;AACpE,8BAA6B,iBAAiB,CAAC,CAAA;AAE/C,QAAQ,CAAC,WAAW,EAAE;IACpB,UAAU,CAAC;QACT,sBAAY,CAAC,CAAC,4BAAY,CAAC,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uBAAuB,EACxB,gBAAM,CAAC,CAAC,4BAAY,CAAC,EAAE,UAAC,GAAiB;QACvC,MAAM,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,CAAC;IAC3B,CAAC,CAAC,CAAC,CAAC;AACR,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { AppComponent } from './app.component';\n\ndescribe('App: Vega', () => {\n beforeEach(() => {\n addProviders([AppComponent]);\n });\n\n it('should create the app',\n inject([AppComponent], (app: AppComponent) => {\n expect(app).toBeTruthy();\n }));\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js deleted file mode 100644 index 5dba092eb8..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js +++ /dev/null @@ -1,17 +0,0 @@ -"use strict"; -var router_1 = require('@angular/router'); -var portfolio_1 = require('./portfolio'); -var valuations_1 = require('./valuations'); -var create_trade_1 = require('./create-trade'); -var view_trade_1 = require('./view-trade'); -var routes = [ - { path: '', redirectTo: '/portfolio', pathMatch: 'full' }, - { path: 'portfolio', component: portfolio_1.PortfolioComponent }, - { path: 'valuations', component: valuations_1.ValuationsComponent }, - { path: 'create-trade', component: create_trade_1.CreateTradeComponent }, - { path: 'view-trade/:tradeId', component: view_trade_1.ViewTradeComponent } -]; -exports.appRouterProviders = [ - router_1.provideRouter(routes) -]; -//# sourceMappingURL=app.routes.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js.map deleted file mode 100644 index 268eb54ec5..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/app.routes.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"app.routes.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/app.routes.ts"],"names":[],"mappings":";AAAA,uBAA4C,iBAAiB,CAAC,CAAA;AAC9D,0BAAmC,aAAa,CAAC,CAAA;AACjD,2BAAoC,cAAc,CAAC,CAAA;AACnD,6BAAqC,gBAAgB,CAAC,CAAA;AACtD,2BAAmC,cAAc,CAAC,CAAA;AAElD,IAAM,MAAM,GAAiB;IAC3B,EAAE,IAAI,EAAE,EAAE,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE;IACzD,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,8BAAkB,EAAE;IACpD,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,gCAAmB,EAAE;IACtD,EAAE,IAAI,EAAE,cAAc,EAAE,SAAS,EAAE,mCAAoB,EAAE;IACzD,EAAE,IAAI,EAAE,qBAAqB,EAAE,SAAS,EAAE,+BAAkB,EAAE;CAG/D,CAAC;AAEW,0BAAkB,GAAG;IAChC,sBAAa,CAAC,MAAM,CAAC;CACtB,CAAC","sourcesContent":["import { provideRouter, RouterConfig } from '@angular/router';\nimport { PortfolioComponent } from './portfolio';\nimport { ValuationsComponent } from './valuations';\nimport { CreateTradeComponent } from './create-trade';\nimport { ViewTradeComponent } from './view-trade';\n\nconst routes: RouterConfig = [\n { path: '', redirectTo: '/portfolio', pathMatch: 'full' },\n { path: 'portfolio', component: PortfolioComponent },\n { path: 'valuations', component: ValuationsComponent },\n { path: 'create-trade', component: CreateTradeComponent },\n { path: 'view-trade/:tradeId', component: ViewTradeComponent }\n\n // { path: '**', component: PageNotFoundComponent }\n];\n\nexport const appRouterProviders = [\n provideRouter(routes)\n];\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.css b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.css deleted file mode 100644 index 5089d3f268..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.css +++ /dev/null @@ -1,19 +0,0 @@ -#fixedleg tbody tr:nth-child(odd) { - background-color: #EEFAEE; -} - -#createfixedleg, -#fixedleg tbody tr:nth-child(even), -#fixedleg thead th { - background-color: #D0FAD0; -} - -#floatingleg tbody tr:nth-child(odd) { - background-color: #FAEEEE; -} - -#createfloatingleg, -#floatingleg tbody tr:nth-child(even), -#floatingleg thead th { - background-color: #FAD0D0; -} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.html deleted file mode 100644 index 66862d666e..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.html +++ /dev/null @@ -1,53 +0,0 @@ -

New Deal

-
-
{{formError}}
- -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- - -
-
- -
-
-
diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js deleted file mode 100644 index 5a86a00221..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js +++ /dev/null @@ -1,67 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var irs_service_1 = require('../irs.service'); -var node_service_1 = require('../node.service'); -var common_1 = require('@angular/common'); -var router_1 = require('@angular/router'); -var http_wrapper_service_1 = require('../http-wrapper.service'); -var DealParams = (function () { - function DealParams() { - this.id = "" + (100 + Math.floor((Math.random() * 900))); - this.convention = "USD_FIXED_6M_LIBOR_3M"; - this.buySell = "BUY"; - this.notional = "1000000"; - this.fixedRate = "0.015"; - } - return DealParams; -}()); -var CreateTradeComponent = (function () { - function CreateTradeComponent(irsService, nodeService, location, router, httpWrapperService) { - var _this = this; - this.irsService = irsService; - this.nodeService = nodeService; - this.location = location; - this.router = router; - this.httpWrapperService = httpWrapperService; - this.formError = ""; - this.createDeal = function () { - var that = _this; - _this.httpWrapperService.putWithCounterparty("trades", _this.deal) - .toPromise().then(function () { - _this.router.navigateByUrl("/view-trade/" + _this.deal.id); - }).catch(function (error) { - that.formError = error; - }); - }; - this.dayCountBasisLookup = Object.keys(this.irsService.lookupTable); - this.deal = new DealParams(); - this.deal.tradeDate = this.nodeService.formatDateForNode(new Date()); - this.deal.startDate = this.nodeService.formatDateForNode(new Date()); - this.deal.endDate = this.nodeService.formatDateForNode(new Date(2020, 1, 1)); - this.deal.convention = "EUR_FIXED_1Y_EURIBOR_3M"; - this.deal.description = "description"; - } - CreateTradeComponent.prototype.ngOnInit = function () { }; - CreateTradeComponent = __decorate([ - core_1.Component({ - moduleId: module.id, - selector: 'app-create-trade', - templateUrl: 'create-trade.component.html', - styleUrls: ['../app.component.css', 'create-trade.component.css'], - providers: [irs_service_1.IRSService, node_service_1.NodeService, common_1.Location] - }), - __metadata('design:paramtypes', [irs_service_1.IRSService, node_service_1.NodeService, common_1.Location, router_1.Router, http_wrapper_service_1.HttpWrapperService]) - ], CreateTradeComponent); - return CreateTradeComponent; -}()); -exports.CreateTradeComponent = CreateTradeComponent; -//# sourceMappingURL=create-trade.component.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js.map deleted file mode 100644 index 54e5996fbe..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"create-trade.component.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/create-trade/create-trade.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAkC,eAAe,CAAC,CAAA;AAClD,4BAA2B,gBAAgB,CAAC,CAAA;AAC5C,6BAA4B,iBAAiB,CAAC,CAAA;AAC9C,uBAAyB,iBAAiB,CAAC,CAAA;AAC3C,uBAAuB,iBAAiB,CAAC,CAAA;AACzC,qCAAmC,yBAAyB,CAAC,CAAA;AAE7D;IAAA;QACE,OAAE,GAAW,MAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,CAAE,CAAC;QAI1D,eAAU,GAAW,uBAAuB,CAAC;QAG7C,YAAO,GAAW,KAAK,CAAC;QACxB,aAAQ,GAAW,SAAS,CAAC;QAC7B,cAAS,GAAW,OAAO,CAAC;IAC9B,CAAC;IAAD,iBAAC;AAAD,CAAC,AAXD,IAWC;AASD;IAKE,8BACU,UAAsB,EACtB,WAAwB,EACxB,QAAkB,EAClB,MAAc,EACd,kBAAsC;QAVlD,iBAiCC;QA3BW,eAAU,GAAV,UAAU,CAAY;QACtB,gBAAW,GAAX,WAAW,CAAa;QACxB,aAAQ,GAAR,QAAQ,CAAU;QAClB,WAAM,GAAN,MAAM,CAAQ;QACd,uBAAkB,GAAlB,kBAAkB,CAAoB;QAPhD,cAAS,GAAW,EAAE,CAAC;QAoBvB,eAAU,GAAG;YACX,IAAI,IAAI,GAAG,KAAI,CAAC;YAChB,KAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,QAAQ,EAAE,KAAI,CAAC,IAAI,CAAC;iBAC7D,SAAS,EAAE,CAAC,IAAI,CAAC;gBAChB,KAAI,CAAC,MAAM,CAAC,aAAa,CAAC,iBAAe,KAAI,CAAC,IAAI,CAAC,EAAI,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;gBACb,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACzB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;QAnBA,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;QACrE,IAAI,CAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC,IAAI,CAAC,UAAU,GAAG,yBAAyB,CAAC;QACjD,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC;IACxC,CAAC;IAED,uCAAQ,GAAR,cAAY,CAAC;IA5Bf;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,kBAAkB;YAC5B,WAAW,EAAE,6BAA6B;YAC1C,SAAS,EAAE,CAAC,sBAAsB,EAAE,4BAA4B,CAAC;YACjE,SAAS,EAAE,CAAC,wBAAU,EAAE,0BAAW,EAAE,iBAAQ,CAAC;SAC/C,CAAC;;4BAAA;IAkCF,2BAAC;AAAD,CAAC,AAjCD,IAiCC;AAjCY,4BAAoB,uBAiChC,CAAA","sourcesContent":["import { Component, OnInit } from '@angular/core';\nimport { IRSService } from '../irs.service';\nimport { NodeService } from '../node.service';\nimport { Location } from '@angular/common';\nimport { Router } from '@angular/router';\nimport { HttpWrapperService } from '../http-wrapper.service';\n\nclass DealParams {\n id: string = `${100 + Math.floor((Math.random() * 900))}`;\n description: string;\n counterparty: string;\n tradeDate: string;\n convention: string = \"USD_FIXED_6M_LIBOR_3M\";\n startDate: string;\n endDate: string;\n buySell: string = \"BUY\";\n notional: string = \"1000000\";\n fixedRate: string = \"0.015\";\n}\n\n@Component({\n moduleId: module.id,\n selector: 'app-create-trade',\n templateUrl: 'create-trade.component.html',\n styleUrls: ['../app.component.css', 'create-trade.component.css'],\n providers: [IRSService, NodeService, Location]\n})\nexport class CreateTradeComponent implements OnInit {\n dayCountBasisLookup: string[];\n deal: DealParams;\n formError: string = \"\";\n\n constructor(\n private irsService: IRSService,\n private nodeService: NodeService,\n private location: Location,\n private router: Router,\n private httpWrapperService: HttpWrapperService\n ) {\n this.dayCountBasisLookup = Object.keys(this.irsService.lookupTable);\n this.deal = new DealParams();\n this.deal.tradeDate = this.nodeService.formatDateForNode(new Date());\n this.deal.startDate = this.nodeService.formatDateForNode(new Date());\n this.deal.endDate = this.nodeService.formatDateForNode(new Date(2020, 1, 1));\n this.deal.convention = \"EUR_FIXED_1Y_EURIBOR_3M\";\n this.deal.description = \"description\";\n }\n\n ngOnInit() {}\n\n createDeal = () => {\n var that = this;\n this.httpWrapperService.putWithCounterparty(\"trades\", this.deal)\n .toPromise().then(() => {\n this.router.navigateByUrl(`/view-trade/${this.deal.id}`);\n }).catch((error) => {\n that.formError = error;\n });\n };\n\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js deleted file mode 100644 index 8112713bdf..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js +++ /dev/null @@ -1,9 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -describe('Component: CreateTrade', function () { - it('should create an instance', function () { - //let component = new CreateTradeComponent(); - //expect(component).toBeTruthy(); - }); -}); -//# sourceMappingURL=create-trade.component.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js.map deleted file mode 100644 index 32b7d22eed..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/create-trade.component.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"create-trade.component.spec.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/create-trade/create-trade.component.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAOvC,QAAQ,CAAC,wBAAwB,EAAE;IACjC,EAAE,CAAC,2BAA2B,EAAE;QAC9B,6CAA6C;QAC7C,iCAAiC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { By } from '@angular/platform-browser';\nimport { DebugElement } from '@angular/core';\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { CreateTradeComponent } from './create-trade.component';\n\ndescribe('Component: CreateTrade', () => {\n it('should create an instance', () => {\n //let component = new CreateTradeComponent();\n //expect(component).toBeTruthy();\n });\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js deleted file mode 100644 index 95180f9b10..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require('./create-trade.component')); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js.map deleted file mode 100644 index ecb07b7343..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/create-trade/index.ts"],"names":[],"mappings":";;;;AAAA,iBAAc,0BAA0B,CAAC,EAAA","sourcesContent":["export * from './create-trade.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js deleted file mode 100644 index 8332f84cff..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js.map deleted file mode 100644 index 6c8ed6fe10..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/create-trade/shared/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/create-trade/shared/index.ts"],"names":[],"mappings":"","sourcesContent":[""]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js deleted file mode 100644 index 1bb3e4bad0..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -exports.environment = { - production: false, - APIPath: "/api/simmvaluationdemo/" -}; -//# sourceMappingURL=environment.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js.map deleted file mode 100644 index 9c5819dfac..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/environment.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"environment.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/environment.ts"],"names":[],"mappings":";AAAa,mBAAW,GAAG;IACzB,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE,yBAAyB;CACnC,CAAC","sourcesContent":["export const environment = {\n production: false,\n APIPath: \"/api/simmvaluationdemo/\"\n};\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js deleted file mode 100644 index 2e474bead1..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js +++ /dev/null @@ -1,115 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var router_1 = require('@angular/router'); -var http_1 = require('@angular/http'); -var environment_1 = require('./environment'); -var Rx_1 = require('rxjs/Rx'); -var HttpWrapperService = (function () { - function HttpWrapperService(http, router) { - var _this = this; - this.http = http; - this.router = router; - this.newCounterparty = new core_1.EventEmitter(); - this.step = 0; - // because components listen on newCounterparty, - // they need to know there is a new value when view is switched - router.events.subscribe(function (event) { - if (event instanceof router_1.NavigationEnd) { - _this.emitNewCounterparty(); - } - }); - } - //new CP events - HttpWrapperService.prototype.emitNewCounterparty = function () { - if (this.counterparty) { - this.newCounterparty.emit({ - value: this.counterparty - }); - } - }; - // end new CP events - // CP getter and setter - HttpWrapperService.prototype.setCounterparty = function (cp) { - this.counterparty = cp; - this.emitNewCounterparty(); - return cp; //chainable - }; - HttpWrapperService.prototype.getCounterparty = function () { - return this.counterparty; - }; - // end CP getter and setter - // HTTP helpers - HttpWrapperService.prototype.getPath = function (resource) { - return environment_1.environment.APIPath + resource; - }; - // end HTTP helpers - // HTTP methods - HttpWrapperService.prototype.getWithCounterparty = function (resource) { - return this.http.get(this.getPath(this.counterparty + "/" + resource)).map(function (res) { return res.json(); }); - }; - HttpWrapperService.prototype.postWithCounterparty = function (resource, data) { - return this.http.post(this.getPath(this.counterparty + "/" + resource), data).map(function (res) { return res.json(); }); - }; - HttpWrapperService.prototype.putWithCounterparty = function (resource, data) { - return this.http.put(this.getPath(this.counterparty + "/" + resource), data).map(function (res) { return res.json(); }); - }; - HttpWrapperService.prototype.getAbsolute = function (resource) { - return this.http.get(this.getPath(resource)).map(function (res) { return res.json(); }); - }; - HttpWrapperService.prototype.updateDelayedData = function (data) { - if (!data.portfolio) { - return; // data hasn't fully returned yet, don't do anything - } - var delayedData = {}; - if (this.step > 0) { - delayedData.portfolio = data.portfolio; - delayedData.portfolio.agreed = (this.step > 1); - } - if (this.step > 2) { - delayedData.marketData = data.marketData; - delayedData.marketData.agreed = (this.step > 3); - } - if (this.step > 4) { - delayedData.sensitivities = data.sensitivities; - delayedData.sensitivities.agreed = (this.step > 5); - } - if (this.step > 6) { - delayedData.initialMargin = data.initialMargin; - delayedData.initialMargin.agreed = (this.step > 7); - } - if (this.step > 8) { - delayedData.confirmation = data.confirmation; - delayedData.confirmation.agreed = (this.step > 9); - } - if (this.step == 10) { - this.subscription.unsubscribe(); - } - return delayedData; - }; - HttpWrapperService.prototype.startDelayedTimer = function () { - var _this = this; - this.step = 0; - // every x second, update data - var timer = Rx_1.Observable.timer(1000, 2000); - this.subscription = timer.subscribe(function (t) { _this.step++; }); - }; - HttpWrapperService.prototype.getDelayedData = function (data) { - return this.updateDelayedData(data); - }; - HttpWrapperService = __decorate([ - core_1.Injectable(), - __metadata('design:paramtypes', [http_1.Http, router_1.Router]) - ], HttpWrapperService); - return HttpWrapperService; -}()); -exports.HttpWrapperService = HttpWrapperService; -//# sourceMappingURL=http-wrapper.service.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js.map deleted file mode 100644 index 12f56275ab..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"http-wrapper.service.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/http-wrapper.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAyC,eAAe,CAAC,CAAA;AACzD,uBAAsC,iBAAiB,CAAC,CAAA;AACxD,qBAAqB,eAAe,CAAC,CAAA;AACrC,4BAA4B,eAAe,CAAC,CAAA;AAC5C,mBAA2B,SAAS,CAAC,CAAA;AAGrC;IAIE,4BAAoB,IAAU,EAAU,MAAc;QAJxD,iBAoIC;QAhIqB,SAAI,GAAJ,IAAI,CAAM;QAAU,WAAM,GAAN,MAAM,CAAQ;QAmB/C,oBAAe,GAAyB,IAAI,mBAAY,EAAE,CAAC;QAuD1D,SAAI,GAAW,CAAC,CAAC;QAzEvB,gDAAgD;QAChD,+DAA+D;QAC/D,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,UAAC,KAAK;YAC5B,EAAE,CAAC,CAAC,KAAK,YAAY,sBAAa,CAAC,CAAC,CAAC;gBACnC,KAAI,CAAC,mBAAmB,EAAE,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,eAAe;IAEP,gDAAmB,GAA3B;QACE,EAAE,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC;YACtB,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;gBACxB,KAAK,EAAE,IAAI,CAAC,YAAY;aACzB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAGD,oBAAoB;IAGpB,uBAAuB;IAEhB,4CAAe,GAAtB,UAAuB,EAAE;QACvB,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,mBAAmB,EAAE,CAAC;QAC3B,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW;IACxB,CAAC;IACM,4CAAe,GAAtB;QACE,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC;IAC3B,CAAC;IAED,2BAA2B;IAG3B,eAAe;IAEP,oCAAO,GAAf,UAAgB,QAAQ;QACtB,MAAM,CAAC,yBAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IACxC,CAAC;IAED,mBAAmB;IAGnB,eAAe;IAER,gDAAmB,GAA1B,UAA2B,QAAQ;QACjC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC,CAAC;IAChG,CAAC;IAEM,iDAAoB,GAA3B,UAA4B,QAAQ,EAAE,IAAI;QACxC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC,CAAC;IACvG,CAAC;IAEM,gDAAmB,GAA1B,UAA2B,QAAQ,EAAE,IAAI;QACvC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,GAAG,GAAG,GAAG,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC,CAAC;IACtG,CAAC;IAEM,wCAAW,GAAlB,UAAmB,QAAQ;QACzB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,UAAA,GAAG,IAAI,OAAA,GAAG,CAAC,IAAI,EAAE,EAAV,CAAU,CAAC,CAAC;IACtE,CAAC;IAYO,8CAAiB,GAAzB,UAA0B,IAAI;QAC5B,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;YACpB,MAAM,CAAC,CAAC,oDAAoD;QAC9D,CAAC;QAED,IAAI,WAAW,GAAQ,EAAE,CAAC;QAE1B,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,WAAW,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;YACvC,WAAW,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;QAED,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,WAAW,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YACzC,WAAW,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QAClD,CAAC;QAED,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,WAAW,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YAC/C,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,WAAW,CAAC,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;YAC/C,WAAW,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;QAED,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;YACjB,WAAW,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;YAC7C,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,EAAE,CAAA,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC;YACnB,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAClC,CAAC;QACD,MAAM,CAAC,WAAW,CAAC;IACrB,CAAC;IAEM,8CAAiB,GAAxB;QAAA,iBAMC;QALC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC;QAEd,8BAA8B;QAC9B,IAAI,KAAK,GAAG,eAAU,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,UAAA,CAAC,IAAM,KAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7D,CAAC;IAEM,2CAAc,GAArB,UAAsB,IAAI;QACxB,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAA;IACrC,CAAC;IAhIH;QAAC,iBAAU,EAAE;;0BAAA;IAqIb,yBAAC;AAAD,CAAC,AApID,IAoIC;AApIY,0BAAkB,qBAoI9B,CAAA","sourcesContent":["import { Injectable, EventEmitter } from '@angular/core';\nimport { Router, NavigationEnd } from '@angular/router';\nimport { Http } from '@angular/http';\nimport { environment } from './environment';\nimport { Observable } from 'rxjs/Rx';\n\n@Injectable()\nexport class HttpWrapperService {\n\n private counterparty: string;\n\n constructor(private http: Http, private router: Router) {\n // because components listen on newCounterparty,\n // they need to know there is a new value when view is switched\n router.events.subscribe((event) => {\n if (event instanceof NavigationEnd) { //NavigationEnd?\n this.emitNewCounterparty();\n }\n });\n }\n\n //new CP events\n\n private emitNewCounterparty() {\n if (this.counterparty) {\n this.newCounterparty.emit({\n value: this.counterparty\n });\n }\n }\n public newCounterparty: EventEmitter < any > = new EventEmitter();\n\n // end new CP events\n\n\n // CP getter and setter\n\n public setCounterparty(cp) {\n this.counterparty = cp;\n this.emitNewCounterparty();\n return cp; //chainable\n }\n public getCounterparty() {\n return this.counterparty;\n }\n\n // end CP getter and setter\n\n\n // HTTP helpers\n\n private getPath(resource) {\n return environment.APIPath + resource;\n }\n\n // end HTTP helpers\n\n\n // HTTP methods\n\n public getWithCounterparty(resource): any {\n return this.http.get(this.getPath(this.counterparty + \"/\" + resource)).map(res => res.json());\n }\n\n public postWithCounterparty(resource, data): any {\n return this.http.post(this.getPath(this.counterparty + \"/\" + resource), data).map(res => res.json());\n }\n\n public putWithCounterparty(resource, data): any {\n return this.http.put(this.getPath(this.counterparty + \"/\" + resource), data).map(res => res.json());\n }\n\n public getAbsolute(resource): any {\n return this.http.get(this.getPath(resource)).map(res => res.json());\n }\n\n // end HTTP methods\n\n\n\n // *****************************************\n // Demo magic - delayed data for valuations\n // *****************************************\n\n private subscription;\n private step: number = 0;\n private updateDelayedData(data) {\n if (!data.portfolio) {\n return; // data hasn't fully returned yet, don't do anything\n }\n\n var delayedData: any = {};\n\n if(this.step > 0) {\n delayedData.portfolio = data.portfolio;\n delayedData.portfolio.agreed = (this.step > 1);\n }\n\n if(this.step > 2) {\n delayedData.marketData = data.marketData;\n delayedData.marketData.agreed = (this.step > 3);\n }\n\n if(this.step > 4) {\n delayedData.sensitivities = data.sensitivities;\n delayedData.sensitivities.agreed = (this.step > 5);\n }\n\n if(this.step > 6) {\n delayedData.initialMargin = data.initialMargin;\n delayedData.initialMargin.agreed = (this.step > 7);\n }\n\n if(this.step > 8) {\n delayedData.confirmation = data.confirmation;\n delayedData.confirmation.agreed = (this.step > 9);\n }\n\n if(this.step == 10) {\n this.subscription.unsubscribe();\n }\n return delayedData;\n }\n\n public startDelayedTimer() {\n this.step = 0;\n\n // every x second, update data\n let timer = Observable.timer(1000, 2000);\n this.subscription = timer.subscribe(t => { this.step++; });\n }\n\n public getDelayedData(data): any {\n return this.updateDelayedData(data)\n }\n\n // *****************************************\n // end demo magic\n // *****************************************\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js deleted file mode 100644 index 9e4fcf2d69..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -var testing_1 = require('@angular/core/testing'); -var http_wrapper_service_1 = require('./http-wrapper.service'); -describe('Service: HttpWrapper', function () { - beforeEach(function () { - testing_1.addProviders([http_wrapper_service_1.HttpWrapperService]); - }); - it('should ...', testing_1.inject([http_wrapper_service_1.HttpWrapperService], function (service) { - expect(service).toBeTruthy(); - })); -}); -//# sourceMappingURL=http-wrapper.service.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js.map deleted file mode 100644 index 532f3fffb7..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/http-wrapper.service.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"http-wrapper.service.spec.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/http-wrapper.service.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAEvC,wBAA4C,uBAAuB,CAAC,CAAA;AACpE,qCAAmC,wBAAwB,CAAC,CAAA;AAE5D,QAAQ,CAAC,sBAAsB,EAAE;IAC/B,UAAU,CAAC;QACT,sBAAY,CAAC,CAAC,yCAAkB,CAAC,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,EACb,gBAAM,CAAC,CAAC,yCAAkB,CAAC,EACzB,UAAC,OAA2B;QAC1B,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { HttpWrapperService } from './http-wrapper.service';\n\ndescribe('Service: HttpWrapper', () => {\n beforeEach(() => {\n addProviders([HttpWrapperService]);\n });\n\n it('should ...',\n inject([HttpWrapperService],\n (service: HttpWrapperService) => {\n expect(service).toBeTruthy();\n }));\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js deleted file mode 100644 index f297df2d73..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require('./environment')); -__export(require('./app.component')); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js.map deleted file mode 100644 index 16ec595c18..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/index.ts"],"names":[],"mappings":";;;;AAAA,iBAAc,eAAe,CAAC,EAAA;AAC9B,iBAAc,iBAAiB,CAAC,EAAA","sourcesContent":["export * from './environment';\nexport * from './app.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js deleted file mode 100644 index 58cdaeea71..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js +++ /dev/null @@ -1,43 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var DayCountBasis = (function () { - function DayCountBasis(day, year) { - this.day = day; - this.year = year; - } - return DayCountBasis; -}()); -exports.DayCountBasis = DayCountBasis; -var IRSService = (function () { - function IRSService() { - var _this = this; - this.lookupTable = { - "30/360": new DayCountBasis("D30", "Y360"), - "30E/360": new DayCountBasis("D30E", "Y360"), - "ACT/360": new DayCountBasis("DActual", "Y360"), - "ACT/365 Fixed": new DayCountBasis("DActual", "Y365F"), - "ACT/365 L": new DayCountBasis("DActual", "Y365L"), - "ACT/ACT ISDA": new DayCountBasis("DActual", "YISDA"), - "ACT/ACT ICMA": new DayCountBasis("DActual", "YICMA") - }; - this.lookupDayCountBasis = function (shorthand) { - return _this.lookupTable[shorthand]; - }; - } - IRSService = __decorate([ - core_1.Injectable(), - __metadata('design:paramtypes', []) - ], IRSService); - return IRSService; -}()); -exports.IRSService = IRSService; -//# sourceMappingURL=irs.service.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js.map deleted file mode 100644 index 889e9b5b79..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"irs.service.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/irs.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAA2B,eAAe,CAAC,CAAA;AAE3C;IACE,uBAAmB,GAAW,EAAS,IAAY;QAAhC,QAAG,GAAH,GAAG,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAQ;IAAG,CAAC;IACzD,oBAAC;AAAD,CAAC,AAFD,IAEC;AAFY,qBAAa,gBAEzB,CAAA;AAGD;IAWE;QAXF,iBAiBC;QAhBC,gBAAW,GAAG;YACZ,QAAQ,EAAE,IAAI,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC;YAC1C,SAAS,EAAE,IAAI,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC;YAC5C,SAAS,EAAE,IAAI,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC;YAC/C,eAAe,EAAE,IAAI,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC;YACtD,WAAW,EAAE,IAAI,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC;YAClD,cAAc,EAAE,IAAI,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC;YACrD,cAAc,EAAE,IAAI,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC;SACtD,CAAA;QAID,wBAAmB,GAAa,UAAC,SAAiB;YAChD,MAAM,CAAC,KAAI,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACrC,CAAC,CAAA;IAJc,CAAC;IAZlB;QAAC,iBAAU,EAAE;;kBAAA;IAkBb,iBAAC;AAAD,CAAC,AAjBD,IAiBC;AAjBY,kBAAU,aAiBtB,CAAA","sourcesContent":["import { Injectable } from '@angular/core';\n\nexport class DayCountBasis {\n constructor(public day: string, public year: string) {}\n}\n\n@Injectable()\nexport class IRSService {\n lookupTable = {\n \"30/360\": new DayCountBasis(\"D30\", \"Y360\"),\n \"30E/360\": new DayCountBasis(\"D30E\", \"Y360\"),\n \"ACT/360\": new DayCountBasis(\"DActual\", \"Y360\"),\n \"ACT/365 Fixed\": new DayCountBasis(\"DActual\", \"Y365F\"),\n \"ACT/365 L\": new DayCountBasis(\"DActual\", \"Y365L\"),\n \"ACT/ACT ISDA\": new DayCountBasis(\"DActual\", \"YISDA\"),\n \"ACT/ACT ICMA\": new DayCountBasis(\"DActual\", \"YICMA\")\n }\n\n constructor() {}\n\n lookupDayCountBasis: Function = (shorthand: string) => {\n return this.lookupTable[shorthand];\n }\n\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js deleted file mode 100644 index 25b1753d7b..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -var testing_1 = require('@angular/core/testing'); -var irs_service_1 = require('./irs.service'); -describe('Service: IRS', function () { - beforeEach(function () { - testing_1.addProviders([irs_service_1.IRSService]); - }); - it('should ...', testing_1.inject([irs_service_1.IRSService], function (service) { - expect(service).toBeTruthy(); - })); -}); -//# sourceMappingURL=irs.service.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js.map deleted file mode 100644 index 970745e9c4..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/irs.service.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"irs.service.spec.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/irs.service.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAEvC,wBAA4C,uBAAuB,CAAC,CAAA;AACpE,4BAA2B,eAAe,CAAC,CAAA;AAE3C,QAAQ,CAAC,cAAc,EAAE;IACvB,UAAU,CAAC;QACT,sBAAY,CAAC,CAAC,wBAAU,CAAC,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,EACb,gBAAM,CAAC,CAAC,wBAAU,CAAC,EACjB,UAAC,OAAmB;QAClB,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { IRSService } from './irs.service';\n\ndescribe('Service: IRS', () => {\n beforeEach(() => {\n addProviders([IRSService]);\n });\n\n it('should ...',\n inject([IRSService],\n (service: IRSService) => {\n expect(service).toBeTruthy();\n }));\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js deleted file mode 100644 index 88b73e6f81..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js +++ /dev/null @@ -1,31 +0,0 @@ -"use strict"; -var CommonModel = (function () { - function CommonModel() { - this.baseCurrency = null; - this.eligibleCreditSupport = null; - this.independentAmounts = { - token: "" - }; - this.threshold = { - token: "" - }; - this.minimumTransferAmount = { - token: "" - }; - this.rounding = { - token: "" - }; - this.valuationDate = null; - this.notificationTime = null; - this.resolutionTime = null; - this.interestRate = null; - this.addressForTransfers = null; - this.exposure = null; - this.localBusinessDay = null; - this.dailyInterestAmount = null; - this.tradeID = null; - } - return CommonModel; -}()); -exports.CommonModel = CommonModel; -//# sourceMappingURL=CommonModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js.map deleted file mode 100644 index d3d3c98ead..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/CommonModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"CommonModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/model/CommonModel.ts"],"names":[],"mappings":";AAAA;IAAA;QACE,iBAAY,GAAW,IAAI,CAAC;QAC5B,0BAAqB,GAAW,IAAI,CAAC;QACrC,uBAAkB,GAAG;YACnB,KAAK,EAAE,EAAE;SACV,CAAC;QACF,cAAS,GAAG;YACV,KAAK,EAAE,EAAE;SACV,CAAC;QACF,0BAAqB,GAAG;YACtB,KAAK,EAAE,EAAE;SACV,CAAC;QACF,aAAQ,GAAG;YACT,KAAK,EAAE,EAAE;SACV,CAAC;QACF,kBAAa,GAAW,IAAI,CAAC;QAC7B,qBAAgB,GAAW,IAAI,CAAC;QAChC,mBAAc,GAAW,IAAI,CAAC;QAC9B,iBAAY,GAAW,IAAI,CAAC;QAC5B,wBAAmB,GAAW,IAAI,CAAC;QACnC,aAAQ,GAAW,IAAI,CAAC;QACxB,qBAAgB,GAAW,IAAI,CAAC;QAChC,wBAAmB,GAAW,IAAI,CAAC;QACnC,YAAO,GAAW,IAAI,CAAC;IAEzB,CAAC;IAAD,kBAAC;AAAD,CAAC,AAzBD,IAyBC;AAzBY,mBAAW,cAyBvB,CAAA","sourcesContent":["export class CommonModel {\n baseCurrency: string = null;\n eligibleCreditSupport: string = null;\n independentAmounts = {\n token: \"\"\n };\n threshold = {\n token: \"\"\n };\n minimumTransferAmount = {\n token: \"\"\n };\n rounding = {\n token: \"\"\n };\n valuationDate: string = null;\n notificationTime: string = null;\n resolutionTime: string = null;\n interestRate: Object = null;\n addressForTransfers: string = null;\n exposure: Object = null;\n localBusinessDay: Object = null;\n dailyInterestAmount: string = null;\n tradeID: string = null;\n eligibleCurrency: string;\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js deleted file mode 100644 index 6458c363e6..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; -var FixedLegModel = (function () { - function FixedLegModel() { - this.fixedRatePayer = null; - this.notional = { - token: "" - }; - this.paymentFrequency = null; - this.effectiveDate = null; - this.terminationDate = null; - this.fixedRate = null; - this.dayCountBasisDay = null; - this.dayCountBasisYear = null; - this.rollConvention = null; - this.dayInMonth = null; - this.paymentRule = null; - this.paymentCalendar = null; - this.interestPeriodAdjustment = null; - } - return FixedLegModel; -}()); -exports.FixedLegModel = FixedLegModel; -//# sourceMappingURL=FixedLegModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js.map deleted file mode 100644 index 521a3d985a..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FixedLegModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FixedLegModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/model/FixedLegModel.ts"],"names":[],"mappings":";AAAA;IAAA;QACE,mBAAc,GAAW,IAAI,CAAC;QAC9B,aAAQ,GAAG;YACT,KAAK,EAAE,EAAE;SACV,CAAC;QACF,qBAAgB,GAAW,IAAI,CAAC;QAChC,kBAAa,GAAW,IAAI,CAAC;QAC7B,oBAAe,GAAW,IAAI,CAAC;QAC/B,cAAS,GAAW,IAAI,CAAC;QACzB,qBAAgB,GAAW,IAAI,CAAC;QAChC,sBAAiB,GAAW,IAAI,CAAC;QACjC,mBAAc,GAAW,IAAI,CAAC;QAC9B,eAAU,GAAW,IAAI,CAAC;QAC1B,gBAAW,GAAW,IAAI,CAAC;QAC3B,oBAAe,GAAW,IAAI,CAAC;QAC/B,6BAAwB,GAAW,IAAI,CAAC;IAC1C,CAAC;IAAD,oBAAC;AAAD,CAAC,AAhBD,IAgBC;AAhBY,qBAAa,gBAgBzB,CAAA","sourcesContent":["export class FixedLegModel {\n fixedRatePayer: string = null;\n notional = {\n token: \"\"\n };\n paymentFrequency: string = null;\n effectiveDate: string = null;\n terminationDate: string = null;\n fixedRate: Object = null;\n dayCountBasisDay: string = null;\n dayCountBasisYear: string = null;\n rollConvention: string = null;\n dayInMonth: number = null;\n paymentRule: string = null;\n paymentCalendar: string = null;\n interestPeriodAdjustment: string = null;\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js deleted file mode 100644 index 9fa6141a1f..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js +++ /dev/null @@ -1,34 +0,0 @@ -"use strict"; -var FloatingLegModel = (function () { - function FloatingLegModel() { - this.floatingRatePayer = null; - this.notional = { - token: "" - }; - this.paymentFrequency = null; - this.effectiveDate = null; - this.terminationDate = null; - this.dayCountBasisDay = null; - this.dayCountBasisYear = null; - this.rollConvention = null; - this.fixingRollConvention = null; - this.dayInMonth = null; - this.resetDayInMonth = null; - this.paymentRule = null; - this.paymentDelay = null; - this.interestPeriodAdjustment = null; - this.fixingPeriodOffset = null; - this.resetRule = null; - this.fixingsPerPayment = null; - this.indexSource = null; - this.index = null; - this.indexTenor = { - name: "" - }; - this.fixingCalendar = []; - this.paymentCalendar = []; - } - return FloatingLegModel; -}()); -exports.FloatingLegModel = FloatingLegModel; -//# sourceMappingURL=FloatingLegModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js.map deleted file mode 100644 index e7d7ce0933..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/model/FloatingLegModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FloatingLegModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/model/FloatingLegModel.ts"],"names":[],"mappings":";AAAA;IAAA;QACE,sBAAiB,GAAW,IAAI,CAAC;QACjC,aAAQ,GAAG;YACT,KAAK,EAAE,EAAE;SACV,CAAC;QACF,qBAAgB,GAAW,IAAI,CAAC;QAChC,kBAAa,GAAW,IAAI,CAAC;QAC7B,oBAAe,GAAW,IAAI,CAAC;QAC/B,qBAAgB,GAAW,IAAI,CAAC;QAChC,sBAAiB,GAAW,IAAI,CAAC;QACjC,mBAAc,GAAW,IAAI,CAAC;QAC9B,yBAAoB,GAAW,IAAI,CAAC;QACpC,eAAU,GAAW,IAAI,CAAC;QAC1B,oBAAe,GAAW,IAAI,CAAC;QAC/B,gBAAW,GAAW,IAAI,CAAC;QAC3B,iBAAY,GAAW,IAAI,CAAC;QAC5B,6BAAwB,GAAW,IAAI,CAAC;QACxC,uBAAkB,GAAW,IAAI,CAAC;QAClC,cAAS,GAAW,IAAI,CAAC;QACzB,sBAAiB,GAAW,IAAI,CAAC;QACjC,gBAAW,GAAW,IAAI,CAAC;QAC3B,UAAK,GAAW,IAAI,CAAC;QACrB,eAAU,GAAG;YACX,IAAI,EAAE,EAAE;SACT,CAAC;QACF,mBAAc,GAAa,EAAE,CAAC;QAC9B,oBAAe,GAAa,EAAE,CAAC;IACjC,CAAC;IAAD,uBAAC;AAAD,CAAC,AA3BD,IA2BC;AA3BY,wBAAgB,mBA2B5B,CAAA","sourcesContent":["export class FloatingLegModel {\n floatingRatePayer: string = null;\n notional = {\n token: \"\"\n };\n paymentFrequency: string = null;\n effectiveDate: string = null;\n terminationDate: string = null;\n dayCountBasisDay: string = null;\n dayCountBasisYear: string = null;\n rollConvention: string = null;\n fixingRollConvention: string = null;\n dayInMonth: string = null;\n resetDayInMonth: string = null;\n paymentRule: string = null;\n paymentDelay: string = null;\n interestPeriodAdjustment: string = null;\n fixingPeriodOffset: string = null;\n resetRule: string = null;\n fixingsPerPayment: string = null;\n indexSource: string = null;\n index: string = null;\n indexTenor = {\n name: \"\"\n };\n fixingCalendar: string[] = [];\n paymentCalendar: string[] = [];\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js deleted file mode 100644 index 8e929b8822..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js +++ /dev/null @@ -1,51 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var curLoading = {}; -var load = function (type, promise) { - curLoading[type] = true; - return promise.then(function (arg) { - curLoading[type] = false; - return arg; - }, function (arg) { - curLoading[type] = false; - throw arg; - }); -}; -var http_wrapper_service_1 = require('./http-wrapper.service'); -var NodeService = (function () { - function NodeService(httpWrapperService) { - var _this = this; - this.httpWrapperService = httpWrapperService; - this.formatDateForNode = function (date) { - // Produces yyyy-dd-mm. JS is missing proper date formatting libs - var day = ("0" + (date.getDate())).slice(-2); - var month = ("0" + (date.getMonth() + 1)).slice(-2); - return date.getFullYear() + "-" + month + "-" + day; - }; - this.getDeal = function (dealId) { - return load('deal' + dealId, _this.httpWrapperService.getWithCounterparty('trades/' + dealId).toPromise()) - .then(function (resp) { - // Do some data modification to simplify the model - var deal = resp; - deal.fixedLeg.fixedRate.value = (deal.fixedLeg.fixedRate.value * 100).toString().slice(0, 6); - return deal; - }); - }; - } - NodeService = __decorate([ - core_1.Injectable(), - __metadata('design:paramtypes', [http_wrapper_service_1.HttpWrapperService]) - ], NodeService); - return NodeService; -}()); -exports.NodeService = NodeService; -//# sourceMappingURL=node.service.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js.map deleted file mode 100644 index 08209cd8f0..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"node.service.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/node.service.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAA2B,eAAe,CAAC,CAAA;AAG3C,IAAI,UAAU,GAAG,EAAE,CAAC;AAEpB,IAAI,IAAI,GAAG,UAAC,IAAI,EAAE,OAAO;IACvB,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,UAAC,GAAG;QACtB,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,MAAM,CAAC,GAAG,CAAC;IACb,CAAC,EAAE,UAAC,GAAG;QACL,UAAU,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;QACzB,MAAM,GAAG,CAAC;IACZ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AACF,qCAAmC,wBAAwB,CAAC,CAAA;AAG5D;IACE,qBAAoB,kBAAsC;QAD5D,iBAmBC;QAlBqB,uBAAkB,GAAlB,kBAAkB,CAAoB;QAE1D,sBAAiB,GAAa,UAAC,IAAI;YACjC,iEAAiE;YACjE,IAAI,GAAG,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,IAAI,KAAK,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YACpD,MAAM,CAAI,IAAI,CAAC,WAAW,EAAE,SAAI,KAAK,SAAI,GAAK,CAAC;QACjD,CAAC,CAAC;QAEF,YAAO,GAAa,UAAC,MAAM;YACzB,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE,KAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,SAAS,GAAG,MAAM,CAAC,CAAC,SAAS,EAAE,CAAC;iBACtG,IAAI,CAAC,UAAC,IAAI;gBACT,kDAAkD;gBAClD,IAAI,IAAI,GAAG,IAAI,CAAC;gBAChB,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC7F,MAAM,CAAC,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;QACP,CAAC,CAAC;IAjB2D,CAAC;IAFhE;QAAC,iBAAU,EAAE;;mBAAA;IAoBb,kBAAC;AAAD,CAAC,AAnBD,IAmBC;AAnBY,mBAAW,cAmBvB,CAAA","sourcesContent":["import { Injectable } from '@angular/core';\nimport { Deal } from './Deal'\nimport { Observable } from 'rxjs/Rx';\nlet curLoading = {};\n\nlet load = (type, promise) => {\n curLoading[type] = true;\n return promise.then((arg) => {\n curLoading[type] = false;\n return arg;\n }, (arg) => {\n curLoading[type] = false;\n throw arg;\n });\n};\nimport { HttpWrapperService } from './http-wrapper.service';\n\n@Injectable()\nexport class NodeService {\n constructor(private httpWrapperService: HttpWrapperService) {}\n\n formatDateForNode: Function = (date) => {\n // Produces yyyy-dd-mm. JS is missing proper date formatting libs\n let day = (\"0\" + (date.getDate())).slice(-2);\n let month = (\"0\" + (date.getMonth() + 1)).slice(-2);\n return `${date.getFullYear()}-${month}-${day}`;\n };\n\n getDeal: Function = (dealId) => {\n return load('deal' + dealId, this.httpWrapperService.getWithCounterparty('trades/' + dealId).toPromise())\n .then((resp) => {\n // Do some data modification to simplify the model\n let deal = resp;\n deal.fixedLeg.fixedRate.value = (deal.fixedLeg.fixedRate.value * 100).toString().slice(0, 6);\n return deal;\n });\n };\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js deleted file mode 100644 index 5297875899..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js +++ /dev/null @@ -1,13 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -var testing_1 = require('@angular/core/testing'); -var node_service_1 = require('./node.service'); -describe('Service: Node', function () { - beforeEach(function () { - testing_1.addProviders([node_service_1.NodeService]); - }); - it('should ...', testing_1.inject([node_service_1.NodeService], function (service) { - expect(service).toBeTruthy(); - })); -}); -//# sourceMappingURL=node.service.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js.map deleted file mode 100644 index d667a7d3d5..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/node.service.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"node.service.spec.js","sourceRoot":"","sources":["../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/node.service.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAEvC,wBAA4C,uBAAuB,CAAC,CAAA;AACpE,6BAA4B,gBAAgB,CAAC,CAAA;AAE7C,QAAQ,CAAC,eAAe,EAAE;IACxB,UAAU,CAAC;QACT,sBAAY,CAAC,CAAC,0BAAW,CAAC,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,EACb,gBAAM,CAAC,CAAC,0BAAW,CAAC,EAClB,UAAC,OAAoB;QACnB,MAAM,CAAC,OAAO,CAAC,CAAC,UAAU,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC,CAAC;AACV,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { NodeService } from './node.service';\n\ndescribe('Service: Node', () => {\n beforeEach(() => {\n addProviders([NodeService]);\n });\n\n it('should ...',\n inject([NodeService],\n (service: NodeService) => {\n expect(service).toBeTruthy();\n }));\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js deleted file mode 100644 index 46a856102f..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require('./portfolio.component')); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js.map deleted file mode 100644 index dfe8afcd6b..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/portfolio/index.ts"],"names":[],"mappings":";;;;AAAA,iBAAc,uBAAuB,CAAC,EAAA","sourcesContent":["export * from './portfolio.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.css b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.css deleted file mode 100644 index 8b13789179..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.css +++ /dev/null @@ -1 +0,0 @@ - diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.html deleted file mode 100644 index af575b6b1d..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.html +++ /dev/null @@ -1,95 +0,0 @@ -

Portfolio valued at {{businessDate}}

- -
-
-
-
-
- - - - -
- -
- -
-

Summary

- - - - - - - - - - - - - - - - - - - - - - -
ProductCurrencyTradesNet AmountIMMTM
{{summaryTable.product}}{{summaryTable.currency}}{{summaryTable.trades}}{{summaryTable.notional | number}}{{summaryTable.im | number}}{{summaryTable.mtm | number}}
-
- -
- -
- -
- -

Trades

- - - - - - - - - - - - -
{{c.title}}
- - -
- -
- - - -
diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js deleted file mode 100644 index 5207bfa7e1..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js +++ /dev/null @@ -1,466 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -/* beautify preserve:end */ -var core_1 = require('@angular/core'); -var ng2_bootstrap_1 = require('ng2-bootstrap/ng2-bootstrap'); -var ng2_popover_1 = require('ng2-popover'); -var directives_1 = require('@angular/forms/src/directives'); // https://github.com/valor-software/ng2-bootstrap/issues/782 -var common_1 = require('@angular/common'); -var ng2_bootstrap_2 = require('ng2-bootstrap/ng2-bootstrap'); -var ng2_table_1 = require('ng2-table/ng2-table'); -var http_wrapper_service_1 = require('../http-wrapper.service'); -var router_1 = require('@angular/router'); -var PortfolioComponent = (function () { - function PortfolioComponent(httpWrapperService, router) { - this.httpWrapperService = httpWrapperService; - this.router = router; - this.rows = []; - this.columns = [ - // omitting the sort column on each column would result in no default sorting! - { title: 'ID', name: 'id', sort: '', formatter: this.IDFormatter }, - { title: 'Product', name: 'product', sort: '', formatter: this.defaultFormatter }, - { title: 'Type', name: 'buySell', sort: '', formatter: this.defaultFormatter }, - { title: 'Trade Date', name: 'tradeDate', sort: 'desc', formatter: this.defaultFormatter }, - { title: 'Effective Date', name: 'effectiveDate', sort: '', formatter: this.defaultFormatter }, - { title: 'Maturity Date', name: 'maturityDate', sort: '', formatter: this.defaultFormatter }, - { title: 'Currency', name: 'currency', sort: '', formatter: this.defaultFormatter }, - { title: 'Notional', name: 'notional', sort: '', formatter: this.numberFormatter }, - { title: 'IM Contribution', name: 'im', sort: '', formatter: this.numberFormatter }, - { title: 'PV', name: 'mtm', sort: '', formatter: this.numberFormatter }, - { title: 'Included in summary', name: 'marginedText', sort: '', formatter: this.defaultFormatter } - ]; - this.page = 1; - this.itemsPerPage = 10; - this.maxSize = 5; - this.numPages = 1; - this.length = 0; - this.config = { - paging: true, - sorting: { columns: this.columns } - }; - this.data = []; - this.summaryTable = { - product: "Vanilla IRS", - currency: "EUR", - trades: 0, - notional: 0, - im: 0, - mtm: 0 - }; - } - PortfolioComponent.prototype.IDFormatter = function (id) { - return "" + id + ""; - }; - PortfolioComponent.prototype.defaultFormatter = function (value) { - return value; - }; - PortfolioComponent.prototype.numberFormatter = function (n) { - if (!n) { - return ""; - } - var a = "" + n; - a = a.replace(new RegExp("^(\\d{" + (a.length % 3 ? a.length % 3 : 0) + "})(\\d{3})", "g"), "$1 $2").replace(/(\d{3})+?/gi, "$1 ").trim(); - var sep = ","; - a = a.replace(/\s/g, sep); - return a; - }; - PortfolioComponent.prototype.createTradesChart = function (TData) { - var TFormat = 'Date: {point.x:%Y-%m-%d}
' + 'IM: {point.y:,.0f}€'; - $('#tradesChart').highcharts('StockChart', { - credits: { - enabled: false - }, - chart: { - type: 'scatter', - zoomType: 'xy' - }, - rangeSelector: { - selected: 4 - }, - title: { - text: 'Individual Trades' - }, - legend: { - enabled: true - }, - yAxis: { - title: { - text: 'IM' - } - }, - series: [{ - name: 'Trade', - data: TData, - tooltip: { - pointFormat: TFormat - } - }] - }); - }; - PortfolioComponent.prototype.createIMOverVMChart = function (IMVMData) { - // note there's no "highstocks" - $('#IMOverVMChart').highcharts({ - credits: { - enabled: false - }, - chart: { - type: 'scatter', - zoomType: 'xy' - }, - title: { - text: 'Imminent IM over Variation Margin of trades' - }, - legend: { - enabled: true - }, - subtitle: { - text: '' - }, - xAxis: { - title: { - enabled: true, - text: 'MTM' - }, - startOnTick: true, - endOnTick: true, - showLastLabel: true - }, - yAxis: { - title: { - text: 'IM' - } - }, - plotOptions: { - scatter: { - marker: { - radius: 5, - states: { - hover: { - enabled: true, - lineColor: 'rgb(100,100,100)' - } - } - }, - states: { - hover: { - marker: { - enabled: false - } - } - }, - tooltip: { - headerFormat: '{series.name}
', - pointFormat: 'IM: {point.x:,.0f}€
MTM: {point.x:,.0f}€
' - } - } - }, - series: [{ - name: 'Trade', - data: IMVMData - }] - }); - }; - PortfolioComponent.prototype.createIMVMHistoryChart = function (IMData, MTMData) { - $('#IMVMHistoryChart').highcharts('StockChart', { - credits: { - enabled: false - }, - legend: { - enabled: true - }, - rangeSelector: { - selected: 4 - }, - title: { - text: 'Portfolio History' - }, - subtitle: { - text: 'Initial and Variation Margin Requirements' - }, - xAxis: { - type: 'datetime', - dateTimeLabelFormats: { - //day: '%d' - month: '%e. %b', - year: '%b' - }, - title: { - text: 'Date' - } - }, - yAxis: { - title: { - text: 'Exposure (€)' - }, - min: 0 - }, - plotOptions: { - spline: { - marker: { - enabled: true - } - } - }, - series: [{ - name: 'Initial Margin', - data: IMData, - type: 'column' - }, { - name: 'Mark to Market', - data: MTMData, - type: 'spline' - }] - }); - }; - PortfolioComponent.prototype.createActiveTradesChart = function (ATData) { - var ATformat = 'Active trades: {point.y:,.0f}
' + - 'IM: {point.x:,.0f}
'; - $('#activeTradesChart').highcharts('StockChart', { - credits: { - enabled: false - }, - rangeSelector: { - selected: 4 - }, - legend: { - enabled: true - }, - xAxis: { - type: 'datetime', - dateTimeLabelFormats: { - //day: '%d' - month: '%e. %b', - year: '%b' - }, - title: { - text: 'Date' - } - }, - yAxis: { - title: { - text: 'Quantity' - } - }, - title: { - text: 'Active Trades' - }, - series: [{ - name: 'Active trades', - data: ATData, - tooltip: { - pointFormat: ATformat - } - }] - }); - }; - PortfolioComponent.prototype.createIMVMHistorySummaryChart = function (IMData, MTMData) { - $('#IMVMHistorySummaryChart').highcharts('StockChart', { - credits: { - enabled: false - }, - rangeSelector: { - enabled: false - }, - navigator: { - enabled: false - }, - scrollbar: { - enabled: false - }, - title: { - text: 'Portfolio History' - }, - legend: { - enabled: true - }, - xAxis: { - type: 'datetime', - title: { - text: 'Date' - } - }, - yAxis: { - title: { - text: 'Exposure (€)' - }, - min: 0 - }, - plotOptions: { - spline: { - marker: { - enabled: true - } - } - }, - dataGrouping: { - approximation: "average", - enabled: true, - forced: true, - units: [ - ['month', [1]] - ] - }, - series: [{ - name: 'Initial Margin', - data: IMData, - type: 'column' - }, { - name: 'Mark to Market', - data: MTMData, - type: 'spline' - }] - }); - }; - PortfolioComponent.prototype.getData = function () { - var _this = this; - if (this.httpWrapperService.getCounterparty()) { - // re-initialize addittive table sums - this.summaryTable.trades = 0; - this.summaryTable.notional = 0; - this.summaryTable.im = 0; - this.summaryTable.mtm = 0; - this.data = null; //don't leave old data in case of errors - //trades - this.httpWrapperService.getWithCounterparty("trades").toPromise().then(function (data) { - // trades over time scatter - var TData = []; - // trades IM over VM scatter - var IMVMData = []; - $.each(data, function (index, value) { - if (value.margined) { - TData.push([new Date(value.tradeDate).getTime(), value.im]); - IMVMData.push([value.im, value.mtm]); - } - }); - _this.createTradesChart(TData); - _this.createIMOverVMChart(IMVMData); - // trades table - _this.data = data; - _this.length = _this.data.length; - _this.onChangeTable(_this.config); - }).catch(function (error) { - console.log("Error loading trades", error); - }); - this.populateSummary().then(function () { - // portfolio history and active trades charts - _this.httpWrapperService.getWithCounterparty("portfolio/history/aggregated").toPromise().then(function (data) { - // summary table - var lastDay = data; - _this.summaryTable.trades = lastDay.activeTrades; - _this.summaryTable.notional = lastDay.notional; - _this.summaryTable.im = lastDay.im; - _this.summaryTable.mtm = lastDay.mtm; - var IMData = []; - var MTMData = []; - var ATData = []; - $.each(data, function (index, value) { - // new Date(value.date).getTime() when dates are switched to YYYY-MM-DD - IMData.push([value.date, value.im]); - MTMData.push([value.date, value.mtm]); - ATData.push([value.date, value.activeTrades]); - }); - _this.createIMVMHistoryChart(IMData, MTMData); - _this.createActiveTradesChart(ATData); - _this.createIMVMHistorySummaryChart(IMData, MTMData); - }).catch(function (error) { - console.log("Error loading portfolio history", error); - }); - }); - } - }; - PortfolioComponent.prototype.populateSummary = function () { - var _this = this; - return this.httpWrapperService.getWithCounterparty("portfolio/summary").toPromise().then(function (data) { - _this.summaryTable.trades = data.trades; - _this.summaryTable.notional = data.notional; - }).catch(function (error) { - console.log("Error loading portfolio summary", error); - }); - }; - PortfolioComponent.prototype.ngOnInit = function () { - var _this = this; - this.httpWrapperService.getAbsolute("business-date").toPromise().then(function (data) { - _this.businessDate = data.businessDate; - }).catch(function (error) { - console.log("Error loading business date", error); - }); - Highcharts.setOptions({ - lang: { - thousandsSep: ',' - } - }); - this.getData(); - this.counterpartySubscription = this.httpWrapperService.newCounterparty.subscribe(function (state) { - _this.getData(); - }); - }; - PortfolioComponent.prototype.ngOnDestroy = function () { - this.counterpartySubscription.unsubscribe(); - }; - // table helper functions - PortfolioComponent.prototype.changePage = function (page, data) { - if (data === void 0) { data = this.data; } - var start = (page.page - 1) * page.itemsPerPage; - var end = page.itemsPerPage > -1 ? (start + page.itemsPerPage) : data.length; - return data.slice(start, end); - }; - PortfolioComponent.prototype.changeSort = function (data, config) { - if (!config.sorting) { - return data; - } - var columns = this.config.sorting.columns || []; - var columnName = void 0; - var sort = void 0; - for (var i = 0; i < columns.length; i++) { - if (columns[i].sort !== '') { - columnName = columns[i].name; - sort = columns[i].sort; - } - } - if (!columnName) { - return data; - } - // simple sorting - return data.sort(function (previous, current) { - if (previous[columnName] > current[columnName]) { - return sort === 'desc' ? -1 : 1; - } - else if (previous[columnName] < current[columnName]) { - return sort === 'asc' ? -1 : 1; - } - return 0; - }); - }; - PortfolioComponent.prototype.onChangeTable = function (config, page) { - if (page === void 0) { page = { page: this.page, itemsPerPage: this.itemsPerPage }; } - if (config.sorting) { - Object.assign(this.config.sorting, config.sorting); - } - var sortedData = this.changeSort(this.data, this.config); - this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData; - this.length = sortedData.length; - }; - PortfolioComponent = __decorate([ - core_1.Component({ - moduleId: module.id, - selector: 'app-portfolio', - templateUrl: 'portfolio.component.html', - styleUrls: [ - 'portfolio.component.css' - ], - directives: [ng2_popover_1.POPOVER_DIRECTIVES, ng2_bootstrap_1.TAB_DIRECTIVES, ng2_table_1.NG_TABLE_DIRECTIVES, ng2_bootstrap_2.PAGINATION_DIRECTIVES, common_1.NgIf, common_1.CORE_DIRECTIVES, directives_1.FORM_DIRECTIVES] - }), - __metadata('design:paramtypes', [http_wrapper_service_1.HttpWrapperService, router_1.Router]) - ], PortfolioComponent); - return PortfolioComponent; -}()); -exports.PortfolioComponent = PortfolioComponent; -//# sourceMappingURL=portfolio.component.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js.map deleted file mode 100644 index 28946cbaab..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"portfolio.component.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/portfolio/portfolio.component.ts"],"names":[],"mappings":";;;;;;;;;;AAIA,2BAA2B;AAE3B,qBAAkC,eAAe,CAAC,CAAA;AAClD,8BAA+B,6BAA6B,CAAC,CAAA;AAC7D,4BAAmC,aAAa,CAAC,CAAA;AACjD,2BAAgC,+BAChC,CAAC,CAD8D,CAAC,6DAA6D;AAC7H,uBAA+C,iBAAiB,CAAC,CAAA;AACjE,8BAAsC,6BAA6B,CAAC,CAAA;AACpE,0BAAoC,qBAAqB,CAAC,CAAA;AAC1D,qCAAmC,yBAAyB,CAAC,CAAA;AAC7D,uBAAuB,iBAAiB,CAAC,CAAA;AAazC;IA6TE,4BAAoB,kBAAsC,EAAU,MAAc;QAA9D,uBAAkB,GAAlB,kBAAkB,CAAoB;QAAU,WAAM,GAAN,MAAM,CAAQ;QAtS3E,SAAI,GAAkB,EAAE,CAAC;QACzB,YAAO,GAAkB;YAC9B,8EAA8E;YAC9E,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,WAAW,EAAE;YAClE,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YACjF,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC9E,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC1F,EAAE,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC9F,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YAC5F,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;YACnF,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE;YAClF,EAAE,KAAK,EAAE,iBAAiB,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE;YACnF,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,eAAe,EAAE;YACvE,EAAE,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,CAAC,gBAAgB,EAAE;SACnG,CAAC;QACK,SAAI,GAAW,CAAC,CAAC;QACjB,iBAAY,GAAW,EAAE,CAAC;QAC1B,YAAO,GAAW,CAAC,CAAC;QACpB,aAAQ,GAAW,CAAC,CAAC;QACrB,WAAM,GAAW,CAAC,CAAC;QAEnB,WAAM,GAAQ;YACnB,MAAM,EAAE,IAAI;YACZ,OAAO,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE;SACnC,CAAC;QAIM,SAAI,GAAkB,EAAE,CAAC;QAEzB,iBAAY,GAAQ;YAC1B,OAAO,EAAE,aAAa;YACtB,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,CAAC;YACT,QAAQ,EAAE,CAAC;YACX,EAAE,EAAE,CAAC;YACL,GAAG,EAAE,CAAC;SACP,CAAC;IAiQmF,CAAC;IA3T9E,wCAAW,GAAnB,UAAoB,EAAE;QACpB,MAAM,CAAC,uBAAuB,GAAG,EAAE,GAAG,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;IAC3D,CAAC;IAEO,6CAAgB,GAAxB,UAAyB,KAAK;QAC5B,MAAM,CAAC,KAAK,CAAC;IACf,CAAC;IAEO,4CAAe,GAAvB,UAAwB,CAAC;QACvB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACP,MAAM,CAAC,EAAE,CAAC;QACZ,CAAC;QAED,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;QACf,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1I,IAAI,GAAG,GAAG,GAAG,CAAC;QACd,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAE1B,MAAM,CAAC,CAAC,CAAC;IACX,CAAC;IAyCO,8CAAiB,GAAzB,UAA0B,KAAK;QAC7B,IAAI,OAAO,GAAG,qCAAqC,GAAG,4BAA4B,CAAC;QAEnF,CAAC,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE;YACzC,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;aACf;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;aACf;YACD,aAAa,EAAE;gBACb,QAAQ,EAAE,CAAC;aACZ;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,mBAAmB;aAC1B;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;aACd;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,IAAI;iBACX;aACF;YACD,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,KAAK;oBACX,OAAO,EAAE;wBACP,WAAW,EAAE,OAAO;qBACrB;iBACF,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAEO,gDAAmB,GAA3B,UAA4B,QAAQ;QAClC,+BAA+B;QAC/B,CAAC,CAAC,gBAAgB,CAAC,CAAC,UAAU,CAAC;YAC7B,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;aACf;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,SAAS;gBACf,QAAQ,EAAE,IAAI;aACf;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,6CAA6C;aACpD;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;aACd;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,EAAE;aACT;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,OAAO,EAAE,IAAI;oBACb,IAAI,EAAE,KAAK;iBACZ;gBACD,WAAW,EAAE,IAAI;gBACjB,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,IAAI;aACpB;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,IAAI;iBACX;aACF;YACD,WAAW,EAAE;gBACX,OAAO,EAAE;oBACP,MAAM,EAAE;wBACN,MAAM,EAAE,CAAC;wBACT,MAAM,EAAE;4BACN,KAAK,EAAE;gCACL,OAAO,EAAE,IAAI;gCACb,SAAS,EAAE,kBAAkB;6BAC9B;yBACF;qBACF;oBACD,MAAM,EAAE;wBACN,KAAK,EAAE;4BACL,MAAM,EAAE;gCACN,OAAO,EAAE,KAAK;6BACf;yBACF;qBACF;oBACD,OAAO,EAAE;wBACP,YAAY,EAAE,0BAA0B;wBACxC,WAAW,EAAE,qDAAqD;qBACnE;iBACF;aACF;YACD,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ;iBACf,CAAC;SAEH,CAAC,CAAC;IACL,CAAC;IAEO,mDAAsB,GAA9B,UAA+B,MAAM,EAAE,OAAO;QAC5C,CAAC,CAAC,mBAAmB,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE;YAC9C,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;aACf;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;aACd;YACD,aAAa,EAAE;gBACb,QAAQ,EAAE,CAAC;aACZ;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,mBAAmB;aAC1B;YACD,QAAQ,EAAE;gBACR,IAAI,EAAE,2CAA2C;aAClD;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,oBAAoB,EAAE;oBACpB,WAAW;oBACX,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,IAAI;iBACX;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,MAAM;iBACb;aACF;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,cAAc;iBACrB;gBACD,GAAG,EAAE,CAAC;aACP;YACD,WAAW,EAAE;gBACX,MAAM,EAAE;oBACN,MAAM,EAAE;wBACN,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;YACD,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;iBACf,EAAE;oBACD,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ;iBACf,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAEO,oDAAuB,GAA/B,UAAgC,MAAM;QACpC,IAAI,QAAQ,GAAG,0CAA0C;YACvD,+BAA+B,CAAC;QAElC,CAAC,CAAC,oBAAoB,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE;YAC/C,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;aACf;YACD,aAAa,EAAE;gBACb,QAAQ,EAAE,CAAC;aACZ;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;aACd;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,oBAAoB,EAAE;oBACpB,WAAW;oBACX,KAAK,EAAE,QAAQ;oBACf,IAAI,EAAE,IAAI;iBACX;gBACD,KAAK,EAAE;oBACL,IAAI,EAAE,MAAM;iBACb;aACF;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,UAAU;iBACjB;aACF;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,eAAe;aACtB;YACD,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,eAAe;oBACrB,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE;wBACP,WAAW,EAAE,QAAQ;qBACtB;iBACF,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAEO,0DAA6B,GAArC,UAAsC,MAAM,EAAE,OAAO;QACnD,CAAC,CAAC,0BAA0B,CAAC,CAAC,UAAU,CAAC,YAAY,EAAE;YACrD,OAAO,EAAE;gBACP,OAAO,EAAE,KAAK;aACf;YACD,aAAa,EAAE;gBACb,OAAO,EAAE,KAAK;aACf;YACD,SAAS,EAAE;gBACT,OAAO,EAAE,KAAK;aACf;YACD,SAAS,EAAE;gBACT,OAAO,EAAE,KAAK;aACf;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,mBAAmB;aAC1B;YACD,MAAM,EAAE;gBACN,OAAO,EAAE,IAAI;aACd;YACD,KAAK,EAAE;gBACL,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE;oBACL,IAAI,EAAE,MAAM;iBACb;aACF;YACD,KAAK,EAAE;gBACL,KAAK,EAAE;oBACL,IAAI,EAAE,cAAc;iBACrB;gBACD,GAAG,EAAE,CAAC;aACP;YACD,WAAW,EAAE;gBACX,MAAM,EAAE;oBACN,MAAM,EAAE;wBACN,OAAO,EAAE,IAAI;qBACd;iBACF;aACF;YACD,YAAY,EAAE;gBACZ,aAAa,EAAE,SAAS;gBACxB,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,IAAI;gBACZ,KAAK,EAAE;oBACL,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;iBACf;aACF;YACD,MAAM,EAAE,CAAC;oBACP,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;iBACf,EAAE;oBACD,IAAI,EAAE,gBAAgB;oBACtB,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ;iBACf,CAAC;SACH,CAAC,CAAC;IACL,CAAC;IAIO,oCAAO,GAAf;QAAA,iBAsEC;QArEC,EAAE,CAAC,CAAC,IAAI,CAAC,kBAAkB,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC;YAC9C,qCAAqC;YACrC,IAAI,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC;YAC7B,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,CAAC;YACzB,IAAI,CAAC,YAAY,CAAC,GAAG,GAAG,CAAC,CAAC;YAE1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC,wCAAwC;YAE1D,QAAQ;YACR,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;gBAE1E,2BAA2B;gBAC3B,IAAI,KAAK,GAAG,EAAE,CAAC;gBAEf,4BAA4B;gBAC5B,IAAI,QAAQ,GAAG,EAAE,CAAC;gBAElB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,UAAC,KAAK,EAAE,KAAK;oBACxB,EAAE,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;wBACnB,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;wBAE5D,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC,CAAC,CAAC;gBAEH,KAAI,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;gBAE9B,KAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;gBAEnC,eAAe;gBACf,KAAI,CAAC,IAAI,GAAG,IAAI,CAAC;gBACjB,KAAI,CAAC,MAAM,GAAG,KAAI,CAAC,IAAI,CAAC,MAAM,CAAC;gBAC/B,KAAI,CAAC,aAAa,CAAC,KAAI,CAAC,MAAM,CAAC,CAAC;YAElC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;gBACb,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;YAC7C,CAAC,CAAC,CAAC;YAEH,IAAI,CAAC,eAAe,EAAE,CAAC,IAAI,CAAC;gBAC1B,6CAA6C;gBAC7C,KAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,8BAA8B,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;oBAChG,gBAAgB;oBAChB,IAAI,OAAO,GAAG,IAAI,CAAA;oBAClB,KAAI,CAAC,YAAY,CAAC,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;oBAChD,KAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;oBAC9C,KAAI,CAAC,YAAY,CAAC,EAAE,GAAG,OAAO,CAAC,EAAE,CAAC;oBAClC,KAAI,CAAC,YAAY,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAEpC,IAAI,MAAM,GAAG,EAAE,CAAC;oBAChB,IAAI,OAAO,GAAG,EAAE,CAAC;oBACjB,IAAI,MAAM,GAAG,EAAE,CAAC;oBAEhB,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,UAAC,KAAK,EAAE,KAAK;wBACxB,uEAAuE;wBACvE,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;wBACpC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;wBACtC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;oBAChD,CAAC,CAAC,CAAC;oBAEH,KAAI,CAAC,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;oBAC7C,KAAI,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;oBAErC,KAAI,CAAC,6BAA6B,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBACtD,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;oBACb,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;gBACxD,CAAC,CAAC,CAAA;YACJ,CAAC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAEO,4CAAe,GAAvB;QAAA,iBAOC;QANC,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;YAC5F,KAAI,CAAC,YAAY,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;YACvC,KAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC7C,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACb,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAC;QACxD,CAAC,CAAC,CAAA;IACJ,CAAC;IAGD,qCAAQ,GAAR;QAAA,iBAiBC;QAhBC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;YACzE,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACxC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACb,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,UAAU,CAAC,UAAU,CAAC;YACpB,IAAI,EAAE;gBACJ,YAAY,EAAE,GAAG;aAClB;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,OAAO,EAAE,CAAC;QACf,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,SAAS,CAAC,UAAC,KAAK;YACtF,KAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wCAAW,GAAX;QACE,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,CAAC;IAC9C,CAAC;IAED,yBAAyB;IAElB,uCAAU,GAAjB,UAAkB,IAAS,EAAE,IAA+B;QAA/B,oBAA+B,GAA/B,OAAsB,IAAI,CAAC,IAAI;QAC1D,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC;QAChD,IAAI,GAAG,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAChC,CAAC;IAEM,uCAAU,GAAjB,UAAkB,IAAS,EAAE,MAAW;QACtC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC;QACd,CAAC;QAED,IAAI,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;QAChD,IAAI,UAAU,GAAW,KAAK,CAAC,CAAC;QAChC,IAAI,IAAI,GAAW,KAAK,CAAC,CAAC;QAE1B,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACxC,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC;gBAC3B,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;gBAC7B,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACzB,CAAC;QACH,CAAC;QAED,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;YAChB,MAAM,CAAC,IAAI,CAAC;QACd,CAAC;QAED,iBAAiB;QACjB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAC,QAAa,EAAE,OAAY;YAC3C,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBAC/C,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YAClC,CAAC;YAAC,IAAI,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACtD,MAAM,CAAC,IAAI,KAAK,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACjC,CAAC;YACD,MAAM,CAAC,CAAC,CAAC;QACX,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,0CAAa,GAApB,UAAqB,MAAW,EAAE,IAAgE;QAAhE,oBAAgE,GAAhE,SAAc,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE;QAChG,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YACnB,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,GAAG,IAAI,IAAI,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,GAAG,UAAU,CAAC;QACnF,IAAI,CAAC,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;IAClC,CAAC;IAjeH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,eAAe;YACzB,WAAW,EAAE,0BAA0B;YACvC,SAAS,EAAE;gBACT,yBAAyB;aAC1B;YACD,UAAU,EAAE,CAAC,gCAAkB,EAAE,8BAAc,EAAE,+BAAmB,EAAE,qCAAqB,EAAE,aAAI,EAAE,wBAAe,EAAE,4BAAe,CAAC;SACrI,CAAC;;0BAAA;IA6dF,yBAAC;AAAD,CAAC,AA3dD,IA2dC;AA3dY,0BAAkB,qBA2d9B,CAAA","sourcesContent":["// not really the Angular way:\n/* beautify preserve:start */\ndeclare var $;\ndeclare var Highcharts;\n/* beautify preserve:end */\n\nimport { Component, OnInit } from '@angular/core';\nimport { TAB_DIRECTIVES } from 'ng2-bootstrap/ng2-bootstrap';\nimport { POPOVER_DIRECTIVES } from 'ng2-popover';\nimport { FORM_DIRECTIVES } from '@angular/forms/src/directives' // https://github.com/valor-software/ng2-bootstrap/issues/782\nimport { CORE_DIRECTIVES, NgClass, NgIf } from '@angular/common';\nimport { PAGINATION_DIRECTIVES } from 'ng2-bootstrap/ng2-bootstrap';\nimport { NG_TABLE_DIRECTIVES } from 'ng2-table/ng2-table';\nimport { HttpWrapperService } from '../http-wrapper.service';\nimport { Router } from '@angular/router';\nimport { Observable } from 'rxjs/Rx';\n\n@Component({\n moduleId: module.id,\n selector: 'app-portfolio',\n templateUrl: 'portfolio.component.html',\n styleUrls: [\n 'portfolio.component.css'\n ],\n directives: [POPOVER_DIRECTIVES, TAB_DIRECTIVES, NG_TABLE_DIRECTIVES, PAGINATION_DIRECTIVES, NgIf, CORE_DIRECTIVES, FORM_DIRECTIVES]\n})\n\nexport class PortfolioComponent implements OnInit {\n\n private IDFormatter(id) {\n return \"\" + id + \"\";\n }\n\n private defaultFormatter(value) {\n return value;\n }\n\n private numberFormatter(n) {\n if (!n) {\n return \"\";\n }\n\n var a = \"\" + n;\n a = a.replace(new RegExp(\"^(\\\\d{\" + (a.length % 3 ? a.length % 3 : 0) + \"})(\\\\d{3})\", \"g\"), \"$1 $2\").replace(/(\\d{3})+?/gi, \"$1 \").trim();\n var sep = \",\";\n a = a.replace(/\\s/g, sep);\n\n return a;\n }\n\n public rows: Array < any > = [];\n public columns: Array < any > = [\n // omitting the sort column on each column would result in no default sorting!\n { title: 'ID', name: 'id', sort: '', formatter: this.IDFormatter },\n { title: 'Product', name: 'product', sort: '', formatter: this.defaultFormatter },\n { title: 'Type', name: 'buySell', sort: '', formatter: this.defaultFormatter },\n { title: 'Trade Date', name: 'tradeDate', sort: 'desc', formatter: this.defaultFormatter },\n { title: 'Effective Date', name: 'effectiveDate', sort: '', formatter: this.defaultFormatter },\n { title: 'Maturity Date', name: 'maturityDate', sort: '', formatter: this.defaultFormatter },\n { title: 'Currency', name: 'currency', sort: '', formatter: this.defaultFormatter },\n { title: 'Notional', name: 'notional', sort: '', formatter: this.numberFormatter },\n { title: 'IM Contribution', name: 'im', sort: '', formatter: this.numberFormatter },\n { title: 'PV', name: 'mtm', sort: '', formatter: this.numberFormatter },\n { title: 'Included in summary', name: 'marginedText', sort: '', formatter: this.defaultFormatter }\n ];\n public page: number = 1;\n public itemsPerPage: number = 10;\n public maxSize: number = 5;\n public numPages: number = 1;\n public length: number = 0;\n\n public config: any = {\n paging: true,\n sorting: { columns: this.columns }\n };\n\n private businessDate: string;\n\n private data: Array < any > = [];\n\n private summaryTable: any = {\n product: \"Vanilla IRS\",\n currency: \"EUR\",\n trades: 0,\n notional: 0,\n im: 0,\n mtm: 0\n };\n\n private createTradesChart(TData) {\n var TFormat = 'Date: {point.x:%Y-%m-%d}
' + 'IM: {point.y:,.0f}€';\n\n $('#tradesChart').highcharts('StockChart', {\n credits: {\n enabled: false\n },\n chart: {\n type: 'scatter',\n zoomType: 'xy'\n },\n rangeSelector: {\n selected: 4\n },\n title: {\n text: 'Individual Trades'\n },\n legend: {\n enabled: true\n },\n yAxis: {\n title: {\n text: 'IM'\n }\n },\n series: [{\n name: 'Trade',\n data: TData,\n tooltip: {\n pointFormat: TFormat\n }\n }]\n });\n }\n\n private createIMOverVMChart(IMVMData) {\n // note there's no \"highstocks\"\n $('#IMOverVMChart').highcharts({\n credits: {\n enabled: false\n },\n chart: {\n type: 'scatter',\n zoomType: 'xy'\n },\n title: {\n text: 'Imminent IM over Variation Margin of trades'\n },\n legend: {\n enabled: true\n },\n subtitle: {\n text: ''\n },\n xAxis: {\n title: {\n enabled: true,\n text: 'MTM'\n },\n startOnTick: true,\n endOnTick: true,\n showLastLabel: true\n },\n yAxis: {\n title: {\n text: 'IM'\n }\n },\n plotOptions: {\n scatter: {\n marker: {\n radius: 5,\n states: {\n hover: {\n enabled: true,\n lineColor: 'rgb(100,100,100)'\n }\n }\n },\n states: {\n hover: {\n marker: {\n enabled: false\n }\n }\n },\n tooltip: {\n headerFormat: '{series.name}
',\n pointFormat: 'IM: {point.x:,.0f}€
MTM: {point.x:,.0f}€
'\n }\n }\n },\n series: [{\n name: 'Trade',\n data: IMVMData\n }]\n\n });\n }\n\n private createIMVMHistoryChart(IMData, MTMData) {\n $('#IMVMHistoryChart').highcharts('StockChart', {\n credits: {\n enabled: false\n },\n legend: {\n enabled: true\n },\n rangeSelector: {\n selected: 4\n },\n title: {\n text: 'Portfolio History'\n },\n subtitle: {\n text: 'Initial and Variation Margin Requirements'\n },\n xAxis: {\n type: 'datetime',\n dateTimeLabelFormats: { // don't display the dummy year\n //day: '%d'\n month: '%e. %b',\n year: '%b'\n },\n title: {\n text: 'Date'\n }\n },\n yAxis: {\n title: {\n text: 'Exposure (€)'\n },\n min: 0\n },\n plotOptions: {\n spline: {\n marker: {\n enabled: true\n }\n }\n },\n series: [{\n name: 'Initial Margin',\n data: IMData,\n type: 'column'\n }, {\n name: 'Mark to Market',\n data: MTMData,\n type: 'spline'\n }]\n });\n }\n\n private createActiveTradesChart(ATData) {\n var ATformat = 'Active trades: {point.y:,.0f}
' +\n 'IM: {point.x:,.0f}
';\n\n $('#activeTradesChart').highcharts('StockChart', {\n credits: {\n enabled: false\n },\n rangeSelector: {\n selected: 4\n },\n legend: {\n enabled: true\n },\n xAxis: {\n type: 'datetime',\n dateTimeLabelFormats: { // don't display the dummy year\n //day: '%d'\n month: '%e. %b',\n year: '%b'\n },\n title: {\n text: 'Date'\n }\n },\n yAxis: {\n title: {\n text: 'Quantity'\n }\n },\n title: {\n text: 'Active Trades'\n },\n series: [{\n name: 'Active trades',\n data: ATData,\n tooltip: {\n pointFormat: ATformat\n }\n }]\n });\n }\n\n private createIMVMHistorySummaryChart(IMData, MTMData) {\n $('#IMVMHistorySummaryChart').highcharts('StockChart', {\n credits: {\n enabled: false\n },\n rangeSelector: {\n enabled: false\n },\n navigator: {\n enabled: false\n },\n scrollbar: {\n enabled: false\n },\n title: {\n text: 'Portfolio History'\n },\n legend: {\n enabled: true\n },\n xAxis: {\n type: 'datetime',\n title: {\n text: 'Date'\n }\n },\n yAxis: {\n title: {\n text: 'Exposure (€)'\n },\n min: 0\n },\n plotOptions: {\n spline: {\n marker: {\n enabled: true\n }\n }\n },\n dataGrouping: {\n approximation: \"average\",\n enabled: true,\n forced: true,\n units: [\n ['month', [1]]\n ]\n },\n series: [{\n name: 'Initial Margin',\n data: IMData,\n type: 'column'\n }, {\n name: 'Mark to Market',\n data: MTMData,\n type: 'spline'\n }]\n });\n }\n\n constructor(private httpWrapperService: HttpWrapperService, private router: Router) {}\n\n private getData() {\n if (this.httpWrapperService.getCounterparty()) {\n // re-initialize addittive table sums\n this.summaryTable.trades = 0;\n this.summaryTable.notional = 0;\n this.summaryTable.im = 0;\n this.summaryTable.mtm = 0;\n\n this.data = null; //don't leave old data in case of errors\n\n //trades\n this.httpWrapperService.getWithCounterparty(\"trades\").toPromise().then((data) => {\n\n // trades over time scatter\n var TData = [];\n\n // trades IM over VM scatter\n var IMVMData = [];\n\n $.each(data, (index, value) => {\n if (value.margined) {\n TData.push([new Date(value.tradeDate).getTime(), value.im]);\n\n IMVMData.push([value.im, value.mtm]);\n }\n });\n\n this.createTradesChart(TData);\n\n this.createIMOverVMChart(IMVMData);\n\n // trades table\n this.data = data;\n this.length = this.data.length;\n this.onChangeTable(this.config);\n\n }).catch((error) => {\n console.log(\"Error loading trades\", error);\n });\n\n this.populateSummary().then(() => {\n // portfolio history and active trades charts\n this.httpWrapperService.getWithCounterparty(\"portfolio/history/aggregated\").toPromise().then((data) => {\n // summary table\n let lastDay = data\n this.summaryTable.trades = lastDay.activeTrades;\n this.summaryTable.notional = lastDay.notional;\n this.summaryTable.im = lastDay.im;\n this.summaryTable.mtm = lastDay.mtm;\n\n var IMData = [];\n var MTMData = [];\n var ATData = [];\n\n $.each(data, (index, value) => {\n // new Date(value.date).getTime() when dates are switched to YYYY-MM-DD\n IMData.push([value.date, value.im]);\n MTMData.push([value.date, value.mtm]);\n ATData.push([value.date, value.activeTrades]);\n });\n\n this.createIMVMHistoryChart(IMData, MTMData);\n this.createActiveTradesChart(ATData);\n\n this.createIMVMHistorySummaryChart(IMData, MTMData);\n }).catch((error) => {\n console.log(\"Error loading portfolio history\", error);\n })\n })\n }\n }\n\n private populateSummary() {\n return this.httpWrapperService.getWithCounterparty(\"portfolio/summary\").toPromise().then((data) => {\n this.summaryTable.trades = data.trades;\n this.summaryTable.notional = data.notional;\n }).catch((error) => {\n console.log(\"Error loading portfolio summary\", error);\n })\n }\n\n counterpartySubscription: any;\n ngOnInit() {\n this.httpWrapperService.getAbsolute(\"business-date\").toPromise().then((data) => {\n this.businessDate = data.businessDate;\n }).catch((error) => {\n console.log(\"Error loading business date\", error);\n });\n\n Highcharts.setOptions({\n lang: {\n thousandsSep: ','\n }\n });\n\n this.getData();\n this.counterpartySubscription = this.httpWrapperService.newCounterparty.subscribe((state) => {\n this.getData();\n });\n }\n\n ngOnDestroy() {\n this.counterpartySubscription.unsubscribe();\n }\n\n // table helper functions\n\n public changePage(page: any, data: Array < any > = this.data): Array < any > {\n let start = (page.page - 1) * page.itemsPerPage;\n let end = page.itemsPerPage > -1 ? (start + page.itemsPerPage) : data.length;\n return data.slice(start, end);\n }\n\n public changeSort(data: any, config: any): any {\n if (!config.sorting) {\n return data;\n }\n\n let columns = this.config.sorting.columns || [];\n let columnName: string = void 0;\n let sort: string = void 0;\n\n for (let i = 0; i < columns.length; i++) {\n if (columns[i].sort !== '') {\n columnName = columns[i].name;\n sort = columns[i].sort;\n }\n }\n\n if (!columnName) {\n return data;\n }\n\n // simple sorting\n return data.sort((previous: any, current: any) => {\n if (previous[columnName] > current[columnName]) {\n return sort === 'desc' ? -1 : 1;\n } else if (previous[columnName] < current[columnName]) {\n return sort === 'asc' ? -1 : 1;\n }\n return 0;\n });\n }\n\n public onChangeTable(config: any, page: any = { page: this.page, itemsPerPage: this.itemsPerPage }): any {\n if (config.sorting) {\n Object.assign(this.config.sorting, config.sorting);\n }\n\n let sortedData = this.changeSort(this.data, this.config);\n this.rows = page && config.paging ? this.changePage(page, sortedData) : sortedData;\n this.length = sortedData.length;\n }\n\n // end table helper functions\n\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js deleted file mode 100644 index 61f2c9b7ba..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js +++ /dev/null @@ -1,3 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -//# sourceMappingURL=portfolio.component.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js.map deleted file mode 100644 index 3a1779fd31..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/portfolio/portfolio.component.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"portfolio.component.spec.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/portfolio/portfolio.component.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { By } from '@angular/platform-browser';\nimport { DebugElement } from '@angular/core';\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { PortfolioComponent } from './portfolio.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js deleted file mode 100644 index 8332f84cff..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js.map deleted file mode 100644 index 296ae2a6bb..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/shared/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/shared/index.ts"],"names":[],"mappings":"","sourcesContent":[""]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js deleted file mode 100644 index 8f0ea0442c..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require('./valuations.component')); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js.map deleted file mode 100644 index c2ce92ec00..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/valuations/index.ts"],"names":[],"mappings":";;;;AAAA,iBAAc,wBAAwB,CAAC,EAAA","sourcesContent":["export * from './valuations.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.css b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.css deleted file mode 100644 index b7fc7aadf6..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.css +++ /dev/null @@ -1,17 +0,0 @@ -.panel-heading h3 { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - line-height: normal; - width: 75%; - padding-top: 8px; -} - -.checkbox { - width: 60px; - height: 60px; -} - -th { - white-space: nowrap; -} diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.html deleted file mode 100644 index afcc9343bc..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.html +++ /dev/null @@ -1,336 +0,0 @@ -

Valuations for {{businessDate}}

- -
- -
-
-
-

Portfolio (1/5)

-
- -
- -
-
- -
- -
-

Trades

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeTrades
IR/FX{{data.portfolio.IRFX | number}}
Commodity{{data.portfolio.credit | number}}
Credit{{data.portfolio.commodity | number}}
Equity{{data.portfolio.equity | number}}
Total{{data.portfolio.total | number}}
-
- -
-

Base Currency

- {{data.portfolio.baseCurrency}} -
-
- - -
- - -
- -

Agreed with counterparty

-
- -
- - -
-
- -
-
-

Market Data (2/5)

-
- -
- -
-
- -
- -
-

{{data.marketData.yieldCurves.name}} Yield curves

- - - - - - - - - - - - - - - -
TenorRate
{{v.tenor}}{{v.rate}}
-
- -
-

{{data.marketData.fixings.name}} Fixings

- - - - - - - - - - - - - -
TenorRate
{{v.tenor}}{{v.rate}}
-
- -
-

Market Data Source

-

R3 Sample Oracle

-
- -
- - -
- - -
- -

Agreed with counterparty

-
- -
- - -
-
- -
-
-

Sensitivities (3/5)

-
- -
- -
-
- -
- -
-

Risk Type Delta (Qualifier {{data.sensitivities.currency[0].currency}})

- - - - - - - - - - - - - - - -
TenorEUR-DSCON-BIMMEUR-EURIBOR3M-BIMM
{{v.tenor}}{{v['EUR-DSCON-BIMM'] | number}}{{v['EUR-EURIBOR3M-BIMM'] | number}}
-
- -
- - -
- - -
- -

Agreed with counterparty

-
- -
- - -
- - -
- -
-
-

Initial Margin (4/5)

-
- -
- -
-
- -
- -
-

Post

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeIM
IR/FX{{data.initialMargin.post.IRFX | number}}
Commodity{{data.initialMargin.post.credit | number}}
Credit{{data.initialMargin.post.commodity | number}}
Equity{{data.initialMargin.post.equity | number}}
Total{{data.initialMargin.post.total | number}}
-
- -
-

Call

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TypeIM
IR/FX{{data.initialMargin.call.IRFX | number}}
Commodity{{data.initialMargin.call.credit | number}}
Credit{{data.initialMargin.call.commodity | number}}
Equity{{data.initialMargin.call.equity | number}}
Total{{data.initialMargin.call.total | number}}
-
- -
-

Base Currency

- {{data.portfolio.baseCurrency}} -
- -
- - -
- - -
- -

Agreed with counterparty

-
- -
- - -
- - -
- -
-
-

Confirmation (5/5)

-
- -
- -
- -
-

Joint Confirmation ID

- {{data.confirmation.hash}} -
- - -
- -

Agreed with counterparty

-
- -
- - -
-
- -
-
-
-
-
- -
diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js deleted file mode 100644 index cb27d93a88..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js +++ /dev/null @@ -1,101 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -/* beautify preserve:end */ -var core_1 = require('@angular/core'); -var http_wrapper_service_1 = require('../http-wrapper.service'); -var Rx_1 = require('rxjs/Rx'); -var ValuationsComponent = (function () { - function ValuationsComponent(httpWrapperService) { - this.httpWrapperService = httpWrapperService; - this.data = {}; - this.formattedData = { - sensitivitiesCurves: [] - }; - this.fullData = {}; - } - ValuationsComponent.prototype.startCalculations = function () { - var _this = this; - console.log("Starting calculations"); - this.fullData = {}; - this.data = {}; // outdated data, delete it - this.calculateClicked = true; // show loading spinners - // demo magic - this is to ensure we use the right valuation date - this.httpWrapperService.postWithCounterparty("portfolio/valuations/calculate", { valuationDate: "2016-06-06" }) - .toPromise().then(function (data) { - _this.fullData = data; - _this.businessDate = data.businessDate; // in case it's valuations for a different date now - _this.httpWrapperService.startDelayedTimer(); // demo magic - _this.getData(); - }); - }; - ValuationsComponent.prototype.getData = function () { - this.data = this.httpWrapperService.getDelayedData(this.fullData); - if (this.data && this.data.sensitivities) { - this.formattedData.sensitivitiesCurves = this.getSensitivitiesCurves(this.data.sensitivities); - } - // scroll to bottom of page - var spinners = document.getElementById("loadingSpinners"); - if (spinners) { - setTimeout(function () { - $("html, body").animate({ scrollTop: $(document).height() }, 1000); - }, 100); // wait for spinners to have gone below latest element - } - }; - // TODO: make this independent from the actual curve names - ValuationsComponent.prototype.getSensitivitiesCurves = function (sensitivities) { - var formattedSensitivities = []; // formattedSensitivities - // loop on the first curve, knowing that the other curves have the same values - for (var key in sensitivities.curves["EUR-DSCON-BIMM"]) { - if (sensitivities.curves["EUR-DSCON-BIMM"].hasOwnProperty(key)) { - var obj = { - tenor: key, - "EUR-DSCON-BIMM": sensitivities.curves["EUR-DSCON-BIMM"][key], - "EUR-EURIBOR3M-BIMM": sensitivities.curves["EUR-EURIBOR3M-BIMM"][key] - }; - formattedSensitivities.push(obj); - } - } - return formattedSensitivities; - }; - ValuationsComponent.prototype.ngOnInit = function () { - var _this = this; - this.httpWrapperService.getAbsolute("business-date").toPromise().then(function (data) { - _this.businessDate = data.businessDate; - }).catch(function (error) { - console.log("Error loading business date", error); - }); - // check for new data periodically - // higher timeout because makes debugging annoying, put to 2000 for production - this.timer = Rx_1.Observable.timer(0, 2000); - this.timerSubscription = (this.timer.subscribe(function () { return _this.getData(); })); - // but also check for new data when counterparty changes - this.counterpartySubscription = this.httpWrapperService.newCounterparty.subscribe(function (state) { - _this.getData(); - }); - }; - ValuationsComponent.prototype.ngOnDestroy = function () { - this.timerSubscription.unsubscribe(); - this.counterpartySubscription.unsubscribe(); - }; - ValuationsComponent = __decorate([ - core_1.Component({ - moduleId: module.id, - selector: 'app-valuations', - templateUrl: 'valuations.component.html', - styleUrls: ['valuations.component.css'], - directives: [] - }), - __metadata('design:paramtypes', [http_wrapper_service_1.HttpWrapperService]) - ], ValuationsComponent); - return ValuationsComponent; -}()); -exports.ValuationsComponent = ValuationsComponent; -//# sourceMappingURL=valuations.component.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js.map deleted file mode 100644 index 0285721250..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"valuations.component.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/valuations/valuations.component.ts"],"names":[],"mappings":";;;;;;;;;;AAEA,2BAA2B;AAE3B,qBAAkC,eAAe,CAAC,CAAA;AAClD,qCAAmC,yBAAyB,CAAC,CAAA;AAC7D,mBAA2B,SAAS,CAAC,CAAA;AASrC;IAiEE,6BAAoB,kBAAsC;QAAtC,uBAAkB,GAAlB,kBAAkB,CAAoB;QAhElD,SAAI,GAAQ,EAAE,CAAC;QACf,kBAAa,GAAQ;YAC3B,mBAAmB,EAAE,EAAE;SACxB,CAAC;QACM,aAAQ,GAAQ,EAAE,CAAC;IA4DkC,CAAC;IAnDtD,+CAAiB,GAAzB;QAAA,iBAcC;QAbC,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAA;QACpC,IAAI,CAAC,QAAQ,GAAG,EAAE,CAAC;QACnB,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,2BAA2B;QAC3C,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC,wBAAwB;QAEtD,iEAAiE;QACjE,IAAI,CAAC,kBAAkB,CAAC,oBAAoB,CAAC,gCAAgC,EAAE,EAAE,aAAa,EAAE,YAAY,EAAE,CAAE;aAC7G,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;YACrB,KAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,mDAAmD;YAC1F,KAAI,CAAC,kBAAkB,CAAC,iBAAiB,EAAE,CAAC,CAAC,aAAa;YAC1D,KAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,qCAAO,GAAf;QACE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,kBAAkB,CAAC,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAElE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC;YACzC,IAAI,CAAC,aAAa,CAAC,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAChG,CAAC;QAED,2BAA2B;QAC3B,IAAI,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;QAC1D,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;YACb,UAAU,CAAC;gBACT,CAAC,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;YACrE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,sDAAsD;QACjE,CAAC;IACH,CAAC;IAED,0DAA0D;IAClD,oDAAsB,GAA9B,UAA+B,aAAa;QAC1C,IAAI,sBAAsB,GAAG,EAAE,CAAC,CAAC,yBAAyB;QAE1D,8EAA8E;QAC9E,GAAG,CAAC,CAAC,IAAI,GAAG,IAAI,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC;YACvD,EAAE,CAAC,CAAC,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/D,IAAI,GAAG,GAAG;oBACR,KAAK,EAAE,GAAG;oBACV,gBAAgB,EAAE,aAAa,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC;oBAC7D,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,GAAG,CAAC;iBACtE,CAAC;gBACF,sBAAsB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;QACH,CAAC;QAED,MAAM,CAAC,sBAAsB,CAAC;IAChC,CAAC;IAID,sCAAQ,GAAR;QAAA,iBAiBC;QAhBC,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,UAAC,IAAI;YACzE,KAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;QACxC,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,KAAK;YACb,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,kCAAkC;QAClC,8EAA8E;QAC9E,IAAI,CAAC,KAAK,GAAG,eAAU,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;QACvC,IAAI,CAAC,iBAAiB,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,cAAM,OAAA,KAAI,CAAC,OAAO,EAAE,EAAd,CAAc,CAAC,CAAC,CAAC;QAEtE,wDAAwD;QACxD,IAAI,CAAC,wBAAwB,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,SAAS,CAAC,UAAC,KAAK;YACtF,KAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IAEL,CAAC;IAED,yCAAW,GAAX;QACE,IAAI,CAAC,iBAAiB,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,CAAC,wBAAwB,CAAC,WAAW,EAAE,CAAC;IAC9C,CAAC;IAhGH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,gBAAgB;YAC1B,WAAW,EAAE,2BAA2B;YACxC,SAAS,EAAE,CAAC,0BAA0B,CAAC;YACvC,UAAU,EAAE,EAAE;SACf,CAAC;;2BAAA;IA4FF,0BAAC;AAAD,CAAC,AA3FD,IA2FC;AA3FY,2BAAmB,sBA2F/B,CAAA","sourcesContent":["/* beautify preserve:start */\ndeclare var $;\n/* beautify preserve:end */\n\nimport { Component, OnInit } from '@angular/core';\nimport { HttpWrapperService } from '../http-wrapper.service';\nimport { Observable } from 'rxjs/Rx';\n\n@Component({\n moduleId: module.id,\n selector: 'app-valuations',\n templateUrl: 'valuations.component.html',\n styleUrls: ['valuations.component.css'],\n directives: []\n})\nexport class ValuationsComponent implements OnInit {\n private data: any = {};\n private formattedData: any = {\n sensitivitiesCurves: []\n };\n private fullData: any = {};\n private businessDate: string;\n private timer;\n private timerSubscription;\n private counterpartySubscription;\n\n // show loading spinner when clicked and data is not all received\n private calculateClicked: boolean;\n\n private startCalculations() {\n console.log(\"Starting calculations\")\n this.fullData = {};\n this.data = {}; // outdated data, delete it\n this.calculateClicked = true; // show loading spinners\n\n // demo magic - this is to ensure we use the right valuation date\n this.httpWrapperService.postWithCounterparty(\"portfolio/valuations/calculate\", { valuationDate: \"2016-06-06\" } )\n .toPromise().then((data) => {\n this.fullData = data;\n this.businessDate = data.businessDate; // in case it's valuations for a different date now\n this.httpWrapperService.startDelayedTimer(); // demo magic\n this.getData();\n });\n }\n\n private getData() {\n this.data = this.httpWrapperService.getDelayedData(this.fullData);\n\n if (this.data && this.data.sensitivities) {\n this.formattedData.sensitivitiesCurves = this.getSensitivitiesCurves(this.data.sensitivities);\n }\n\n // scroll to bottom of page\n let spinners = document.getElementById(\"loadingSpinners\");\n if (spinners) {\n setTimeout(() => {\n $(\"html, body\").animate({ scrollTop: $(document).height() }, 1000);\n }, 100); // wait for spinners to have gone below latest element\n }\n }\n\n // TODO: make this independent from the actual curve names\n private getSensitivitiesCurves(sensitivities) {\n let formattedSensitivities = []; // formattedSensitivities\n\n // loop on the first curve, knowing that the other curves have the same values\n for (let key in sensitivities.curves[\"EUR-DSCON-BIMM\"]) {\n if (sensitivities.curves[\"EUR-DSCON-BIMM\"].hasOwnProperty(key)) {\n let obj = {\n tenor: key, //3M, 6M etc...\n \"EUR-DSCON-BIMM\": sensitivities.curves[\"EUR-DSCON-BIMM\"][key],\n \"EUR-EURIBOR3M-BIMM\": sensitivities.curves[\"EUR-EURIBOR3M-BIMM\"][key]\n };\n formattedSensitivities.push(obj);\n }\n }\n\n return formattedSensitivities;\n }\n\n constructor(private httpWrapperService: HttpWrapperService) {}\n\n ngOnInit() {\n this.httpWrapperService.getAbsolute(\"business-date\").toPromise().then((data) => {\n this.businessDate = data.businessDate;\n }).catch((error) => {\n console.log(\"Error loading business date\", error);\n });\n\n // check for new data periodically\n // higher timeout because makes debugging annoying, put to 2000 for production\n this.timer = Observable.timer(0, 2000);\n this.timerSubscription = (this.timer.subscribe(() => this.getData()));\n\n // but also check for new data when counterparty changes\n this.counterpartySubscription = this.httpWrapperService.newCounterparty.subscribe((state) => {\n this.getData();\n });\n\n }\n\n ngOnDestroy() {\n this.timerSubscription.unsubscribe();\n this.counterpartySubscription.unsubscribe();\n }\n\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js deleted file mode 100644 index db91fb67e4..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js +++ /dev/null @@ -1,7 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -describe('Component: Valuations', function () { - it('should create an instance', function () { - }); -}); -//# sourceMappingURL=valuations.component.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js.map deleted file mode 100644 index 4fb63fd824..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/valuations/valuations.component.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"valuations.component.spec.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/valuations/valuations.component.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAOvC,QAAQ,CAAC,uBAAuB,EAAE;IAChC,EAAE,CAAC,2BAA2B,EAAE;IAChC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { By } from '@angular/platform-browser';\nimport { DebugElement } from '@angular/core';\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { ValuationsComponent } from './valuations.component';\n\ndescribe('Component: Valuations', () => {\n it('should create an instance', () => {\n });\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js deleted file mode 100644 index 822273e9dc..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js +++ /dev/null @@ -1,6 +0,0 @@ -"use strict"; -function __export(m) { - for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; -} -__export(require('./view-trade.component')); -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js.map deleted file mode 100644 index 2dcf1c1386..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/view-trade/index.ts"],"names":[],"mappings":";;;;AAAA,iBAAc,wBAAwB,CAAC,EAAA","sourcesContent":["export * from './view-trade.component';\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js deleted file mode 100644 index 8332f84cff..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js +++ /dev/null @@ -1 +0,0 @@ -//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js.map deleted file mode 100644 index 52f64b1e74..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/shared/index.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/view-trade/shared/index.ts"],"names":[],"mappings":"","sourcesContent":[""]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.css b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.css deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.html deleted file mode 100644 index 068a5b6708..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.html +++ /dev/null @@ -1,206 +0,0 @@ -
-
- - - - - - - - - - - - - - - - - - - - - - - - - -
Common Information
StatusConfirmed
Trade ID{{deal.ref}}
Valuation Date{{deal.common.valuationDate}}
Interest Rates - {{deal.common.interestRate.name}} with tenor {{deal.common.interestRate.tenor.name}} via oracle {{deal.common.interestRate.oracle}} -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Fixed Leg
Payer{{deal.fixedLeg.fixedRatePayer}}
Notional{{deal.fixedLeg.notional.quantity | number}} {{deal.fixedLeg.notional.token}}
Payment Frequency{{deal.fixedLeg.paymentFrequency}}
Effective From{{deal.fixedLeg.effectiveDate}}
Fixed Rate - - {{deal.fixedLeg.fixedRate.value}}% -
Terminates{{deal.fixedLeg.terminationDate}}
Payment Rule{{deal.fixedLeg.paymentRule}}
Payment Calendars - - {{calendar}}, - -
-
- -
- - - - - - -
{{date}}
-
-
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Floating Leg
Payer{{deal.floatingLeg.floatingRatePayer}}
Notional{{deal.floatingLeg.notional.quantity | number}} {{deal.floatingLeg.notional.token}}
Payment Frequency{{deal.floatingLeg.paymentFrequency}}
Effective From{{deal.floatingLeg.effectiveDate}}
Index{{deal.floatingLeg.index}}
Terminates{{deal.floatingLeg.terminationDate}}
Payment Rule{{deal.floatingLeg.paymentRule}}
Payment Calendars - - {{calendar}} - , - -
-
- -
- - - - - - -
{{date}}
-
-
-
Fixing Calendars - - {{calendar}}, - -
-
- -
- - - - - - -
{{date}}
-
-
-
-
-
-
diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js deleted file mode 100644 index ba61400984..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js +++ /dev/null @@ -1,66 +0,0 @@ -"use strict"; -var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); - else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; -}; -var __metadata = (this && this.__metadata) || function (k, v) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); -}; -var core_1 = require('@angular/core'); -var node_service_1 = require('../node.service'); -var router_1 = require('@angular/router'); -var ViewTradeComponent = (function () { - function ViewTradeComponent(nodeService, route) { - this.nodeService = nodeService; - this.route = route; - this.deal = { - fixedLeg: { - notional: {}, - fixedRate: {}, - paymentCalendar: {} - }, - floatingLeg: { - notional: {}, - paymentCalendar: {}, - fixingCalendar: {} - }, - common: { - interestRate: { - tenor: {} - } - } - }; - } - ViewTradeComponent.prototype.ngOnInit = function () { - var _this = this; - this.route.params.map(function (params) { return params['tradeId']; }).subscribe(function (tradeId) { - _this.showDeal(tradeId); - }); - }; - ViewTradeComponent.prototype.showDeal = function (tradeId) { - var _this = this; - this.nodeService.getDeal(tradeId) - .then(function (deal) { - _this.deal = deal; - }) - .catch(function (err) { - console.error(err); - }); - }; - ViewTradeComponent = __decorate([ - core_1.Component({ - moduleId: module.id, - selector: 'app-view-trade', - templateUrl: 'view-trade.component.html', - styleUrls: ['../app.component.css', 'view-trade.component.css'], - providers: [node_service_1.NodeService], - directives: [router_1.ROUTER_DIRECTIVES] // necessary for routerLink - }), - __metadata('design:paramtypes', [node_service_1.NodeService, router_1.ActivatedRoute]) - ], ViewTradeComponent); - return ViewTradeComponent; -}()); -exports.ViewTradeComponent = ViewTradeComponent; -//# sourceMappingURL=view-trade.component.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js.map deleted file mode 100644 index ec999b6a19..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"view-trade.component.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/view-trade/view-trade.component.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,qBAAkC,eAAe,CAAC,CAAA;AAClD,6BAA4B,iBAAiB,CAAC,CAAA;AAC9C,uBAAkD,iBAAiB,CAAC,CAAA;AAUpE;IAmBE,4BAAoB,WAAwB,EAAU,KAAqB;QAAvD,gBAAW,GAAX,WAAW,CAAa;QAAU,UAAK,GAAL,KAAK,CAAgB;QAlB3E,SAAI,GAAW;YACb,QAAQ,EAAE;gBACR,QAAQ,EAAE,EAAE;gBACZ,SAAS,EAAE,EAAE;gBACb,eAAe,EAAE,EAAE;aACpB;YACD,WAAW,EAAE;gBACX,QAAQ,EAAE,EAAE;gBACZ,eAAe,EAAE,EAAE;gBACnB,cAAc,EAAE,EAAE;aACnB;YACD,MAAM,EAAE;gBACN,YAAY,EAAE;oBACZ,KAAK,EAAE,EAAE;iBACV;aACF;SACF,CAAC;IAIF,CAAC;IAED,qCAAQ,GAAR;QAAA,iBAIC;QAHC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,UAAA,MAAM,IAAI,OAAA,MAAM,CAAC,SAAS,CAAC,EAAjB,CAAiB,CAAC,CAAC,SAAS,CAAC,UAAC,OAAO;YACnE,KAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC;IAED,qCAAQ,GAAR,UAAS,OAAe;QAAxB,iBAQC;QAPC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;aAC9B,IAAI,CAAC,UAAC,IAAI;YACT,KAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,CAAC,CAAC;aACD,KAAK,CAAC,UAAC,GAAG;YACT,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;IACP,CAAC;IA7CH;QAAC,gBAAS,CAAC;YACT,QAAQ,EAAE,MAAM,CAAC,EAAE;YACnB,QAAQ,EAAE,gBAAgB;YAC1B,WAAW,EAAE,2BAA2B;YACxC,SAAS,EAAE,CAAC,sBAAsB,EAAE,0BAA0B,CAAC;YAC/D,SAAS,EAAE,CAAC,0BAAW,CAAC;YACxB,UAAU,EAAE,CAAC,0BAAiB,CAAC,CAAC,2BAA2B;SAC5D,CAAC;;0BAAA;IAuCF,yBAAC;AAAD,CAAC,AAtCD,IAsCC;AAtCY,0BAAkB,qBAsC9B,CAAA","sourcesContent":["import { Component, OnInit } from '@angular/core';\nimport { NodeService } from '../node.service';\nimport { ROUTER_DIRECTIVES, ActivatedRoute } from '@angular/router';\n\n@Component({\n moduleId: module.id,\n selector: 'app-view-trade',\n templateUrl: 'view-trade.component.html',\n styleUrls: ['../app.component.css', 'view-trade.component.css'],\n providers: [NodeService],\n directives: [ROUTER_DIRECTIVES] // necessary for routerLink\n})\nexport class ViewTradeComponent implements OnInit {\n deal: Object = {\n fixedLeg: {\n notional: {},\n fixedRate: {},\n paymentCalendar: {}\n },\n floatingLeg: {\n notional: {},\n paymentCalendar: {},\n fixingCalendar: {}\n },\n common: {\n interestRate: {\n tenor: {}\n }\n }\n };\n\n constructor(private nodeService: NodeService, private route: ActivatedRoute) {\n\n }\n\n ngOnInit() {\n this.route.params.map(params => params['tradeId']).subscribe((tradeId) => {\n this.showDeal(tradeId);\n });\n }\n\n showDeal(tradeId: string) {\n this.nodeService.getDeal(tradeId)\n .then((deal) => {\n this.deal = deal;\n })\n .catch((err) => {\n console.error(err);\n });\n }\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js deleted file mode 100644 index dda60dee81..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js +++ /dev/null @@ -1,9 +0,0 @@ -/* tslint:disable:no-unused-variable */ -"use strict"; -describe('Component: ViewTrade', function () { - it('should create an instance', function () { - //let component = new ViewTradeComponent(); - //expect(component).toBeTruthy(); - }); -}); -//# sourceMappingURL=view-trade.component.spec.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js.map deleted file mode 100644 index e7fc9200f7..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/view-trade/view-trade.component.spec.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"view-trade.component.spec.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/view-trade/view-trade.component.spec.ts"],"names":[],"mappings":"AAAA,uCAAuC;;AAOvC,QAAQ,CAAC,sBAAsB,EAAE;IAC/B,EAAE,CAAC,2BAA2B,EAAE;QAC9B,2CAA2C;QAC3C,iCAAiC;IACnC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC","sourcesContent":["/* tslint:disable:no-unused-variable */\n\nimport { By } from '@angular/platform-browser';\nimport { DebugElement } from '@angular/core';\nimport { addProviders, async, inject } from '@angular/core/testing';\nimport { ViewTradeComponent } from './view-trade.component';\n\ndescribe('Component: ViewTrade', () => {\n it('should create an instance', () => {\n //let component = new ViewTradeComponent();\n //expect(component).toBeTruthy();\n });\n});\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js deleted file mode 100644 index abd9c9a595..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -var CommonViewModel = (function () { - function CommonViewModel() { - this.baseCurrency = "EUR"; - this.effectiveDate = "2016-02-11"; - this.terminationDate = "2026-02-11"; - this.eligibleCreditSupport = "Cash in an Eligible Currency"; - this.independentAmounts = { - quantity: 0 - }; - this.threshold = { - quantity: 0 - }; - this.minimumTransferAmount = { - quantity: 25000000 - }; - this.rounding = { - quantity: 1000000 - }; - this.valuationDate = "Every Local Business Day"; - this.notificationTime = "2:00pm London"; - this.resolutionTime = "2:00pm London time on the first LocalBusiness Day following the date on which the notice is given"; - this.interestRate = { - oracle: "Rates Service Provider", - tenor: { - name: "6M" - }, - ratioUnit: null, - name: "EONIA" - }; - this.addressForTransfers = ""; - this.exposure = {}; - this.localBusinessDay = ["London", "NewYork"]; - this.dailyInterestAmount = "(CashAmount * InterestRate ) / (fixedLeg.notional.token.currencyCode.equals('GBP')) ? 365 : 360"; - } - return CommonViewModel; -}()); -exports.CommonViewModel = CommonViewModel; -//# sourceMappingURL=CommonViewModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js.map deleted file mode 100644 index 643a5dbefa..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/CommonViewModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"CommonViewModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/viewmodel/CommonViewModel.ts"],"names":[],"mappings":";AAAA;IAAA;QACE,iBAAY,GAAG,KAAK,CAAC;QACrB,kBAAa,GAAG,YAAY,CAAC;QAC7B,oBAAe,GAAG,YAAY,CAAC;QAC/B,0BAAqB,GAAG,8BAA8B,CAAC;QACvD,uBAAkB,GAAG;YACjB,QAAQ,EAAE,CAAC;SACd,CAAC;QACF,cAAS,GAAG;YACR,QAAQ,EAAE,CAAC;SACd,CAAC;QACF,0BAAqB,GAAG;YACpB,QAAQ,EAAE,QAAQ;SACrB,CAAC;QACF,aAAQ,GAAG;YACP,QAAQ,EAAE,OAAO;SACpB,CAAC;QACF,kBAAa,GAAG,0BAA0B,CAAC;QAC3C,qBAAgB,GAAG,eAAe,CAAC;QACnC,mBAAc,GAAG,mGAAmG,CAAC;QACrH,iBAAY,GAAG;YACX,MAAM,EAAE,wBAAwB;YAChC,KAAK,EAAE;gBACH,IAAI,EAAE,IAAI;aACb;YACD,SAAS,EAAE,IAAI;YACf,IAAI,EAAE,OAAO;SAChB,CAAC;QACF,wBAAmB,GAAG,EAAE,CAAC;QACzB,aAAQ,GAAG,EAAE,CAAC;QACd,qBAAgB,GAAG,CAAE,QAAQ,EAAG,SAAS,CAAE,CAAC;QAC5C,wBAAmB,GAAG,iGAAiG,CAAC;IAC1H,CAAC;IAAD,sBAAC;AAAD,CAAC,AAhCD,IAgCC;AAhCY,uBAAe,kBAgC3B,CAAA","sourcesContent":["export class CommonViewModel {\n baseCurrency = \"EUR\";\n effectiveDate = \"2016-02-11\";\n terminationDate = \"2026-02-11\";\n eligibleCreditSupport = \"Cash in an Eligible Currency\";\n independentAmounts = {\n quantity: 0\n };\n threshold = {\n quantity: 0\n };\n minimumTransferAmount = {\n quantity: 25000000\n };\n rounding = {\n quantity: 1000000\n };\n valuationDate = \"Every Local Business Day\";\n notificationTime = \"2:00pm London\";\n resolutionTime = \"2:00pm London time on the first LocalBusiness Day following the date on which the notice is given\";\n interestRate = {\n oracle: \"Rates Service Provider\",\n tenor: {\n name: \"6M\"\n },\n ratioUnit: null,\n name: \"EONIA\"\n };\n addressForTransfers = \"\";\n exposure = {};\n localBusinessDay = [ \"London\" , \"NewYork\" ];\n dailyInterestAmount = \"(CashAmount * InterestRate ) / (fixedLeg.notional.token.currencyCode.equals('GBP')) ? 365 : 360\";\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js deleted file mode 100644 index ccb4d97de8..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js +++ /dev/null @@ -1,14 +0,0 @@ -"use strict"; -var FixedLegViewModel_1 = require('./FixedLegViewModel'); -var FloatingLegViewModel_1 = require('./FloatingLegViewModel'); -var CommonViewModel_1 = require('./CommonViewModel'); -var DealViewModel = (function () { - function DealViewModel() { - this.fixedLeg = new FixedLegViewModel_1.FixedLegViewModel(); - this.floatingLeg = new FloatingLegViewModel_1.FloatingLegViewModel(); - this.common = new CommonViewModel_1.CommonViewModel(); - } - return DealViewModel; -}()); -exports.DealViewModel = DealViewModel; -//# sourceMappingURL=DealViewModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js.map deleted file mode 100644 index 63db4778f5..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/DealViewModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"DealViewModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/viewmodel/DealViewModel.ts"],"names":[],"mappings":";AAAA,kCAAkC,qBAClC,CAAC,CADsD;AACvD,qCAAqC,wBACrC,CAAC,CAD4D;AAC7D,gCAAgC,mBAEhC,CAAC,CAFkD;AAEnD;IACE;QAEA,aAAQ,GAAG,IAAI,qCAAiB,EAAE,CAAC;QACnC,gBAAW,GAAG,IAAI,2CAAoB,EAAE,CAAC;QACzC,WAAM,GAAG,IAAI,iCAAe,EAAE,CAAC;IAJhB,CAAC;IAKlB,oBAAC;AAAD,CAAC,AAND,IAMC;AANY,qBAAa,gBAMzB,CAAA","sourcesContent":["import { FixedLegViewModel } from './FixedLegViewModel'\nimport { FloatingLegViewModel } from './FloatingLegViewModel'\nimport { CommonViewModel } from './CommonViewModel'\n\nexport class DealViewModel {\n constructor() {}\n\n fixedLeg = new FixedLegViewModel();\n floatingLeg = new FloatingLegViewModel();\n common = new CommonViewModel();\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js deleted file mode 100644 index 793a319f1b..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js +++ /dev/null @@ -1,20 +0,0 @@ -"use strict"; -var FixedLegViewModel = (function () { - function FixedLegViewModel() { - this.fixedRatePayer = "O=Bank A,L=London,C=GB"; - this.notional = { - quantity: 2500000000 - }; - this.paymentFrequency = "SemiAnnual"; - this.fixedRate = "1.676"; - this.dayCountBasis = "ACT/360"; - this.rollConvention = "ModifiedFollowing"; - this.dayInMonth = 10; - this.paymentRule = "InArrears"; - this.paymentDelay = "0"; - this.interestPeriodAdjustment = "Adjusted"; - } - return FixedLegViewModel; -}()); -exports.FixedLegViewModel = FixedLegViewModel; -//# sourceMappingURL=FixedLegViewModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js.map deleted file mode 100644 index 654543c58d..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FixedLegViewModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FixedLegViewModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/viewmodel/FixedLegViewModel.ts"],"names":[],"mappings":";AAAA;IACE;QAEA,mBAAc,GAAG,kCAAkC,CAAC;QACpD,aAAQ,GAAW;YACf,QAAQ,EAAE,UAAU;SACvB,CAAC;QACF,qBAAgB,GAAG,YAAY,CAAC;QAGhC,cAAS,GAAG,OAAO,CAAC;QACpB,kBAAa,GAAG,SAAS,CAAC;QAC1B,mBAAc,GAAG,mBAAmB,CAAC;QACrC,eAAU,GAAW,EAAE,CAAC;QACxB,gBAAW,GAAG,WAAW,CAAC;QAC1B,iBAAY,GAAG,GAAG,CAAC;QACnB,6BAAwB,GAAG,UAAU,CAAC;IAftB,CAAC;IAgBnB,wBAAC;AAAD,CAAC,AAjBD,IAiBC;AAjBY,yBAAiB,oBAiB7B,CAAA","sourcesContent":["export class FixedLegViewModel {\n constructor() { }\n\n fixedRatePayer = \"CN=Bank A,O=Bank A,L=London,C=GB\";\n notional: Object = {\n quantity: 2500000000\n };\n paymentFrequency = \"SemiAnnual\";\n effectiveDateAdjustment: any;\n terminationDateAdjustment: any;\n fixedRate = \"1.676\";\n dayCountBasis = \"ACT/360\";\n rollConvention = \"ModifiedFollowing\";\n dayInMonth: Number = 10;\n paymentRule = \"InArrears\";\n paymentDelay = \"0\";\n interestPeriodAdjustment = \"Adjusted\";\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js deleted file mode 100644 index c6f59c63af..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js +++ /dev/null @@ -1,28 +0,0 @@ -"use strict"; -var FloatingLegViewModel = (function () { - function FloatingLegViewModel() { - this.floatingRatePayer = "CN=Bank B,O=Bank B,L=New York,C=US"; - this.notional = { - quantity: 2500000000 - }; - this.paymentFrequency = "Quarterly"; - this.dayCountBasis = "ACT/360"; - this.rollConvention = "ModifiedFollowing"; - this.fixingRollConvention = "ModifiedFollowing"; - this.dayInMonth = 10; - this.resetDayInMonth = 10; - this.paymentRule = "InArrears"; - this.paymentDelay = "0"; - this.interestPeriodAdjustment = "Adjusted"; - this.fixingPeriodOffset = 2; - this.resetRule = "InAdvance"; - this.fixingsPerPayment = "Quarterly"; - this.indexSource = "Rates Service Provider"; - this.indexTenor = { - name: "3M" - }; - } - return FloatingLegViewModel; -}()); -exports.FloatingLegViewModel = FloatingLegViewModel; -//# sourceMappingURL=FloatingLegViewModel.js.map \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js.map b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js.map deleted file mode 100644 index f97a9987be..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/app/viewmodel/FloatingLegViewModel.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"FloatingLegViewModel.js","sourceRoot":"","sources":["../../home/arc/proj ects/corda/samples/simm-valuation-demo/src/main/web/tmp/broccoli_type_script_compiler-input_base_path-q9SObyK6.tmp/0/src/app/viewmodel/FloatingLegViewModel.ts"],"names":[],"mappings":";AAAA;IACE;QAEA,sBAAiB,GAAG,oCAAoC,CAAC;QACzD,aAAQ,GAAW;YAChB,QAAQ,EAAE,UAAU;SACtB,CAAC;QACF,qBAAgB,GAAG,WAAW,CAAC;QAG/B,kBAAa,GAAG,SAAS,CAAC;QAC1B,mBAAc,GAAG,mBAAmB,CAAC;QACrC,yBAAoB,GAAG,mBAAmB,CAAC;QAC3C,eAAU,GAAW,EAAE,CAAC;QACxB,oBAAe,GAAW,EAAE,CAAC;QAC7B,gBAAW,GAAG,WAAW,CAAC;QAC1B,iBAAY,GAAG,GAAG,CAAC;QACnB,6BAAwB,GAAG,UAAU,CAAC;QACtC,uBAAkB,GAAW,CAAC,CAAC;QAC/B,cAAS,GAAG,WAAW,CAAC;QACxB,sBAAiB,GAAG,WAAW,CAAC;QAChC,gBAAW,GAAG,wBAAwB,CAAC;QACvC,eAAU,GAAG;YACV,IAAI,EAAE,IAAI;SACZ,CAAC;IAvBc,CAAC;IAwBnB,2BAAC;AAAD,CAAC,AAzBD,IAyBC;AAzBY,4BAAoB,uBAyBhC,CAAA","sourcesContent":["export class FloatingLegViewModel {\n constructor() { }\n\n floatingRatePayer = \"CN=Bank B,O=Bank B,L=New York,C=US\";\n notional: Object = {\n quantity: 2500000000\n };\n paymentFrequency = \"Quarterly\";\n effectiveDateAdjustment: any;\n terminationDateAdjustment: any;\n dayCountBasis = \"ACT/360\";\n rollConvention = \"ModifiedFollowing\";\n fixingRollConvention = \"ModifiedFollowing\";\n dayInMonth: Number = 10;\n resetDayInMonth: Number = 10;\n paymentRule = \"InArrears\";\n paymentDelay = \"0\";\n interestPeriodAdjustment = \"Adjusted\";\n fixingPeriodOffset: Number = 2;\n resetRule = \"InAdvance\";\n fixingsPerPayment = \"Quarterly\";\n indexSource = \"Rates Service Provider\";\n indexTenor = {\n name: \"3M\"\n };\n}\n"]} \ No newline at end of file diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/checkbox.png b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/checkbox.png deleted file mode 100644 index 1b1b03ba31c1e7fcce86ea6db5b79f0575a373ba..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16080 zcmX9_c_38Z+rM|l*q5=(l4L|=&r-^gEK^ysmOT~Ow?wuXq==-ElqJ4pX^1FWlDRUa z4J}9!lafLVl6B_3XMXQr>C8RnJlpv^%XvP`HV~G}gwJKl{7@ktj_F{XyUAC$#U#5yhq=8SWx!i2sIY_HrNWBj9D+&zK-#S9lj8x$)vpCCTda%SWzT@>r z%%BkT{88=txIhOtPYThAbOa*;8DSFD?9b~u4b@0P6I7C9Bp(xIB?6ecP`p-nf zKmCVemPh{~?p&SopUIq`Ue6SFhA}{9LCm z#l^_%(0ze;(}v;`orMYB=3gLuIvRv*q^=Mi*ib5>OR*jJ;paM}LOreuxyX~1Xur7o zE}zo-!bHk?h<;<=A34F8oNK#3!a*2wL3SWE4l7NdT2Ly^rpOK-IE%4%zCdR4kYzSo zA;k#PlTxuGK{V2o*())^wIK)j_n}i{ldPxLChmI}C zAA~kLGF3p>8PTuWhpg@BPO9}SC9}E6bHOOe>-D9ue<#r?_WpKz;UplszbEa?*Whj3 z=rVFCwXl%AMj+Ny#UkhFbL5CZ1+anj*q@7Z?ekk=#Bx63mzxB91k zU6K#ZTMr`d`(!56@b}A4*~}ZgiwiNV_8)V6jAle%;^}$KKi)-|r=pdZowt+UP8UHh zsynX00CH{zix~@-+?+glrIpn0fA!L4%Epqzu0>YjiL_PylFg~Y>0s!Xh5Q_)*n*)- zp3F`{Cy{r%=FQAEAG^O@N_G$?U{#-L7B3pMU1+bJ+s9xbPg0eiu9BbrhR$AHV`2T- zG@=I`IhQu)m&`ki-Hh`yx;C7vQtL>GcHO5carRmF>wofKNpEvY z5fbH2*lTvXQ5kuFeNwnrvf(e}*pN0nPnw~axv}@w%^vk{KrIq5AZ4foM$?eboU%iE&SiEwi$n%L$ahe9ueRyt%FpGLu9Dx~8j2Pr!Wm2OG zQAJ}I)3J5f`Yg`Pv40zLx2|LZsZr!^wi&OQ8_O5o9I+zhBwfMsq@ssPf+9_D=p)~_ z-G?bsK^JJJFI?L4vp*{qwnVOqe)o=O?W|tLO!WUXR^If}RrFi%%}HBEKBe|%vt`z9 zZS!C~Av-`KEB=+0gq^83t2#5!6qY%7*_qvJsv6r1cU(V~-NMj9CNSn*+oHP1uVg2n zn@yRLEC;bVcA}c`?G^&j$$@^eStwqku`I=4`IgkMa7RvBw?J}Fh68-?&iWRHu>Uoy zK|5%J?125`%v8+|tG1=+?S4j3-W0ibzKNwDl3G^rRxWB|stg_vxEY~!wkY8nY4t=( ziSdL;qes;)~IL*TpJphLzU&*5W`w`iRGe6YhuwajWEC;C% zxMRbL@i(WiDBtQD?y0ZOj!f2O9IROG=R1)=AhHafE&RKVC^4)Mv&t{ke4V^)h1b>; zP0UaTKf+ECUp15VaW{OCrJQIcIBL-~u3B$Hx&E40(|Y)gj)Q2-Z|#cqLLnh|{Paz; z)2C8QFh3Qci^s7^606kbgEvO`7!H{kDIz0_g#=jVnXmrad^%s+40W!ZTn3x=^PXH< z>s|UEUwZxmR+6QVb>zZI{`)L9x^lEZBTAD};q|G%!&O+R&t;-en+0o2Gf~Hpq-;xER*74QSiJybG zn@_QL2XqSWo2mZinmi9%k-^PbDeVdqd-1bSiA88*?T0yXEP}q#Ner05yd8v(Srf9< zSzW5B`;klXn<~U?w@CadK5C2|KM^c7-TXGHzRL^t+aEO<;o6iLl4NGxb&{HWjo|9l zl~4by`y?y(_tUQi0BBa?p` zldK=b0`d!2Iw}@(uvcLtXP0_cW#a3R{eN2TQU#8a3-#YfutQ;nAS3N|p>u9u2ip5* zj~tPbP+g82g=fq6&cJ7m$=k?Ai*j^Gc#0K7Qv!6eLalp2k%xe?Xy_c&n zeOSZ3zXJV2(0ldOWs1Ob!AZnjZMc}jisjjAjBp<6f>qe0K!$ zmXuF5@^43}%I;#Bzn}1`Pr?bg@#DPr zLuhq(HrmbX@4J!sR}cGX;}Xf~634auYSW??g(1s#tn3E86G}0^OSsgCMZ_+sLCW}2 z+w5eLpFm96{KNlPiJo-teG=$%thwXkxj%gf8|B6}q@R|SS_j4PA z?=*K!QOQynusP+6A>M)Q{;^EKt2V2AA%zi!e3m#KcO~Z9k{fb5FHr9qp_d@F>3wL| zznQ7II@tfeZ%@c8aN*I0`m1HWDlgYwf#WK=#GZm55WXz#6a>L`ab`2@i@SX;%-rBJ zoL3QSTnYl!>)e@j7w4-+gpL)r5Hzi;v3VOu5n$XP#u!2?e=H?Dy?pbsasDsv(W_s{ z)abD;!!RN9dKS z<0Ts^0!C~F*;7?or=)5#OEH1?5uD<-cG%9;N@vO&GUKZUGU6=eZxNcSePmF?C zccxJ;Z+{$Y>y*pSomxk)LDe-MdSW}$j>$16|9v3`%8m)Wq$ohd*LDlDhc?{BVrE_S zo8_234FAjb9ZJFoCJ^O%SuFB~oK5|g{zaDIdiDt{!VpUTd~eZr7qO^PfCsrulg`N7^DCEZI(YZrIX!McAYZRWV-Am3gN>R z!ssou_VJduy^%su@$V+XrDvbGzAMG7HeSfEb$VnM!797fR+Ms_&&&Eks=ivAh&1oN zH~jYkvx$_NpS$lYlPsnWtlt+;s#mGPX;r-Zck0U*UC7qy(AOcfV1TwvQZL1&8A0v? zKhAZD|45Y3$wPtB)jUW$O;6qPU`IP-*HSXfZj%}|@7j;B`RB!6u4zG>Q(SpgmKi;qZ2ffPp3PnuIi*5m;V+GO zSvR4{e@aKTMeboH_*qVPO#AOSizQ3z+d6%o7#P8ITkF4#gYjHAqr9N`>j@s zMg#)=dCFBc->4B!XBGdsm|ENAIhSw>+t8PudZQ28Mm!A;#&IMhRbR~AS@lg;GsIn^ zq6e1VGbAp}3bpgL6=F$*`}#gq=OVuvz}bFClMsZZ#V>s_c3d9QtI}vtLnX_gu6Md)Sr!j;e*k1YHhHqXw{Ob+{Q<~2{%>(;y*aiv(8RI4|?>c-xvyy+FT%yCX1Y@ z)bcmv%qhA;??69O1%k+b5JfR(=&@Wkkb{A1!^JZjzWifHeIHsPQ{<--=SA*^X#&G> zv3$R7b~S$8H@~f@y_jo`XKN)hvdstB>xYRF3qf|Vv-Ah(30WJ<<1Fo@%Gu#wS~DU^ ze@*hWd1G*>i5>T3k=DAItw9txs$(m^wBfO6YW-B$jnzc-3a|OGX{~0mv;Ve1=TIhCct)`%s~4h~&E}eVh^?UWe8p8svhk zTIv%iCZ5?)hc3oq$Rw)D?^A$T@p$p5uMb`~7aKDJeWwouhpPaaPCTyi`|%L0t@@8u z>t&Ow4Vi?p3d1GAFNMc!Ke*sDQcw5~qL-VV5BO9squX$Iso6o~(+pXNm{5O)Rfg-p z8EZxv*fsEYqRD|!Ud5D$NQaoQS*(&!WX|wnYiZiT!1LW%fQPEfL#P!pi1}%+WZsDAhF1_|z_9vD4D!x!wAOf_lJC0g2N(M4^n@=H%o@f>jl!0fLI>U*f47)e6Tk&;hb5?Co+SlRr{)@1=Q-0Vs57g5M=-t^9y}eupW62c(>c@n< z#!{9{uSdsvpdtyq5vD+|Mb&YRJPI5*7TE}Eoqpttklx{$4Ve6lQ@&*Xia0JeqTZi_9v8G-@+o)Uk zhah)&gxUNcw1usKL|}-^?mD)k%oQm=H6U=m85)K|2xB*Jx-S6Bh#L5;3rrm2AHqD~ zz9{bgfvYqmC5+`x2COAp&7esPA>?(_^WAB6C_gasn(8!|ah9P#mmt43I8^d4aE7)W ztT-Jk#7tm3;|LKboLq-a%NYM2r?@2JG{|+x3|W#xy!Y_>gOWaEe*Z9K8lZz*Y8+-p z-2EfhT{n zX$6QCQu}hHtI8hmo=g>Z|IAehI#Q)|zzGNZn)v(mIFCn3fHSQXpx>qD+_qm+90dcq zWPu6Pbe>^FC~IvTzui`}W0*L*29`eoBt7WXAZRSmCUvY7j2ox%um{qB5C-d1>^DYA zfJxot+PY16bI*--8BJhoPO*|8^Z>!f8!^CxN$Pmd5J?lL)YZ9(ZG@fYcH@{>?mO@0 z`MLZ5+qEVZU`-WA=!8hK#_91#$Ag~%$tM60s1nK7nY-LAJn@@En%FyFneyGX=0^Ao zs(?671Q#*zx~ma@Mr}Z&>!YplB9Ye92V~11O`|FNFPxK;KRvbD&3DfMv3~dZ3Ji0X(xJV^nxH=a1*GYM4AZ9xH z82qp(S%-dtJ)H|b;7f;SwQMGoMD-rnW1rbh}PlikTf;{%)Jj{U9HkO_#5c85-?Ubygpx8oz+EZtwRI! zA=^VBLXrcqX)VVDN{3La#E}Xu>ma~b3m@KX(A34r~aezmY8kRg&;j_9XN(^E6P3V<;X*nWZofr6B_;yMqWnDO-ngRDV- z>HJ{bhD$eB#zE#g`5fqy1SGSUnQ}*| z!`?ZIoF5e5uhS&j{(l)`=G5YaHlbuqJxWXZ8xEAX`yzdaDt8W5qnO%vM}_@|W5e4|3M4qlhkpG6!ZK9#OR?dZqR zbdIEyfp>g+7yVC&Nrmvh~p;D1boh^U6 z#gVCor$*n`SIHv;Yen-t?s02$w)#%a=%I@0oG*!+XPAlwRRaOe<6 zlz~LF*N^rCW7Ry;#2yz3C3+vSoQ3AVeSq|x1i)Ys4Im#bMb6i3y=#be=(|xvMaD6q z(Tmlruwk!KTITSaSQA@*+429RwZ zJ@(#QTah zJA+Q2zuo%4Jf8r{)|ccwK7*vuYAhFzjU=aCh0CfKj_74q zL;rp>4Ee&*=69q=&G=e7-XQyTXFWd%hg*^q+AhZHDl!HDzqE6EqrQxMQi~VLXnksM z=)#LnqL9LV>$H<>Ic}eI zQp6Q-AbU^olxy)DVm^rmHjDgQz3VG@|1KjPao>6K*FukbuI7M>+XDVlyy zU|2JrO4Q>YT!~*txnyS7{eovmda=5}hFEjg=l(Peaxr;nWA&Ch29=6e%qZ+0pwHt4 ztX(_zBh_ldW$pM^kfRkqKn(x{htv3Ph<_BCuV%dED)W6RhN7m|+jA}&^N)_FUa1v<~T69w53(3s8E>Lwxl zN4z4Y&xp&#c9WJM9q9u^G(iMe5f;?E_9k`JU*6r40?S9-WG=o$^5uF z=Fpi=>iJAROIF(E{{Fx7ijm=9zdIk-S1#I}?t$_i$!tD=!^;!%edk*6g?!#aKBuZW zN(43)Ih%F^MEeHHW%|0%j~bIznzYOzuigV;O2Vq`?O(&)g#Fcj+w0t1?&8wHB+-Xx z(Wjx8N1J)j+$;3$k7@kvrFkO)OKS@?*pDR$gor92Z0+k;{1LxnD^MV_M6t1Y3^l+E6UOl-iJxr z7pwHaOAvaTx%Rm>OCxzkZ#C|0cu}I|Mn5$r>#K|+G#~aWU8+H#?c)%w27&U@Wh8tp z-@bP{-HaZnQ(-4P(B=9&c$$8lGCnhD!j*I@4WR4x-b>p2R6E7ZnDHr^i?bzCGXPS9 zu7rum9sQ@&#*G`NQT?o$yq~>Lo|9nOgYEO;?1VaTjL&IawWB3n%oB_za0o$UN#eoT zI7=({7Q)*K;ulFcU77mBUUsxCnAZ}X?D}xp+J2u-EF!Ho463I=N=Z?+N^af0+#Q#G z3b7R~k{3g_-DdA+Rwt>FZBiXn>n%NWu;#Sq3=%HNYwiVoup)r>SF>@%H@70WT^m%~ zEI19EV!G68=$(VEb|RndFN0*}ybjl2kjITfUYEy5SPdXnnLpy4*(B3x`}eRQdn6M_ zDi(9km$NjF2;JV93&MCKYp=!cH6+&?aJk}y&W$=yLpV1P9Nm0lbzKG{rCfEx^hk35 zwU_aWG=Z()$ z@)O2sWF<~Yo;b*R*`p2lI#_qf6CqDv1`u1G%+$J85gz5OLWp|kVBn&!AJ!-6pe%=_sC zV<4pQYlIAlsc*I1^w8mYOQ^CAzmwu_Gj#^ziPk7#&9y;}5y}XQ=R2&u1yeQM!tU<| z`+%_C;b?<)tge&x7APS^h$+`LK@+@4u8+wQ&Ibvq0&b3H?yz^}KnOS42NdaghMzm@dqw|?|7Xi& zr*TQU4E4xzQr9fa;trN^e3s=tkH?d4p8&b-8&QS^{XFVaH#qZLuM}LP0kmk?dkI_# z@k9**BEX#t`gw>}RBo?*eWzy6{3qLp7xRM;o5@fA9}b+%R`1-|OLgGQ z{Gtu}q=WFvSP&dVaCo*aACC3iwsi81j>uO}t`l|{mPio2th>)?%^p%lY{Wk)ExWq< z%E#ynC#lAYCJgQMe={majx7*?fz5Q0#8a-`2ooE&3|%uR0&J8eMg6{V5;0}Ay~_cS z8D8`6^aV1=wl4oG=4gq#)4b~+Fa(y{73t@rl1K0(mvSq#tUkKva)oXWZdvy2)MXrH za3DzDY*M6{{L?c{?1*Z=UBLPdbq@a>N?{1l z1#(OKGPUXgvGO%1edw=K7oky@(T#j;+q%tN zBXt}%c3>SJDJ*IY=!_7I=Uw#&6v)d!33Uvvh3zrQ??rXEegxs;rFUAIcgfz7Yurkc zeq#vFV#32nR}Wp8%C_I)AHDz!!jFq(F@`Pf6Du}d+n6Ir1_+frvsXWrtzp8b3r3(U9}cyfjostNiAg!zT5w5(qjz~$qBp?u^$eeldVcTt=Vycq@k)#|l?!D3hUIZ>kiOZ3u?|1d zhbqK)D5Kn?>80dR?}PHwXOAXIqMMR}?>`?mR}_&Au9Ax4TKOZP)l%@&AF`z~c24Aw z6FFq=10k2nAB*Jh#sX%vzk1grz!85EUpygJ$w^WMa?AmniZjP7VZN^QOKOzFx^SvC|f?Ue1UN@)~gmJaMJa!)EJy{(b;%-^%~%u(RfsVx0MM(09_kZ9q02h^6G_ViC#qDVcE zBJoUIAGk;r2;kXf)JUd^V`jO2MBrD)Q&-?_M2?(&B6S4UEMt?&SO#%=h590&ip@Dp zO#swJIm3DYyH#pdi|z$k4!C%x*33dbUfY{XhHd}JVs)y2A~gE^bmNcfwauOsaP6zQ zM81?&y_Nbq7m9OkPzJ&)*aAg=5`tSrH61L;MWH#yzx#)1O$R}Inu%{HHO}b6msf!@ zQAFdiwx;(S><7);i{SFi$oOjV z?IGs++Zr&s#U2uYRzTWWQ#|?!I%9Yd8XVzj$Ok3U?Epl+%0M;sa+vTP=Xid!-?sF~ zl!_$ZTp{fMKPha1rnenHPJ&JxVL`a2^E=|6%JDLTz^b)?AXIg@?zQj8q;qqZv{Pp|_K-|0kBnH_NBr?|;GG;Sv= z8FJn81rZ6D%ZY>xZo%ch1>xy3smKe)(<`rlF6=tRO;43~-<07PKFJNpNx;6rkjrcJZgPi)HeqGg)eB&n<(`sTKT<0A* zUy*-%*>%ERY*SPIwS{yP)z6eXcVB zCjkt82giB05tb~~gD?NRgM2B~;mdkq4fx`@K9^b(xjJ)*=6SjDvJP}6NDxl@jwndX z+InYJfC9@IAV51q3$MkcHJ~sL87w)W8~^U0rk_ZpI1Ys7%0VZ9$P_HiKgz3wuZ?hI zDi8=cMr^?p`D5BzSv!6|=6;!!)7x(BdR?h}&I8e!C>jUFzH55Tl(#*@_p_ZdwqT}b zd3EQ}v*0Ah4BdqiIUz(;mn<;MKuJ zkMjS9%aqEsgfWU$4D;y&1Wj*MsO^&bq#l>cS3br`gac(wr+WUA1DDgZL6T)rZs+FOucuRkYU6 ztH&x)UY~{>eFWj1&6(LLokc*plQUe<{9iZIs!PxVvAHr;FrKtOZ~6~cyfis_PzYA! zw$`b*@kcFE8P^XG#pyTal5FtyYljPD8*;G@*YzN=RpY1~=@sk6&?iVO4wsLdq@P82 zFOv24agW-6OD7KyxS`2@ykiw7&E!awQxF~W<5jZ+>;`h$IK*_IdwT`pr~mNGg@2!1 zogz+~bq4sB@4li`?k)@|-eK4RRTjx^U(z+4nW)&pfkfmk{kcIAjjug$m#umazn@kHDbNy-sb$X5lpx04#A3ja(PT8A3+VnttjT_AhQV16zh zXPA1TPT%bgutOkj@+39e5eFQl$O&HK&-M%{ewr5Lz#ME|L<1VkI`-?v%zztB0cXnP z^H-Vr1}aauHOAM*<2B2j#1%h0M5~|*LN#S+QaA@pD`w@xES{+rshYvFgILrDm9MK0 zAAV$sC;|J?0onuQQpcx&{i#$CUHo;0WG}q!(_I%HvMV6vxfO4l(CY5p zKW8_1Qu`fsK$(d8Uv#GcW4_$etKKtxAFu7xqs-lrCcV7yMyebYEpvYT`4DJT>G{vI z#DTAdmc~L94&v|4bgXhU3Po4fk#QwqfxEzdI9O3=)M&3j!UWmW~F_Vnqym~qJ~w`~3a4l&3S+^gsXNj~zl z?sA;o?qVs5>Eunq4_l6n^Te$2G95QApCbOA>=5w#B1?tj7cX}bR7n>^&6mn#Xgx8w;en+gqJtK0VGoxcxG zKS+z37~K>RJ5kQ>@bNqS4((41TSe2w6@xq+z}wew;Be^tEV3ojpelGsn z_3S&cCqw3J;Pf82wrql!U=($;&*s(A?x#{mN9ukYFB>>p`*Ncz_6w2xcq>lu=y$*A z?E~9DFyl-=VWG(V?^?fMS095Uz|2`Y+yO)x_y^gq?ssYPQ|-*mbdZnH#fhsblUail2*u6V`|Uk z+|zB`<~t>GoSDWt{F`x%D~R>_5=);rduSEYIF8-}-#&G9*##Ye-Z)F@379~Kw7I`N zm5^8J8zt?J+&RhqIw~}37wRxtyyj9`Q7`#J0eW#F0W#*lf7toW{Tnc-A}hhVDvnH@ zsH}I2*azHwm2m>DJz3-h8Kw)x28hq$LFIwH-D8V=q+aiU%&b3ZEy7A z{lj+BHoRsQT|N_8$qMi5JRB|zE$=fD%n`-1S+KXHQpV6^pJ9^6?4Vmd@*FddR=?awu3tqbY(GT&;6u=15%ya zMaH$ZZg$Dl}AiM&({)(sL(nID{IEIk<*$1>Joyiac?p&4gNP!`PM&fipLp?{Nu`a`w4pQ^jHm?Q$p#p z&&aJGCa8$>)_>L9sQm1?i?;%dezL6so8_Xw5m;-3N=WzfruR}`2!;rhd*Za=hW+5S~!&X=P>C;d3i?W zR|uy8{2B3sgtiL$4>hX3Z4w>L<0pM8`P<8Ae||qtfVf0VIU|&D;3fOp-z+K$`T=Ed zx95B{v%#fioi{{u+TnA!361foNGXYbNg8_fyd~45C&tirwDa6~&TJuR2UI$LWx_0T z5bddE(?L684Ayt%q(yeKaC~y&U?qV_?T|7q?I>fzohgeBZ(W%7i>4xwza|pEcnJJF zMYd+I0}6?hCM^sfff>e8%|UZ}LqJ+-OL4mQ`Xjp4Z~T?n`ICi3jaq-n77!_i2v`|CA<_gR5{_l~f#Z9x4z0eU1%{Q3%^ikTG?vCw1uoXob;9U%5 z(}6Y9R+is_#=ez@w(lGj$SH7l?mt`4pOWtkQz|}4+{cdbl~{}gvK?ZL_N{;o%bpn9 zvM*s`jU~4c)g8R7NSaZ<`$1>G&k&J@kg9)XZ?{4_QlA{!NtM^gEXI&DID370{E*cG z{ICGiHQ@IT^ySX+unUTMZ$%lWT~5}2KYx(d_{s_EEhi$T(+ETZM;*aYsKg3f*^49d zj*&lHXea9b2=stP7}rKYWAV1!v}_Qu5Nq0wd7j%JDICQ<;=1pJ;3f2kfje{t_AQqU z#GKv5)5kqFVp?^SQjwuytPrm_ShO>i~GHqD~OrSc9Ubjtu6OkYrcmBsN*0v>;PenJd^TSx-jb>+pYHS=n5|s~xEOR@Zv<4Totx{KyM*|3cn|I6eKO zWU|z%7!K7b8{daQItQ{(2*cWNN^n%ON^8zN)~<`^w|38-sEE#%Qz1TeY{)s`WAS#4 zCbQZ|m(+ZIl+lY^TieI#KET<|Y@0AodvsUj---}N(yGJe;Bqeb|5&?jDerQgWfP?K@+q!6es0Dh>m zt)kT%LPvYo*wou_%9S*%!1?NoScubv8{(f$e>QHW*sm-$E|8U;>qFOZNIa8A7<5^o zqJI!=$jm-=YNNV+YkY|)J4$K3sm(0D>kuP=QDpU$l;S}jc%cPaCLx^a2k_WyI;(95 zTkp5Z2ipt5J%wh`BgOqpdiaf}CtpO9**Q^%oy zN8fq8+sD+yEr4ip8*B%x3x4_2(gDkw@k z;O;!6yHP-UbbNif=NNwV3B5Th*2sRB)V?FTI##iaDE?g4|GggxpM8Q~wQCP!D@}i% zHv3HRKoy>TX5*dVIB~xFd>#nj#ONdoA;DWQ|Ju$tQVxmLuC?N)-fe13w0v@R!7P3Vdl0iByI^*gxFZXjk&C^Hm@*)y5&eCR%?Rz>9oD(CuQwD{m`cPelG(2= zWuE*3yNRc-T?Q{_!f8+QWM+-TR38hAe(Za5=Em(Nwn;)9bb#d>c_Pi*DL?@k=b_rp{_%}AcXPK|BNQg4Tc zf_fK2o^I~j6T@?{raai868ksYQGqd__@J)!y^N zvo*Wz#G+tD-Ijl$%u7CHlV;CEw)~vW{1dIM zOjLA4Kc#7^%#u*r{udN)EbzS+fS~Rq#Z`fc3st?9DOyCz^tYo74?mK& zG^_OfD1^_(^kjN2_i^>9EiVx%E@4knTd`<*8fn*(c!3;LE{@3+H=1U}FscuuC7|oO zKLxzH%4fBmZ`lM5+IXfnLk>AEg8|Lu!Ddlc7VP=i|0$L=n8DCqC5DWyLL?mJeV0JA zYb}%6jB{kBrzC%1h8r!*6HF1nRAG z*a%$bwTXaXHV^dc0{N()33EGRiZY-?bdr6NY6L%7|NO5^-3}t#^R8+!s}TXR?-93b z@C4@Lmd&!+PieGU6#~$^<1(xJ{q2ye(3EN&=V9M|^ClMhP|=eWkZ%Z?t8#7bZ^&-5 zUv+=^ACOH#px7!cRW4JUeQ5uWK-1fW?c^ZPzjm1HnfX0kg;>+BJK=>Urrtfhb^Zzd zJPsnKSuo@o0VQI21lN%iMk&IJJDC-7YX{9O(Mx4hlW{e*0MS;dx204(k1rYijs{93 znZ@d=zR`xv11}-EAS$*5ZG($VR-BiTs$|cs7Sy-WXEsiK%?>WP@23)VmU)FfKqe3$ zf5Ce3%t9}sZ_Sqx*)UY@x1~{ySxPs^()j-;n&RNWoz*N)bn_Yu6X-0x2?=JX`!7$v;5-5i{<*EOdHxY{X7CG3pK1gB`ZXsNk7Y{vS$+U7 zmRwf^BYD83(1o-t`tsi+Pch~;UD4p=sYK0uIL>(_>iRYu6d{raeq^DimIWb&_oBye zUWd+dX&v#*BkYX1D(q#n4svp$g z_eI8SAARtK`56L5)q^*8GHtxZ%BPQ0D$bkm?&D7qiqE7-0BQx>|;DX z80RO@*lkX^-Y3H(L>(A60#v0V6HfD(7g9CrH;JasGBL^0HFaSC$cMDS7_B3juWtUutF_J0e>_BH?j diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/opengamma-logo.png b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/assets/images/opengamma-logo.png deleted file mode 100644 index f72f73005c6e1e9568b792f7081a7937f7e890df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49212 zcmY(r1z1$u_dh%;C7>vvq+pQ}3epWC0@5H2N_XP`!;p%XR#9qzp<6l~7)rXNVPFQN zhMWQEe$V**Uw`-YdG2$4&g`?++N;-R?_;>8y3#drMsg4cbWQoiGi?xv91j9r>L()s zp3wGrRRRCI>h{9W69nRWK=|*HPmau6;30#TqJfu=tBn`o-=u?%mdsAW&1c@-sPIAJhg~)rG0^J7`XQt{(b4ne0a8WiE=xeZ|e>=^2-vJo-oA zQ&`4_@rOO+FE2BY|I-kn*>yRlDn#K@vX9p{U(hUH5v^c^)4E*6`ZiQHR9Rhp##GPL zG`8vDeC_Py;F=qx=)=ibQq!jS3H(Il)I6=K^O*U3Wx+AbvhA|T3h(*+pG1X#L}Gw2Bm1_+4+|e_5&b1J`fQ7@fRQU? z{tjSSqz>i(?+0b^SyXD3jIBzhol?Z#UxH8oHERV$&8qPGe;=j`hk%t0yZZbx=p($| zBC8>p^nZWLj|TSb4d}O|o^mcnl1B0GFS5}@_|M<3C~7{GoBI1uS9yz1Sz;C?Wgn>i z^_e^Se>gJ&rXzizsQE<%*bM$Z`VgXSP`&;T=8xnK&qCazXeEN^5uK-VM ze{qxc*9Ks~!vDzmbo$Ah5BUz*ciS^%w`Q!Td*(QDRB!elYgXCV&xb4Jw-oie8 z1GHL-w~_J{)j^w3iTyQ0KTl*eqToOBOie`Gr2-hdIq@7mm2j&Kzu0(qE|DYgld(eR zzcy4~M*sM>5q;8cU4x#sf$@q{;MaZyl%5^I<3HuN0&bEQ@z>RYlCNUaMtd-a$|r(O zv8?#*z$QDsD?YI*Jg~90vyZ_(rjNRNR)L5Mv-rD#^ta}ZLUxNcqD7|RH`0$6q%LS; zrxy{z?LEGs3TqRe+|{QOvMTbQT5uk3Xf`1JQ>j zpL#pJkbc%X3u`CBk=*O@rWQPjx5(bJvdkotcHVO{e=Yd$24oe9@Ney`U1wYaSk z6Sg|P-fo6u6BiWCd}F~;$+P}E-~UQT{eS+*-T_uyS-VO)1)kf*RgcQh^w(5(7>$h#S0cH(O8+|*mo zqfd1JM#0Ui3bRuIQZAffOw;)EGhb+1V?9IY$Y1Mle(Xc2R#k{#oC4L8U9Ny(hgc1A z&fy2&xPAZd)tG^CJSqFXz`lGHWBU1P+}AO2hX0&tOy^V-$GsjZYo0im$R%G@Z!%Nj8Em+)t1QhtMKK)P2cMRe9PhS@x>1m zw_KmB<0_5M*E8^Bmm03Hk^ak2lcWVfQBffxZ5J5e8r#W`f|G+F4Q&phl1vAy>K>}m zwnT@4PY)DWfBWsZUC0jo)yyKk=m0RdQI@<5y^}E$pT6#VL*IA|&A7$B^y22}2oPrc zGnSr*8d5H?7d01+!P@`FE_Mzr21Gp7G<>4pTGJGF9ksq{?SlzX98+2g^E}5lnn}&b zXcqs=4&;0E$Af;Q0Uo4*g5Qv=HJ!}4(*&(X53ar=h&BzMt?qeflH$54twniZ2XEZR z22vakHrdC@8873%JpGrF?6DQ5F^|4Z!oG)M=2}|yL~Y!Zm_}8PRoC|u*EZtwTKI>3 z)+_J+s`f?792x>h>RKf;vTwkDDDYv^d*4HBD$#p4dOV4!1tAF7ULpM=GxSu!+-vyU zkV)mQ-`{l(0ptIK7GGt9G~cOq+g`MQ1UCG3Aq#a?FRZJ;{tG+!2H9%I~#uBb8s6_XVyM8L4{w2h~>JV zxOqz!I+-&>^^O&~5r^Gpe(vzMcHZR;0XN+x!MW(0QOeXTm3`{2SFb`1q@)5(4`*1D z_g8Q5cn!$xU$KI!$S`N`far_cCo?pu{n|lFDweW%G+xq&KqqmA1kykBV7V7`@X+S+ z-`tXJ83J~_aTyHjmHmNLS#TXhd92!cl(_2Za}cR30X~3IF`_o>|xSf=I?j=n5n-J{7puh2W_fiPhmTcxMv$`gVgdru5vaI(2X#WmUEnWz$ z<9IGL{3|r*4ow5o)tScXH)|X||I?uEn6?_NobbUv|6zIkD#n=zhtcXnO7zW1auhlg zSV_1@TcOcT!~NeSR6&0mMOmdnD$K1q2){)6j5d3sm+yc@jU@{5Aj|Vs^WXaUGq^Am zOpL=!FR-88Z4Y-aVhkSc|4@uL+s7K()N<#Cb|#ZcZX+ z2vt~8TJ3-2V=EN!(VxSayxTy)!r@s_WvW2oHinAXCVPY9|GTb$@6WnxG%`)$+(vaG z5p$ubmrLaSZv)NLqlv!YQL>rTglfQ+cgNy@-Xk?X^L-IA3Wz$$=HQMzpRH-?UoYW# zrPqQ0oKZ_h{i7*&SU7yPoZBe>f#SzgDL4Ifz=jXT2!q9+KV|ghje!@)2#V-n#B`zm zJtXAB0rGi194I^ZDw!sLizvWtbIb$;uJA-g7RkLAD_?jWT zA-K2qyM!YI$fRhXqQ^LpoC^i{A6sOd`3|$_H|Yo7*+p48#{|v{!bLw!H8tAtiRgxc z1p}eg-Qs8KgR{8~*Fm84{Cazt^QAHT7_*R1&791Mj_0twWS=r2$PSC=1@Qo9(#=6f zy+*fLLPw*v{X-sPak67@s~-&pvT>XdKXR)WQ5j&j?weh&0JR8mSy?X$C_NX)+O8RT z)`$C52Q#Kw3Tpubhf`r@{YodqeQKr4*&|c+1w2TC8ojy2eZYUp_qk@j>XQIKhadmw z@B?M}px%&)DIp~m)PqoOg`A{6U8|6tt=;1t5uoL&zOLMNf-6^NFapB?>sDtdRnQmqlbY z&0%n(-iz8wQU26a7*glYNOT0zomT`}Hig&d?DEOlml?&Ro9-Xy>eX}yXU5Xrd*@Z0 zvze@00lXIoJ?fEyO=x3m%XirJ#No>R_(J)e-rx6Q9!WEY_ySCDPi4@FNib=h`?VFf zW4Em9;g(`)?Y^tw^<2Q#WRVfQ4H7hUk0NJ&r#1rBM0NWIA)gChZc*9UQTryBa?1vt zdP_hvjIyBuBHPL$1-*G(5U}H};H6f;)2H{?)u({XDN+5_RS>9IW;qWQouHiXtM2G9 zbM=2CS9a--KE%D9qGq&9F`)|uIvx#b$yzscf@xA-r9rD}0Q1YwiaYR$m;`+x@w(_M zS@*4#jJ5QYiQRK!>|}nB6bl$80-N{7Mcl4Q zogI}HCPm_b2AV_2%x5}gSCIAWXHDoQi=d_CqeZ)w*fg$BPGkh?Dyi_}%P#{kKg8BP z$r1`g5RUd{1ENCYdT>%)E=FT2Z#l2Fw1!Gsq5$Z}z^Ja!|M~3R{Iu{>=fLr&p-s@~ z8d5pCGNRZt1f^$DcSe1FRp2lynNohvu(C2LiW`;m?~%5h zqIm{y;+|S9NNEFkM0VbDwCHH{`!MHtT|MQzkP@MjF$hs2Hc>EmLH+Y{{NBfFN1H{P zqXHi4j4g;A&NicKdKXQSG0qkWTFuO)wyc%(-4({j$9%q+ao?^Ep#Q&;6a&cpZaJ@U zc|kR&Vk4fvSixzqPfH0&Pw4;4M9s1Ozky7;)&0x1@QHFL(V%^%5leATF$G}EUxGnq z)OAyS#?qt_msoH^BXqFMn`wF%Kv^1Rm$VE38ZO7_W=@xn04Xmana%h0$|ngIk)F4L z5#9q@7ZWw1S^F!Gs0p?>`qP^mrX2ziPBd~>LLTS64Mca`sJg?Rn~YUu<)pt1VOH0( zF>s#l&)&{#PB{Hp6ARcG5ea9xBWy-J2ai!e90DnkJp%9>gW=OER&3sQOC649Kud}6 z2=rRIqK{w+oKOPX`MznaWstXnx^92tSh9ER>||M8bZAYnFzuBYGcuHOto=zsDN``w z)YxbL^k&7AUJqa(=kWC?; zcXQ|)B(!)B-s-M;Q|X<3dnfH%w#Uu3GCYc zbA-AN#UWt*{f>Ka>#>ErkCd$meBRvy3bg6FbrP7C$>Ys2RAB=+V6QMcQNwH6#7 z^O)PYz6lW5Bvft?Jl>yBcIsxyg1Su|S`ajP9vl@o4|ACk7Tm$DD?(%p)~E-&2~D+~ z$LlVKOX zlcnZ~V)+#S?^x(r6uf{x#!M$3otR06*hcJP_)wNxKs$1W3utokZ2}mVwI6tLQG3p? zz&1}ukM9CPG)E}`O;Op+I^&3sQ1F+ZM`W1B)XL<`;H+Q=cu}3OS{78FM z?N~4nEjVbBSmq*d)f3_gRCQ2L?C1XfB|@{NqD+g1KUwejvt}}?Udk+1zu^jaM zw+YY-XDBs86!yYs|wzAxt4RDUlhz6i(PMa9Nz3NKsiJ`X0?0b&^$T48sI=MMzhdW*5wEATu znB!0Xd{;%tM}#O`QeUe5=p4w?R+obaMc{G{@5tC4c%Ch@o>vie-D z9_DFCvJsGr^y|02flt5LCGp7V%k|}?B*3sMRs%Fhk{!!83EsD{IdRO(IorgukMSEK zA-;HvnQ^@A6F}#nYE?c$2s7VC1n3JXG6JKj)Qcr6fGbC|hEw3c_R+XYQ+y;aHQ5*T zEWZ>3Itwii)|&zh(dWlIwOTEE6OKT`31);9$dQd=xatQkfzr2*)C`Qdme|_2Lf$08 zn7vaC!PmV#zkUM$^aU;eD3Kc8$Zp21GT!yP}X@` zVFg0u#hbxu7i-4LklJnDmq{b6sOmpuIm1F)ZT&i$;R`8{jot^^U6GL12R1y_XWOb8 zp2dE#w^KxkAgw0_6jS0CUE1QWZt!4+v-+ISCAuuE{}`|ZMg`uf1z=QoE{_$|VuS0c zy&Wa^*#kGQ{h2JJt5EK?MMuhwNh9q!mr3T6YANJZcz!Xjn}}VhFSX3z5q#f=p*Q>0 zy&zv|k*}9PK~>oNH&Sf=<$Tz^9g)p#s07D)b*FlFFzgpf-ezi_%#mWYqyF%H{Auma z7^OczUcR9~5+NA_;}eyhc0&TtaZ%}regcH}sJ4Bf+Z{asr~y)KQe2EkJuGpyq-mEe z1eE^-0Q&k>{R&>hkHOZ(qe$hUc->PTGNvxry)wf{Ach`ddBg&5viFHRS8FkRi#LFW zijqQey#u#W>p6k#YZiSGz{lt+-4fOj`$WJ&8oUZsTpq6TQQ&thK~fJnYy|z#Uuf!> z1ei>%QNT>7#u=A*tzhDOQ$sB^>7%^y#RHf7K$cqV(@+>6SB|qyw@oyDUz$n_w?2sR z{HX=mh4nf$Sh5XM-XdsQv*_WUlGFBl%Y=7)`WVONCCyQ|_&hG6#5@1H#LeT=JMFS6 z^1@mB^woh!miH29%`~qvI0-v{#;B9cI|sIkvN=7Tp#O0qPErbRMGtD7^e-`@{cQ52 znW`jqsaH9$aE@PW)BF4Yf@1zCHI!r!Rf8G153mkmB!H49>Kb=RJiCaP12%}qDW}o1g zW@-R8hX=Cyk&%5~UTYQrQ0qpoDne5SJD~%~znXM~T6mOOkYu~UzE^CS5pV4iG-9xF zx~oh%gC1C^3UuacI`zmVp%WmzW*&OATf^ayF^XT1P^0zMcnCQGz-`BM<*K!hX~&;= zpKcOBexqZ>p6{@fEuKj&N}ds*K$EC31S5XwB;RZM^zygrjh^~eo(2L`LxKQ2Wd{zI z4&NCuxeQjQLE};NL+V}BMI?06RE@`seHxqYT3gVc`qKbIS!Zzoe+58&#$coBbq+7S z%W2YuY&v1*98xl+Kn170(tG0y*j(g@6n9Q5onv3=b!2fH^YLsY^Rw#pgPvyu5TXwn z;CHJIk=D)CWY1T*sXmGs#%BC-lwc|c90f@Jvid;l7Oin_3^zpp?eAmn`y6D=hk`AG zRy_4mv#%&NXZ91}mU)Px0_a3=D=%h>uMd7%P~kKDLmV8CtTX45_~HELK&Wt|ENWHK zi*XGA&G9flGj>9Q&pAFE`X`mJ!!?4+4bEuQ0n`_aGT5NxLscZ|x}_@Ur4|!rD`~0ndPfk^^5-z1@rE8_U+N zIA$JHVMbY7FPk6>%zWRJ^WXxdY)Clq6~YIk6{_qtx+CzMQ_Btc>@GxDhgOLDu3 z*MkzK#We#pf-4Cby*2(A=xT33~&_q=%p?1`Uk4OoU0@{OY;Flh_Uge1nW`OFuu-oKpZK+Pl1=mTeHrJug-1<^ODXSE8NPis!+R~DEe%(>~GI-TW z8pZM^Mp*q+H+Gb8rlDD6ZH4)|{h5E2!-FMGrPqAiRGaOD4}4pYQEKpzTK=Q03<*>_ zsOPdzEDBPVH+~5;*LLdl^ZfMlp*{HwZ=gCO>K7H);Da&3*r-|bo&?|Xy_a{7Ml9Bd zu7Kmc`D`<9d^Mba3PuD^|HG6u&0sD+`4mlCXPg#s*{4mF?p~1oxEG)>INYU5hLjxbgc@q#`RdIP9Sr>%033dv7uUB}i0Bge zcLRRgTDj=mk>K`q)2>jsS62&!_lr~d2skH?Lja?h4eaS^Y2?LSw~9is)%>%gntGGK z7ws?l0Tv)3V}q@dV#G{~pA$bi&Q-f^tqO zCQurnE<1Lcp@9Ot&GSAEIDQt>Aj%(% zaEYwm4La!aBLfIF=O|iX?r^`t6#)6IhKV)=PtZO(_@c6m zwkNiR`U8l;jO}kL^tVa_vr%V&5I z-srialQWa;Ob5Wq1Z~pdEkU5iGNv(drzp}H8#6}K?)@u1-&P4tVqc>1|0d`zpYFEe z>dpL}pco*m7()u#b4-8!IR*E{2^Y5d^;NuthN)o~&H-eG-M=TjzHh*!uygYl3(yJ? zWl=8Y@i$8Ln6`s3+n3Kr-l$n+{y86$PPSb}2hUqw7p4}AT?pwtEdB{v%9zgM7Vy?( z4~W@S+Km6)9%TRnHvP5%ehGAU;>e!9GVlEIk-bC{eIYMSOythfoeO~|p__!QJ1$fI z!HBA5rX%9SR)8cm64L9VjUsL@MjWSqmyF$0Cl)wnUd49#{P_0c<+G;S0Z9*pt^o+v zs{FOl+n#m`d7j6v(ci)WVxZIM1_AtaS~kyNjYUZnvzL{C*w0=h|{1_bS&5|@Y73fQs;$u04lV1cn`VdHpB38~($e7A+t;7A&j0EGcqrD%Tvd zbHOtH?70d-t8+FxT@4bNQGJHkDWEM{R}8j>=nl94C@vBRoKQQX+W?@$jDQKjCd!3} zET{lJawKwdUwT#($dy*FN3-G0t-V=1&!$VlGN9<~i?>4tGz7;wEG8w!cTg4#(mwEv zSGl1SJ_U{?N2J}DUa*w)Igvu_FlX~W_B z({L<9%9^Zmx$LiXeXwu6mz^5n;?3L+OR}$ihr;a)La0(any3UE)}lmt+*C3$g6{IM z$Mpd!CL@KhE`>9I?k_XZM~Bq#_SZm^zfkut_xjRO5JRj|F;{QzQ}4ACe{l>GO&~N_ zbAl|4fEwQM$Z{J#&3pf~s2K6ZL6F2#=O6m6+SDU!<{#0#i64eLXB6}(L9&^x$0J7b zSf3%E@+7uDz~<&)uW?mp@GznMIjn$?{yEo)ZWg<};69D?yPDFOUFN~N>F1=f1%?mJ zNbivP(%S@_zsXVwV_0T)`N%@&AAauyC#!Y^^zrlCD3oJhz`&d?5K{u!ytaMpuHc1= zIfStNy3`L=m|L9f_j5i%Yx5O52%8tc1ArG5BR|!a25=cDjF48g+bjF{+d8<8>k&+a z79bF{V9y+Lqoj)d&PXKF`4JT%Er!n%ELE2Z0W4LVKX{9kV$^pF2cQnh6w$8aj;so` zWD}CcQZsn2u=|V1Rl9{R?+IJY-5ji&Q#FYLu51PAR#}b&#C1mIn6czU9@!g+u$rB8 zF6_f&zYyB*=1sH+p}O!G0o6s6H(Qb;=V?@;H@Kg-^%_aUUDqdW{0Aq~9bA!5M`N#m znzf?@M3wkshm)GlPkE~v@g*_)_^?~L!))#y-Q7K{h@!1t}g&7_sZ@d z2z1x{pd0WOCmv;TIiHcsJ>}Uz24b!Hbh*8MD7BAYVcazSKFL3vhi60sZ;WKcZr_}%1YlcKn_w+*nwBE>y>;9tKy5>1A<}?} z;<+p7R6jWUxm@=9Z5{z2bMFdSireE+NxlNN zmSs?w_{Py>i_N7INgyOu+WV`0*wXONrMkO;;C^5aRyqVSOoG<6X}0>EI9XrM9aU--%Pqyljcmh0T}h6NmIK_86v` z7Eaf5v03f_iUW*PHu|1rQ(~w+UsPUSiH;e(NDUh7b9E2=ArPEix6=H42Tz=0-CO-Y z9Dw+FGidI7zgG7F0CF?wXJ%F1(ivA(Cc7LsEc4XF%^xM!KEAk-(k#PK#(L!z0I$eD zJ6tytgwv_Pq4R^3GPdq!kL!=CU$=aoKJR!5X>zz&r*JrsF?YORT~6rlR78OF4?<3Y zLU84n>J!Jb!GyUZy7SX1+x`tGd)dUyC^PMgC9(P^p1aFWZ$kqX#h>O z4AG_Yv^P^{z`O<9!>(A4qc7@#{Z-bS9ndNaU+FbD8DBrQ6iki5=K#p@_c_&5_S)t$ zQTOY|f)|H=;~Cw3<{G8f<=o&rgGKHC1jN1S*pD+;nI4TWqo?kB+XGI^g09d-(QRH3y$OZjDSh!IN1ajE)QvIOr+Xd3- zO1vnQ>XDf5+sz}p)3|{{@3(y@$MdA4-b3&6gEh6KnWrMQh6t_&@5j#4>;e_iUoi%I zI_A?!XS33J@O}=Q%wEbl6gp82@?K+E7}=9NNohFuZ&+pUYm~NCv$?nf`N5MBo16;E zN$%@DZ@z;51EMmEKf2`Q3c2ny0 z5I?%bW(A%GG`+5<7Hlr+VQ{!{B9Ro|E_I*-zB2S(Z-DR$2lI~4)OOVomSnN2LikRP zyI{Pd%V2n!uRra&+PEDKwSOY$EOQXGRvEmhbbH;!^dgNT^3kl>&ft3-^=BI9K}pX( z2Ph{2urUv6~P(CThF^}+!k<)oDd+LlYzrs{`z&NWW zxE2aMB2Khros3-gDVH&*GT3=klW^X5xHt8Ay)4<+`?>j>`W}DiEoM>ogqiw_)Nfeb zlerPcJtwGRz`;Sq#O0FXVSDR?$>;OX0?5XjJxQihmVgQBQtVc-q}HH+rc?q_V~brn zGN#xOy;0MG;7~iFKxePZ0FW}+?+O57X}}r;Dx(H#-;#>y`x!6a>&3(-%TO^;)*iHk zS-kK7i97tJdfH$|nxHYt9zLU!L-ZrCr`D9$u8#-w{;DT=r2iYwhr1c1^%`yq9kc0N zGIrZ-i4Vu8Uc@R|J707>(cN*+z~yK9;e}Y~UhDXz(N6K}(cZu(2{s7}I{ohczTV5< zEP33>;m*Stle~W_Ey>CRYd>IU+Fuyjn_S}=|CL`QzOmAdR3w{{=Gc~|N!-OF!8K`~ zXVm{tV!@>+qvP?arW8H`Is;;}maNNAT)9&RJJqUctj*fgWEIZ#hq}(J__AosDu+>v zk~!s{W7ZGo3odT)T{K|xR7@R!eZ{et4(^`=7mQ$=%?Munu*{`_-~J;Q3U-lIwM^Bz zra))XuM!Sl-r>G|Hm_OV2ypD(Gi^Q7OPsszY4ig&#d&?N{?)H$y8+ zglf+;3fP&9rb)C-bq=?*Ul^aaMfKKa;BBUN;vT&%`$x~pImqudo$fIb8{Lm+NwVPdjM5uchpTTtt|gxt`rnQr zuj|yl8fB&{rS~=XJj@SyTsUl_gG*l1GZ(K2&{2fdXt-?}j*?ki%n7$3GJZ9@Wg5!( zbC`gT3l=5=Aw`Q%P7EPU zd*a*^Ta?ODI)|nGOBU;hchk1~>aDftZ>(hbg?X;y`>uFV42{zJn)jpTuPGvPB^5Eh&%%V(^8?G(O9(j3@tq%|-qx^9DVNOa15eN6 zPYL}lPBa|hrNopTS1U>nDK5(iT}t~(v=Pt)Gw4*h#wJY_7QJ`{&N!jp^wt+Phu*qT zHuNlyssOltA#uht1B`^~EjEPHex~|Yz{Qk4#DyK66#n(4qnkMI>xwbMyZ8K;G2Ca4 z45>tYog2@ZYz6A?WY^@6#G5zOn|$C|v9p1~}#otj$w?ezps%!4*4$z=o`o;U9$d`DuQftk%$Wm=-jx zcrbUCjy&uAsek_*+H@-+S_JdxiX$j+P@>q|kRlPxa2(PsgD;;)-q-Yfy{~5VkT=iy zV8KB1!W(h^4OQJcO@z-qEihPfJKi6Ao7a+0IONqidl2{A&lf-x`>HFf(bgEMqx}G% zO#07^>E~L_Ij5-W%-~VZs~AfqVhxZ40*~_Ox0j|BmV5i%>}NPk=S_(7$o$(10Hvbq z6jyK#bU9Gel51eFnmvPDA7eTDf)uzZvi5ey*z;z^9;L%Y#0%!4Q;{s4bGh4sbMcnf zn zFTJ^ABlxvGlb>uxWuO19Z+AO=^&GNkc9O%VYsXF#)oW({d+JZ)=t7Z1y9S(ZmVQ6o zu@s&(shENS-)_J**G)5dEG|( z45fmU5!dC!V5U5%e*a^o=RZ!A#Vv2Zolh>0(@kE85EF0LII~s7u?mWz2SSM#CfOzR zoksg-HH2(`^}D$oM{i%+N|ILliSx&fTv-peurn8feyteUE`n^E$=3{~rgVr22HT7y zT{`Jxe=RYn9mllb-DnDIoU+Z(P4$5&LOFkuy-`%)&5TA~2S2-TZr$~dH zn?KLKeF3!iP@l%aw&nzn|prjwqXK-P3yVTFOb> z@S|}|S^mZB$9iFx7+WqE-85^jo>I%Zn-#dCt(R8^(Obh&z%54zvUpqGf+Q)mRE%@0 z-glCJ`3=RkXG)w@LF3(dRq4*8G4yNYgI{r?{FDcoLZ40`% z%R+_XFo-IXK2^H5@S)VzeMf;@JF#r(W4P64N8-+6gfP}%R5l*>^|$=bXL_GSTM(YN zXDy`r%Nklk(5<)EZEnB1cpPRtdAMX{NU=0iu=$~Vxs2Y{vxZ5g1CoU|Yj~S=SvL|%jvQmmP1pvxxSP0SgR3oa}TaJr^kLnJMZbATAI}*y06~- zbS_*BiB9h2&r8he)9B|{S{zS^i7&hT*on_P=y2%U6Oln3#-<)GWPL5>nk3VGhP29D?ER6FA;Mc?$H71!V? z!MPj#XSR3L`#g9jsuiQC7Us=4X();!y}v&BC9C!DNm|l119ScRsRz!1R{pMw`!BCT zhwOq6UKvn`a#t&Qzq7iuEj(}c>jtG7?k&;ZJ1 z;eIf)UV`-#y!2jRh4=Y4ekEpWADNijUa?1?r{~vkO{PdnciyZDz@sN)7IZH)psVmd z^DbN@^ZN&Tu>$!0F{!IJ8&0e{fjp1*C^j(!8(to)asfW+QKgo#J$xRBJBM%cxcnYa zJav6v{2+ub0jmUe+I-cAqFoNXJU)UDQJ;^r5R)qMqzo{CA7HyJ=0Z1USM%9|L~4r> zu20oovs+H_rzNFIJqRp4+WD~^`OKDKe7YqC-~N~-{=K)aXQLMB**CGC-&oeOh!S7z z6QdyhdS3LpFOFg+BdxUJlaZ2Xs}$-``x)J)L{xO6=9DRn-=p;97T*-*JTSI2#th!u zYo1K0l)L`a{dQman3NerM%7fsrO32jOI?7!_Ll-jr68Q*w4HZ6yi82A{6?+6dt7U- z{CB|Dl*5<;IvL{k1{yBs*j{FBAp0C&bZytHWg>ApGKZ$0x{x*U`n9i}~!LP;_D z8Wzj42YRSIe_acb$VsKenih{tW%+8$p`rv1a}nVWI@+Ef*OI~PR8mYNQhM~;d(tiP z0rgzhZ`R)&Kd&-xXFv;_5a@#(iaSj|<~HmfFxe*@0KyZ;+?qEqI8j$}ztkY||C~RW zDCZ}i&NUR_N_M~ZwpG4;CFK*%l%;8&MR9e@EtZG;HDe?4{H~2{-3GW8nuDItH|W@N zqoWITM-L5Ka$rXdu($Ap2~&Tgy)^cEX;l_C^Sy#}I!ygP$fvtQ_e7^DY|-5N)*CUvG|%thdvsT7T}`gLSo*84{xfMVl?+pLoz&4q zgNzDXg%yy82eZv&C{RuzXTG==#GCD9bqX&*SjTP5a8a)e_l4DZ>kndVigcj&5KHIg zwj-ng_%aN&fbj8Wy_o7fY+~&UY_gh8BHCI$e(CEE?@z1y>HL7B2~zNd?nx=~{zv1m zFP8l`3YjCXGX`6U^>wmW6F)x%uuHMh@ELF3>c@T>X&ha=6ss{+$kTvqhC@zvtbO(zDCbz}2O-M4~-v2HiY*C%-TD zsn>-Zu*}&eLrUiRKK};k^Ud2>*RaUN>q$Vs~+2;`yz5{SRwet%aIH*tOv+dH&_3jNi&z^3z7azh_wNwlY?i#0lWrmeDt#0Df_~LWA)QYSqxb1C zA}4xe%-7^*@6}aHwN`&{YRs|r>AQCY2%N9c(-{3tci>V}zv1Mh1m~g=2}9aWI6K*1 zl;VOQaCyLN+_KqQEjK9*d=Y<;*^J)p%%w_R=(p0l9Tit%yWPvn*6V$?R0Fk7gmgQk z?jKqoHY2?h%##~fv8mEVZ9tN(%{JfZBf?R@%+6yrJ?E2+<9l)Qtw)4w zVljrAVMb3?_eDvfD&*_((#?XZm|N58j9K zSy$Yp3whfV-csWUkL!@dJf1kumBP^KHWrX>sjEP*4-);5ndqf;XWbLTW8qJIk&=8q zbZhjHem2YBY6xMc7VGNHe;ozC5Z>?9IXFcgq`XckrnF42Mn2_bs;wK8H+L`=Ut8O)^hnue}&U}HiH7HSf-of zB>7U84dvnyw^DMvV}Gf=c00)f-31LXE}()t-D-xEA{V)Jei&uu(VMj%3X^Q|HC%)< z_$q)dz?<$yFN9nA>(DnB_q7 zDL1-L_6Mpc8P8#s3=JQ{7v2}tz{oDhyM?5#GtRY5vc1*k?!vv!_eJLR*Gm=5_a0m1 zeRh=M+BK6Lj;dsWxnRm;bka@)KlqI&yu~B{sRB_yg;d=~PbRQ%)@+;__^^9I=_k%o z96!TgA>fm>xOX{jSvg;VR{(fhq(}}~j95`9)Ef3_?cg#bZ_z*AsfWcIBtDsR7@h3u zGM#)1e4=GseIys>lKW5PvcR+pmSTQWj1tz%(?Cb8dmtpw^ znkU1T^ZEr*7P@PdVGObE9;f%Cuwq}NZr^(GDh=*P7G;Me#gilGAh>p?&6$drHiNAf zcWkAac!sK)-J{cML$F63CElZ+?Vgpv(tU^b!fSlmWN0Rz^`x;0%IM(oaYI1^kxDPW-NEu|nIB{FwSIv!_`GOba_IS_reL-{La+@!u z)n#EL<2(7;k>r~-U#f$WPNF28!^BT#lDl8tftW2nvNB{rts~2!RDiW|Vrbe}R9}^Q zU6B2`^yJl$%~v%7jMWJLx_8kLx)pD&gzf_0G*Vq@2!8dlbJOiXZPXaU^|x(4nO_Fa z?H_&l8Kz2!*<4JvxM7U5KEN5lrCw%7oBSx>RF=#IU%e3loBOpQ;!Ubg{6@}28@1e# z(!u$L@AF#7jObYUx*Pw1RZfp@6y3nt-EuK|t`@3{mw_9H4Ai%+VwW2qOYE?P4)vMX z3bIr;GJhXgtj!$}p(3XCGs|T@brToVPx1dXdu^wL!*rmZW=|5yDa>^$?%9uooJ}S7 z&^?H;OiHVp#R&%S1uLy@S6)4z`L+7){hF3t9@V$r!wVUEX%c_{sZr6zE&f8JGQZr2BnrhxbT~nILx{?StUR4Rsna5`yBAQx&g~aMF zBH_2@1hi7EN*1FpIPS#Tmqbd^3C1022AIAy8Jvep7%f_8 z%@8sDSZDs>Zl@Mm_D0TzRzwsd^fi*Ax&V2Y=s$LN{2`||d# zr2m9Jr7kShHO%&TQ^ETC9@{%ey9OS^Cjapvqb~PT!Pw;|q~Qm@H_pak^%H3#dj^p^ z-&e0$HoqZt-ncuyZL-X{-6YufYC_)}RIsVIC#QpvR;x>!8BdrsMGVHL-mq}t$D1)B znEOn0WNK=Y&E(etEu`-pCs}j6uUFZ9l01=&e%TtEmE`O})GcXyNL0zs!o#!L z!_h%iz3s*cjSIoXMMy zwEJ*k=g@JEG!xb&m0|sbq1LvDC<^F3iTV732W1Z9e#O{A^Yq9_ow#S~Qm|%p5@hY6 z%@e;=_ewJ7dpyIrn)_lTGJQ5~tirvfyHEx=8=e}$-+Dy3P|05P?QzpY zhr8|kuU!^~hN$5Q`mk13;V^`sO^1w#$$=gFNASa=&c+?3kRR=3FK&X$syK+IQ<&;n!Z9u*B$;mu#3kxe$)7$ z34EtZ=%l-YMWq{*F!2xxR`Wp@bW0>(MvPK#SJ|DDPgKy=K6;^1?`z63Bx*}7h;2+7 z&o&a-a~C?g)C(2ab*+xNRoR2N*sE@$1O8zOZM!_Wt0`?-Hhb*rd<839A@8aDRg)G| z3~yxK$RWu9kHMRI8+m{9CH4AwN;_HkPweNN@yY109`EeachvuYMc^)2EujPo5BGBcEbiDM(?oYuKjW) zz=tIxbes;7-=j2YKiI01`5hvm*QKsn_B}pOSxRESTHL$)AgU3#A^hXBbEms@frklA z(vK5&%c}>LG}DJ7+h&r6zt4oD9a%H3A$fdW`sD;Fz!6aiZ1RuQ^Bhelj>j00Gi8R8 zdy5UXAKS&#Je5vcRn5Dzn-iLZtn!+$bdBH3RP`|nU|RQC-I+^z;*gJJx9R@9uN~fqWbV*3JNO!k@beBUaA>9lx zbT@ox7={69hHi#>uixME{>$?W_ujM5*|GN8>(q~!qi;*AP16OnCJ$;O)L;xPuvsab zCln#OoBw*;KNUj%={3;kdi)nY{mW>gUhy+)XgayKL92X!(37W_!ZOH)=si4>knQls zgak#}GN!8CX0=a2S}tUjUWwcD+?;#>vh4GkWtm&S3esqOexR`0)R&_VDfZW#+ zmsNqL-7v=B#vsnX%Fy_rzQ6Jj(x%mBt^MQpaTncH5mhul_>a-!jUx?>3lVLA`6(O_ zYW3gcf~}Mlhu@B%(!$_#0Za6xMawoRy5w-}lrO^RqkjJa+iiyK8Pz#Omyn}hkR5t% z-XoN^OPUy!&cENbo<^R%bz-`K{2z_fA1gyHx7A%de&7x2K(&;a89;!uy%f^dpBeuW zVgFE^;Q`xqaDMU!FDN>S*b<-cS*y^s%A}(4jP)bGjxPmk$7)HID_S}usI6>-WOl#- z#=y8~Upm(?FZ6ix92GNq z#(W);;}*116H0%a(1+I#z!{`G+urOlUze_2`G4b%)Ql(kC3rd)b+GoH#Fe`@ZH&Xy z5(lCbN^$ir`DmooJHwf^KW(X^HD7g?>Sa{Z!d%XF@(VWu+;F$n|3n50ewof1WGI8Z zUUvDO6E;&o3X@I0Y`eLo%orh$tWDHVutwDcUt?2!08=a%d^SBA=TuumuwPFM>BXg3 z_9;vDSveRHfBWs^VeeRV&W|;TIayC@Jdu0p)!|P*!HJtOr#$oJP`;6yq_P*kt?;OJ zdacZ#p58X9>6-?A*vVlYvnF<=IZTrtHJhW-T(Ti}JoH04OOpF2?&_W8q(bvyxp7vh z(NL)Q6`kalqc2k15Ogt4|M)cg5BuqBfc(wPXD`FIuzV^BuBLL7_1WqYyk_sVaq*{Q&U|v6rYM zIgzqIpT_l4SNm(}o&KhDsK3RQ)1HDXA^Om$bvto%(Y2G?44BzLKHm2>sPR@0JG1HZs0D z`3?)gW7aR0x*O}yK+EUY!Q_bEmIq2;otKu8BIdlwb4 zgXd>0*)Jt)q`_foFOWG!waW3;Lv@H!wQb^}d%ma+v@E^LDn#3IlONQK`vVH-E5R*_ zGBsuqL51?a#7-%G=TioaX|jg0yS-mPZI7q;UH;Db8zyzZfxjaDLt3dfV(#6y%^R=3 zUigGF%nr+Oe3B36lZNkyC!Q3DDM*|~XVgh@kKTH0XJi5a~uV!`adbLi!E03JR2zwN*$ECReKq_SCnaLc9 z-hF8tjA*yEqZ*BO(y+Nj|Ma<3@(#%D@(3_yUyH*B2*4b;`4Si?d9nykkN=xCX@5VI z`z?dnT&PDhu3&3kAtv90j7*}msyK+#KH%w1BhDELzD{E z__lHm^KTlixAuyuHD1de_MnF|fb3iK!V`IZL_%^@ld1^I@zQFGTB}jVWD-D7e~dN2 z4PCN<#N^hFkFKgryCljlhLi{ke|U-l@dsrsi8bs~PN$`6j@$57)w@2~G3$z&LDsvq z>*`G$)Hg5=9kK5F3rk@CBgeHCe8=!+2-%&At-W9FRV8D#06edFfvSGHmh|$l0#xLq0mPTCt<+PI%Q_6_dY8C1-WHxKyIZ1Cw?6@r+yQS^)aCDbd}78+og#pD z&PRW$JcSy~xSV+ZEOraTKCCv;aDVwjG%iYkV5wDW+$vOGx&27MGbfFsd+GOXWv;JD zg-;=Zd-n4YAf>YY2i1FJjT>Oe<={j7PDSwqbplv;5(iCIFK<#9XBpMUX;HLP?`0tw@ zmA|eJMU)WN>lZink%P~jjn*i7aJ>l3CgE*DBOtuoM=dM7R5d32e6UG?lXO*ZqZv9cdM%I zXU0pRwzC|j43EKuMPMFzxB<4OES4sHt2))wq3K1zhZj1T`OH(v;9Pu49^_#`7?TmAk?ljovBwG!4#GymKGO7$6RCd+>AyI|dBZIg~hy@S9*Mkk(J^Gwm^=0x|0_Wxh^jiAkz3td)I^vYq z&I|N4|9)P6o!#mHZ=blJl-V>8(>d4yrmqo+qDAY1?*SH<-DslX8F{Dv`7;bAhc7Gd z%H58`wVD^2b&st=aDZ7?9bxY5xSy_)G5-2%QBu4L(g&B3D~R4=>+S=AO9h=ZVGU9j zs~FmC)4ihtUTaUBp@y5PYn?IQ0-m)SSgKq6Q0?LUm*Lyi+&x&|?RDdyGVaHh^ALHI zx6W`j*w-=>-~q=GmS@AuMF0I#g6s0w^rREEve}$t;l3+u&P($x(Yy!VbUO2T`-?J= zwk8fn-FWMsntswxW^>DgC7JalUQzfBK~~=3vTZJFpNVdpu{^7bDiPQ_SQ)tE^AI=* zn(p&!?;Bk${^dR4%Zb{9u?J+QsCetH5@!4+Knag%gzaX;PV-1IXbRz!9Dn=)bPCmn z@4Xdha~kHR90F$Bk47Gp8xXs2f8fQIZ+k}FB!_7nv-=d=2NT`Wh{|6FH+=zK4*QuZ zheP6+m#@~K8-w1&Rh0=H1#>K6OWjebpH{{vvnr>ds1IvH$fcZhe-*q6ogehl3W9)w zV3P!+x6_z95(MC#rwZ-Q$sKQ2f6Ca=o8m!kq$MRB3-;lid;0ApWD%O$xvXV>{Al9I#v-7 z(AqR`o$Jj5MkV!1^N%uc-?H&-HP1oXyE zp9$=Jid;qhwcO80OowE@1f|*@MFcPyo-O_1HMR&E9|3QUkC67Ku|8Xdzxz{+6shpc z{(If?%V1lfRLz1kgsLO`hLF49(V;(wH2CW0d*oclCI?`E8b6bGx7h1tb)aW`?j*bG(@&-VskERvi610_I)QzIAy6mwvg~I_odG-46HTjJr{E> ztu+=+!5x}$jthO4^OG!K{eFbg(iaW5MILS+UzwZRWo_my?${KUdp>LK-XwH$LQ3EW zpa=l-t>QFW@dEr31Z~=>oOE4;Up!0p(KztQvy4E;Cngx0bWGwJf#6sW^r~nyu#5 z_{UFKTaKj@?x}HFRBJY&G-jjchxj}hYx96s{%Euy{Kt1xmg3Y^KcJYetoFhW-y+ZX zU@M7E*0)?qEznRq;3zTpo6A5m%4JAZFvBB=<|cQNvJhJz@jMkAAw3EQhD7AhUd!3Y zTrl_WTA3O3tVHU^%`N1|Bm0OuyK`E1=vy^xmnjYGj>H^+czz8_;!gnW-W?u{VbW zR=Vp2daul4R*ibtD&M68RBd!T{8q>DKX?4)&*#l>o_t%*YYh2Ra|v@}pM!gZ8{CgoT!CQ9ZYZbP$nKa?DEZ}#n=dIvJU;>rziX%FMi}-!Xf4DvWK4HpIa_T4#{_c z-9Cp_FUy^yml`bYf7pY^&6kx~Bd7xp2Nu^rduGfQ^kX))il`-fh^}HR^iTqJ0}Nc*7;)f)?K7(~T#fAGL^DbA znnfyOzr=6EWs~_UI19VYg_VW)qJ-wQoCl5$FEo$1ltf)i&jrm=hoesy7m?5G*qIgF z6lVq-Q$<;#%~$>l(GIsuT~i`fZf-N?QNNYbS0Od7d1UMhEsJ(QB6e0h2!db+5XEd0I#s7;d04cK$BlC{<*!b06nT)b^md7BjDw; zpDz8NaK$>^SV7^VUE2^!2ZUe#c0yw|la5NPAe}HT0XgRqjw2H_g}~TRMi@PL1$@mo@KaM2;5KAd_4gl0CeceRgsQRNUq~1$YGi9<=gUS_bCVC{1|KEe z@Q~?lddqC;dt#T`v8OExTwe&6#gPc)G>e`UtqAl0)5SXxl*l)_AG9bklVcrUs#LlW z!|z*|#pN6E!5;DK4<0(9P+vZ{zR`;^mjs{DduLGG1^s<@p+~;}j|@D~OgEc`F!ryt zwj6&|IXqyc6Gn(n^U^a-|Ln{C9i)-CWw=NxJd!TMQB(!J&kY(CdiK4sr7@_y!$7m?U)WJIsZ6xQ{$6FH=jDa z(K+lQ^!-r<1b?8jmWZ|hOi6}by%D@4&KG>UQOyJjROw4JwrD~uPaY0jQnAEqQItzd zz8BO%;;;?B?L5qcGm{E0QCQ!i{e&M4!rU%tGM1~N8|oC?_I|f;b;*LII`=bI&cnU~ z8jFcRbYh-v^PBJQ>UO}#*9ZREqUeN4oRJ-i3o-ixP-?i+o8+Ky}b>PxY&gmC@@Y}C0yA}E(_3cI~lfvLG)f-GXTP14^ zKg5as?T#jC**sJQxNsc(2llGbZyxSj zu_p&MjXZ``BGsQ@&&5srgsB)Ur4fL7GvqL5&pJ&;^s)v}FYy{p=x6)v1ykm{Y8i0s zbL;^*%xg(0blG7OBX6nRXi^xg#!N>+;~N!vn#l|J-MfkaIu650Pga zz@7pjoZ0asv-CZb?4xGvVsFAvM7@NUf_LiUcE7i!+mU@Is(M~&*LU^IONm9@(5G>l z(JH6^)T{i>odh&pgAX@|=DBBDW?k!mU+VP-=lmZSbK79d+>gPfG*sR9*ZmHYPD;nm zq8XjN3q7$88Un2F&~!}kViaXCaY2XRkNq3ygktl+dPEX7h>DxG-Cd5@=3~(bT5B@= zvl5f^#ob1<+XUYUwLAlVgEH_DO_wV(CJ@2fx9>W4mW&0Ln?+T70&T<+v86f-sl~cK z2neu1Lr44x+g<)Fo9Cr<^6R*AL-%C@9!b$8!dA;-uo5AOS1*iDo18a4oS@w`z=7z{ z7M!nXz;aJ*K9-E()XF?O@NinQ$^V*AN|i|rDowXMA|hLuPhY~EUrg8AXO8D${Hrvq z|7tlq^LCX>FcBpS3LN8S>Ay;W3w^~~R9}Brr91l{EwCs{XL`4YDV+P*vDR;M@a7!py->Ze8g(ppL7Qx;tR)PG|(Q z+soLwSUtCi9yvO)1)0?;;F)OS=<-Na&JroEdN zxq})a)#T+4pV~-!X-+4 zl|nWvhhM)mx?N_QJ|bVwV0!L?cH0E3U2AG=r3}Hlv%5_MP6-j2b6ObMI1pD$x14}2&e5W4vV|V+2uezC z$a{>`UxQpq9nhuzEfC@{r_1xxm6IMg;=Xf;B5t%g2HVo~C2Nq=ort#{mCARSka05b z6G#Ab{Dp?c&(6mhaHjHHUHhjvJOXLBkasC|A9*UV_9aiKpHl-(G&Sx{>5&b#3GvqNrcAgRUw`{IgjJuy|smIm@b9DsQsdxwq7n-p7MGB4$U;`%6rMC8an%Edl* zA1?E>oBG1V+}Sr|p+yMM`znf#UjW0Y&ntDg@cu8b zKl0D|;)+fEeyg#J^BzdGr>ev97%}7&#V>Ztc^huh;j}D)f77Q@WCA|QcXbBK?o!gb z=*HcZ-)z4QdIJR4ibbN9FYfVv-oT#RS6z%DXYA-;kfMz}i}9wth27v6bZb`MYY}yf zF{}D<%AUW9cgj%^_H*Hmt+tfxhKDi;o_UPlds6g&svT!KBNVv8*al%(<+DT=s1q!I zZXYrp#WjusR)`8pIlt8Rc*0MG&nG*Av!L7g%SuaoXS)w; z9xzb6_4-_hCppH6CC)`>>sYe_^Gz*Fzlh%nTWmRlU2$31_#SAS``9P5*Xzp_9ey^Z zNS|jr5#|`Et^fpXdWAor$(`3Zq82`Br}7_$BmC(?GdKRv6i*)H2V(m=TSb2F%oyzZ ze!W$7eD!9{lFD}#l9znm6oIq7_fJ#lef*FKW?agA0GdU(iTsSBE z=YBiSF|0sn#lZaUD+UnN^*^JKjnpQ!l@ni&fXPs7pR0SN_HWzIzJVf8U`)BL52O=L z{fR3uG`^oUB*3WY=B)S6{jpeD^RDGaiXt;cdfX)Ys(M&$tX~n27G6-xl=t3|mZJ#O zlP-$Jb9w=rm-vy!Z^(_K4!(L0YC@#{Bt5=^LIl)p*(QpaKm;dDwOiFx?b*dl@qKTg z^nM?ilvZ(CIocRR$u_&tPq!1ZnT($uUmz+jtXB)~b9ToAx-p&$9%EKXlYv214Zy#c z&lXJ#)E5Ub1{Gr-m+8>DNa%rt#y7V34(^JnBy4kz(#MmM4_Bivdd?>uIG%~TQ=9YUP87+=9oKJJ^vbM3hi`K9_xjC>c57Zb5P{(F!2lOXpd;ryCO)3BlV&GD zPee83gYw8|5JxT4Vj>cJN6mC%fP1X<;7=qL*1pAPR3F~D3-7)VclogLIxR6553{b* z^U?fR3+KpS+cNF7cLl{+!R$|Kg9WhWTE7z-d> zKV9T;?Yn5uOiM@Hfr2-@8@GK90rrND?a3G8F}YPvyE@d)wA_j#7~AQ^Oo4k_maV&| z7=z2&E_F94QSgQw)|632}Gy5KqL!u4#6u|0-xN3_eASIj0BA}2FLGRq=l8nW-uZ;!+J;svOIOQyJ$ z84Ple*q`H+f>KJ>I<@Blx$N8YsP_ymwb#N6w_^JV(>uogU`#&ue-3WBw=*{eqtCAW z6gVyIgb=z{z1S;@82e;U6R9F4=FTs+KOEu&5&GOSNpKSrlmXsKj7#xveJsUYtEH&% zbhD%D@jfqO{V6B$H3J%|kV1iF0;Gq2fV;U7-&$|g_04&I=f_+nU~7X2t7VhNTWl%P z;gu4Mzv@_1zDSfLn{&NYoTBhQv}>O#he>gx@6`8NDirv{*bq^7UJE}tedA?Kyzoz1I75LcH0?Uclkb2ybTkXNZNv;|C^ zOOMMPgUCqi&puo~=NEpIpEIaTO1cRjuYZ9&t8T&*j0){Y?*t+(S81utPcY6&-^X?y z*%4uqS1s>-Rcf)BfHdl>G11QwHE}NLEwp>c_r9>&(Upb%nCA6aKmbQ-Zp-3wYtx)q zZ8LK&F>s{5iI+~m!QspFH#h$OZGePJ0=``QCi}uhFCazZ_fD;_BMvpL>W`#)G*bHW zXZIPO((h~F+LCd`lF|^VB)|=n*FqN0J?OQxG0K~uW+wj2lz7-o(}(YsT?#GwHCF-g zCEKOlbk!=Z_>c%DV4gk)5_&zaoSC-Z!^w<9jcfA7R~tsPi*hC!dYr7D0efKoad(xl z4F++`Vrg*$m#m+zf~7No+~F5klBvpQ=$ zzsNm}t`^l5F7vVqc#`MWm#hL-I#5I3=(RY_n`=j^Z<>wJ<ky6m)c(+(ov&z$k_j-{-mqzDQtq$QWB`4W1zTUM5PRYA z#E|}in;0jF`12Kb82oqEAQ#+(^PY+=X^N?;2!SCo$$$`~yoUe2@)AgssFh?0c;|83 z_yInbbK}*1#2eFLz}Byuf-Fx^;Rv7A8LyKU_4LpIC@tS^-xve4%(;lB1x{nZkA2e>dFP~E$6wR%QtW2(SBkUp z4x!Sr<$^=SZgyE;pHZG$$*ypbzZ!u%6D^0jp*{}%t0Z5ZZOGO*d%f5%DUC6~fJyPT z)aO!dUW4-axKW?AJDW}HH~;e3bG=Rs#H_2I_d|U0gOl}7@HXxc*jM~6+k88PVMV2? zV!=(lZFR;;VFi}QqZ>JoS1@(qAEJd^kcsV?EJX;{U$;t-o&QxZc>_qY1pn=GY-}{s zSpZ}asBm?b3zz~wZCVm*)Fg`@7b!V9&kmVhJ{H_-Xq^{Qr(1E*08garQ!1c=e%%?L zcWT7m_k19Ow4FCev0Sl_JWa~}tJOk=wD`@?KZlSRJpaW_>!1yN){Q3H9C|31l>Ch8 zf$^L>n#bpM$w>`u13>5r`|Mvy^4(35 zS^9TU6P*!iDXE@qILp>SCut6^Cb)2xXzAqu%bh;d!GSsC_z}7|`n&&BV@#qrf%IMk z!_dMXs-<>H$zZoBM-F^YW7xTU?qlHn=a`o9`IlW z(}dD{E?suYGczLXF{@{I?{S~wii1HrH-JMdR5#ggS^xrP`boyLv4Mvo4f_W@44tGV zNyhr~BYQ-s4Rx}8VfpZ&nXUp(QorG+I2TUY&K9D!6B{;dOb?{W;^Y6(1_@0-NWASm)ZDkxI!eIOtbZ6pZmQG z9pSxdfT28~<7M3KQtN+*Uu}5E5d`bBaI2psS^jb9k_oxv(4FP9atR=gK)sc0`u5t< zf}+Z2`fqKVxuox!CaEoxl8YGIM5UzJg2G=5A;RD~x%s-9KU15T(Y|zH*LIt@{ed$Z z-ohWL#%XcQh;)B=uGn$=%lq4WoUati@auYvn#=!ebPi}m2)q>pP8lyIbH7?PFrM^x z$@XXG(q6vHhTXxqJ(Ag~+%`4m@F2h!NKb{lc&yhh`}I5?ZFED=ydc!;>r^eTC-5v9 zX=5#zCw@70&;7aI)5K(7+{OAt>;!`1*?ow$G4|6Xv}gpNQ7W6Z@*&YH4+{9vQImiw zWnc{0X@CBn0R+iR3&l$LjXu=~ijx%mAPj*h@%xR9#V~J%c*x+0X+ImB0Z`DpsF2S5 zP$NI*HW+et6!uE^$=px5;JytJPajSjuxIc>=?Om1l)WGTCfXWspW}XI`^vYW&F}>E z7LQPb)eTOA$*~mHKp*Um;WAm`O(76#Dv3R;Za9 z`?{%~CR|Jk0;0`??DsV3vZL<%T~2EvNGD7eAUC!6d`&*;^<-Da4Kd+H}-dRr32?3YZ^W#RE5 zOq+oQi7t@;1Q{%2yjQzYiA(#FO*pR=FyhcJE@)+g-AJ)W$713# zgIQ=$O)}3@gHGs6Prd9ZX3u3mw?X#-{r-h{L!0p7)x9Tx4;cikqy9bfnTz}xkRG<8 z`=wI5&&ND2S=IA&j|)S2u7-~{g`q_8CH^eqFH|uWEqD(voK&gwl>g%2kr>x&H^q3U znY`dw>L@J7{pt8+gBouxtv)`kQTVn}k&%0;N>rc$HmeDomI(|@p~_8*)m-&-=(;Do zA`me>wDykrYej$A!KX2-^}Lc4=go+ zv=Ee)4mn?2;)KH84U!YSWwcnHeAS4s{a60Lgs2o<{67KqFE30qHe>mmT^ZG8^*i|k zYjzXQ;CHbzdGC24dpu~#{*0Y7Ko;3|E)Hr*bIN2hrkt;vxY%rFnXRPzW8#(faQBhV z)im~=X;W4i(rseqNr!w7$jZcbE!ie7hzaZK3sy)vl*3r{x!TcNJcIr$x&t~oOc2Za z=vNCw$ae|Yv`MF*OxtVJKa$2bxtH~te`2F|RgbuRt zwm~D8w7g{%_8z#T8gUQr@BGpR*Yx`uzS1E@fQJ_Nyu?pTPusX)NhYZiE!na#Yl28$ z-|pr-Do}mjpRvDh_XOFFPd^rG8+Q0pK6n%_i2A%kaIPPvEg%oB9NFy1PpV^G(k6W0 zr#upu*43WOGJ?^Lec(XNn{B1Ed3iA!LntB|}I5$2^#)&&PirbYb5Kh}^B@MH8 z!3605Z4UC)Hm2>{7S5iC&?a5tG;6wkuMBAFrsk)1v=xBeab0R~uhy4cn)Canwb`Fy z_0c&T16es~l7jf#>z>;Xu5G)&+%Z8XAeYH< zeB29qj)J$~Sbo0d8Sn&GygD52kxssyp3M|E+mCA!BOd)kJ?{7Ji4v^1-YqMN5)BBP z{x#917bLgcH1`JKXy!9gdIBbY2!%r>4lgSa^v%`BAQK@J=0E@ z1X-hlV0mxk@3e}lbcOi1adTyq0VGHPh*IZq9ubm#7MW>oUgCe!)PvoRjdu|?_XcB7 zvX0-;IRH%J2r~m$IVGV_6$-~2H1LgIKE8`yBn$l2YaFqoWM?X*|MoKOMU_XwT;1sX z7uUO@Wyf2gwq}}Uu@{dm&YW=KoHr@t_?(PL&GWeNL6am7 zuLiH(nq`_s63>J7M|w4$EIr=elzapL_EHx$*{qf%jkNY~zn6|sP9TL}WMcIY#yN~N zf6e)U5lSyhEvaX8@hjRs6yB3d8w)J^W`5R*5Dq>j{nID^DVMlnc?8@6sZKVNXP`iR zNMi6#3NHeoFpxBM; zODzyirgT3|%$I4dbFTqm6$ivC2i)uh$|fH#J$87HkIS(iL$N#d_`(0B^}u}XNVXM| zg2@X^4=B^}bOK5`cgx8PM?~)vzh~G~GkwO8{DA#!vU97u4(ao9;hp@U8|TP8{jiJP z^Sp`Wd@2&E#Q}eWVeAHz4bYMRfkb!&32|@KA1{eVyVMqEa?UAr!Z0%j7J&eu+hRBd zm_0dyX}%;=C9KIWtwLGZg&pFs!9or8TQ;#A(b^s8hDp1cDzln0$ zQnFY@X3JrM%!Y`mhfE20cmAd|{|_VMmE#eYS+PfM@_-Tm@z}&?+)Gs2)(71!Wm^`1 zTd&p^SAfi}^TVVu-{e0hwxeyGy%+wkXMut@yxuzVKe!MV;Rs(r$UuIqzs$Z;{t0hv z%RR*9Vck!(I@kHl3du`x@=y19NLYhe`g_e(Hs13Qu;p@x4?=*G|jRM%W;t5{CNIxDlyR_x_{ShJ#O(Euv?!Hw0d zHM!ll#qBb~_Iqg4y9#@s=i9B;WmGmfD}MDcohTaKbj z{mgoQKp5}POPts724s*Zb9A61keD%jgHQX?Xcvrm75s6bCMzS!{Wrtx>15ttIhOPK z(_OSc$s|m5t>&HxIC$~+ce*!p>!A+kOr5haWVd6CyIu>bvrbvGAs#>tOEwtNX>s|l zzwYY*#8c-p>o-4Wu^9RMKVaF4tR75JzHk%_2mP#G>hXPrI@Z|j?ASC0oQ;9zU^Er<*BE8*x;W(Ek2HLKeCVmhdfMpu~S~E;Nl_RySkB;4Cj3c{Q zG_m`}cG)I#fT3@NfCsr9`$_QH zrE!1w?>pMfa^foLwUL}dHH7531wS=Pe#JV{ZV=^7lzrNq+3+Ngu5nPnK^#f_(*-!c z6PAVUeC4sUc4N#ceaEMwh&~?UczR1tFUu*-rYmw)Tm- z2%@!%WQSiuhzV2mT{Fx(i6P2-Vb)QEoIp}3m#yQh*^NocvL02Jry(4KoV7Bu2j#l5 z<0iBz9f`)ZJPw5~0YpEhhyfk$-Y|oP&PkTUTydwQ-hEh=FtC#6+Mh#}KH9z8q(L|* z&Ld%O1iUdOAxX-mrE_GPdl_&K6aK$J3*>@7!kwQ~Y}iqPq;?YZf2*9SZU91Vw-;Io zYXZo}%dJ9G-{pPSGX^x(AH(!KOqkPvHU!z=M6*-hxIi?m@WdDDkrir1{XsR!uoJYt;zqEhJRr=&8_?0k@ z0z@wOqL=pFIG?^XrM z(hu74xhw>Uq%4-hUP=D~05mRB$FJXR@=Un&hVF~*5^(^WY_ec7KL5&_YdbiCX*(KN zoQuY6p)(8KH&iV5cM3mS)Z;y6=6-)?G)Y=3Di&q}yg$?6eFwE9q3EUsi8RkBFlT=xtiuB$a8Kg2ZUScE6zgz9t+^0Zho=6a`|FSmTt(R zVFx%m-5hrz;$}(Od@0_JTjn8aL13I~xOUI#;qeb+clDo1VE`oqlfjJ%n)g)ZoY8*c zS(B@h3MuC((7<)6wQOqqQGn1rYNu7;P?Z0&Hfx|016hNyZUvRl#`5USuyiN_)|Fg1 zLI$t|yr9JtkQ;3bw4(FmCn{t8Z>}cQ6J@VrZI_iRY38^89=#`7JEQ|Pz-pLTCMrE! zcHRc`92>p@&P+W4mA?+ay<^H!K#aEm2K9K48(K3RL?#Vu%Ll*B(|M&{nbGypHocI& z``&)DL$PbQ>-LbKL=b46;_PY5RBG}@^s{%T;u_}ZPQot&T4o{IMz9JgNH6j4@{LYI zby;ZeKR3hrnY!{>H+G$kx<1=?E*lLA?(`kt5HKS+d(JMv1 zYkGKk5yo4vV-H0SM1`2pbK1%t8Txl~$?Tss)?XT$CodWf<5E&qM~W)kLhX5&wC{)m zpb2|HDciNpS%PU95_&?ms}}|W;=21Yk~k5PVR|0CP&OYTx0g8>ZL1_J7s<{y2Rd3w zL101`d)l6OXf_i_q)%E|E?pr@U?@*M(n&F$utVxW z#-D1FZlY`xCfY$A$<;%D-OH(@H@De9OEL#__@BR2jmzZ36MD*{KXJQlL#yg+W@C2r z

vB*i!vEMw5r}0vK12q(%5)*S&m%3;&%C76tMDPITxfKRAro&E``LjutHyKzdMN zk}2AtYe50u!GaT6VA!_QtZ;zF54bGn6HO0T_9<`TCd6!Fvc`trQsDQE90pkhw*?8)<@21ajcGe%=(53Q>QyvUcb zt;Bw5344JlJHICrU3|7K41Q+**#tOP0{|I9RV9a3=1rmf6PB6JssX#$hw9DQOdXkT z@#9d{k=N`?64@%p?_Vs~{WSiS%S;e6}g4shfV(vcyVksrQfy*tlH$l;D+UszEmO8kHESmGG z!ao>!U9%!n6Z{EdqUd@|DqDTYCSyQgw%YXwz{sC}h|U3v@J*#8Exyvlcr6N?GmjE> zabc*>WgV*QHDG{n=S0kWx)%5>gpeg;y;UH#uu+g)NLcrpeEB=$lKzB{$HK^6 zMteb;A!{ujz(S#iZhF!|RTk{H_OW{RcTIFe?j&T-_l2#u<6;TDmV8pW$MZD=p`@8V z9i?E`0(J_#N0r=g3Kma7sR!adM*5$yp;}*r?%D%zqMfH~jy>X-B+D!~@h7#Oe3KDP zKP{C<_RW=azu!HXteljXC)+*M69!|ry&HLv&5AzfUMuZ_Cl5Dw)y~^v#aF0FkE0t8 zfPwneTEkyR9}d)4m}COBE(~Dn1in$=B{{1(5+i$<2u%53mS+}9Lf?r7Ocq1*gN|)b zW(+zT+B=rOX^CH)mS(cbs>I&UvwFDfJ)w+HRxI(IeHK=NRTXBHm`mn2X(AnWn-s!& zBq;a@1EjarMH%RD2BZzFHE-Cn_IwV@t{)hOwfQDz*;fMlx=S6LK?`sD6?W@Ac$PTqhOM$bp z7qx{s`Ibb1!vUotc-?Ei-%jkFtyHekd$bDQhP!D^S)8+p$KOB;Ser0FUlT(XdwJ4S zt&Ht#{?EOfkM}1&%|Z=zz5aU$cGp?h0l)?Ar{+xdscmCdPi5lg-5SjinD<@RNL?>S@Ty2%1?aoF-WSLZW_l8 zhr+oisNIZ{dT?M?*`)`7FqnkPdT}(`uDw%_Pw$wj!cjfWymD7hC2j!-Aq^7#PD(M`(L@t{HbEcyN* zHo*t_3ZJ6KJuX{+ifcI4p7E^7`kLSNXn*>=2)!dRTM;+s#(@`kD_l73nZafcRk}Tf z|D?CL$%Qim^cq)ZU&F=FXGvG?7;JX7PvC4ei`w&I(vsIG_SzE+kn@x#kdUh)FmAHAac$Jn!fUsQL`{`ohM2snMRSXbMq zVv(98@Om{e*Y#y1!T1xwtBEMP9Wds+kQtR7`w2!zX5#u=;2LSb6KHuMW5Y45rfk={ zye0m1e3@mI2^Kj0P&4@!QM7Ao-x*g&8pAMAwj~yANzj9_^P9XkBRdmg+-T3h^{xEX zz{T(`h8rh0H>}DP%I&snfOiXAQlZsUmr#$eK02gPQ0Ds&xo&h1L@tw*3!CaZ!lh=t zAC0JLIGq6l3LamBTUDj8P)|GDT^xL=hbyPk>r|N%IwdN^@0eH51z$P^Af!1ki06 z_N~Q~ts_$lyvYI@J6%|pe>`ReyJh=O+>9rqZ+NVR_Ad}5>ym0QlcdN<5{ekc{y31~ zRoS%OJNLhyjc+kM^B|GF-9}D&4RoTqtAnHsrJeNrznr6+u;Triw|FO4RWlT*MD4vf^;`C9bFR$@Rz@|m zin`JL-1w4Rm2UKO!(f8sZ%q%Xa|_^KcYasPjC`C5A@h_Ih&FF`_(84B{Z=hiBeeLK zG5!;y8+l)Es6-pc&^a0H?bqHR23I)q(c8iTi+)jlBM%Q zk`B>lt{pgbF2q027S#=&M9ni*wmt$=~xKU9sP#gna1pJTr~6QnA`HmGR-%`qCY zs)BLZv@T;CU}*Jaq$@8r02TyIK_e<9^8);#9~kX8agZGTwM7R-$|W^O)u-s1h_+~= z{5HcJKT+}!Lx74Z&z*Eja)ePQQUs9LZN@iXUw?WwOK{}HMTT?aFyB*ULDCRFC4G2d zpkB9=dm6zMRuIjEAs7Lr-zVo;Ch34IuUk+wLQcwgx~bwp1vAL1r`HNy=K|2~U=#n; zQ|T;^;Oqu1sE?D_`Qf*wM}4);hV*tvrA>CS3ySqbXY0#F!q!x$?VLjR2fb}0%nXS9 zI9emF5SY?z3_dwSMTTke)AVEW_F%4XU?3NbLO1)NQUp+ z0B_7&6sz!2G0?Pn-?}j(5E4a?6em_}IO$DuMgXd7n5~WYq?UMs}>d z&P_cd(X{1rYI-W^UArwY-J+~SZZ&k$N%YsNa8o_<;PNc`Hsf}%f<=|3rCjx1e6nI< z;4I)*)B2)u$jW})-0=zVU?EVF=LWN_*k5>`Qx< zljx)So-ZDWuv}TpRF9^HF=C0ME=5-wiIpAy?VFHW?ANx9a@MyN*_YZ-axzLZCXpQ` zvp%8bPnn<$os16dBE`E>^iPJmKqIV!*ETP-N{-$vfs1eMFET_m>W>RA9rXfd{URlb zSu*ez#&Z(7A$^0m`!4iIlhmW%UWG1m#ni@{H<|HO4MsZMEj7&GtlPX0yA)N--A=va zY;`DPLLt^;$2Za~?qaLl+O^q~GkXkNY@voRRPTvqRuHCoRAJ;ne6yOixbT1mG@0Pg zdXAEmi}wT2!)o%#%1h->=0Wt%S%b~7Fj^tWj|V$`4$H#_^>m@%3vEKZ!oa9TWV|0+ zU&LM=R+nB|wAx%(D*WVwSdn@K@xDes%M;(P9#}ivfaJfa~jML$-Di2{?o2me)LxM@9?bo9t zs*)!5m{eIm-JbM-%yC$OG1Pf0Y@z#dh=PLQVk5TBV*@g)_m>tTnP7ZCK}rt~y3!As zLw%s}FyM2pJbpM9oCht^rVqk$?^WjU5(rQb6ST>)Xra?L9gNd@je11K_%pkaHt~h{ z-nHjv@>39T2P6ob@!V}lzuYkV+IB>6qT+h~G1W)-s~x%Zy01jjxr^dYB*Z=fcTfgx zTtZn@kSetsjQj(Txr6ncB41>Y)aTPj(E;0eB29<2AG_Wcc9GviPnZ+WVzuhSkB(ec zKPiLKU!rY|SPj(FoU5L1ZIV@(61i8&;976G5^iRBeJlm8ku61ua6O*&?3I?*=ElG4 z#4e1sc)+W<7QcSRTX(iyZ`1qRe$0Ns;@G;D;^H_`%cx5IydDkMM;8V{LkaD`D|c&k zicC6HlTp1`=*WzEl+>Fx(>JAES67KxdKw*vOBQl<{|CP+WaYLD4evNQbv~JVgeax5@~%1G$+RkDWz{3dp8K*P2WMGW1U1VnThc90j8l z^)b5bC2D(GtbZ_yd78>C){7aH^Ef@3Y^`0lQrwC6JDATtpTm;zJxi31B8&7!{4< zc|WXY8N~C}o@OGyP7%p|eQSUiJYg6z$b1UB7Ygmz3r7;Kt3SY4{M&?x zXMD3eWEO=PQ~(xmq}Bq-+?~b8=sd_)pEG6MEC(s%7Tnf0G>vs}7>nW!baBSIiE(?)xhFtkuujDr^V zaq$%0j?~6Oq`{vMGn$Q!ZE6(w-QK{XF-$HhB0Hg>yGyWTHd6*FJbBZpEOw<9Zk&C?r@ z{0`sEuS$-dTdmRUvmVots#Qj-KJ)`)f#;B@BZsw5(supNyWBsz9s_qLBR|8c6>cXb zdhf)2;p^+&>cZ^K6i(wO?kz+i&X)8-y{*a@9XCaphin$?sEA?Bl2_R)gd)6zycZfv z2aVClSH@8F`4SEuDIelBK;QHmi?4(WU8;vP(U`y@EBHvJ`>UM2|zkAK|H9jW6?^eS4TbOgXLkj+9yzqW4d5zp0a!#4udV3uhQ>TY3>bIcyrC00Ukq3IPszVOaFDlj0V>FvR0 z#{^=hVdj$NhjGva9UZ|;XVxT|cEgNlbhFEtCf2g8^RjTTZo_NsMV}h9B!HwG~nx9Z;Z;4=8k?H>8ZrXdp*;22hRL*N-D?!s_ZL9n&A?0gB^ z^c$$_h_Ges%$llGjkTH=|Eku9R4tXr(Df;H4EJBHJLtvKo-EEGMgT{gyBSgTSt5nq zIN&C2X?)Jzp652rLl$-^V-d?LB5j*4d|w70q;4snni$>zWn}Mbq6-~$ryz=E?6i3I zVcn**4K;RpFtn`7#o0x-Q`~67%RzV;_{gTL6wl6$^xcI zY43isM5vA-tNC9kMd3&dKC85F$<`miI}I;Tlbl^R+lDB+j{0En6MG(m;9Vr3iW zOf@N6BZYm&6=i-B9pk6&Qb;JW-PKg&H1z-`Rp+1Ol-jr>cp&oQSQy#RGXusaS#d4v z;gr8mKyjcYI(n#~Yg<1c0s@Ng?|W8aGK*^q`@ocPC&h+o2<&kXE4T1bjST|Q}8 zZcQz@wLd>7LN0vKOqbCi?yYjf2_~qR0iSgPmws0wW3F#~y{|mLnH{%!tESCVyn0CB z4atQ?e8aaFu=2YHd=UCbnM35X`6F6Re~X**J~pwmcop6RSl72MR+Gr-9!0E5mA*vo zbW9zKN{S3DkP3Nx`JAj}LFh0UOt^JujqmQ}aMZQ4ToliX$W^xrPUsS`2zxxB*p-O? zpf?T0aj6WK38d{iv;WMU=sITd9>O1Zsw)xl!Gw74jrXlOxfk`JSm8J(ht{%wz<2>s2V9W>9hBRE-Ns@;$!2Y(9AN^ozjiz_M_TYnUbd z^>(os3AxNoqEjoG1u&nTvqh-HK$aP6#GxWHBuAYB7tUWKgwI!RN;JK>5~vZi_{y`; zggmj|`J=NFmN#ZoVQdBIaAqNy?1mzjF<#DzKE8Kct~N3mEj;%q13T?ym`XB$)iGNb z+#WpQ-smtbj$JrT;_%Z$?Vc93u;*X6!^2zL^H2SsvoWnVxAsN1lEZ$wE_)Ys+rv&> zYr=tN9ISSre5lO6=uKKzsjzBEZBN>`d4@7&izFCm(S!2S8>?>)Be-x^lM|6zlrB>; z+GE2#B^hgMzmZTrAk?=%DI%F!@1F;g+;zq{Dmt#_yQ0q0$ zDzZVB`@9NN*_d}49#+})e)Enj~L<>Vd3%;UZu zN+PG->>_Cis2g!#ay*@6q96cUJ`pT#F&#OdNc}r->gs;J!;$OZ2d8gHX!?s7wD2qM~&9n=rbsIS=h zhUb{p(ZuX`+R-3#2T-V~IXWV~D><%95YAjLO^s0Imo?Z~K!!fy2i8W)wpRTp>|F}RV zvz#+ToQ;eLH8vhE$Xp5f;~i*qgkd)MrNT&mX|JWYBc z-TMvg@Hz7x%7HINyV0S_@P6k+xi=8O@gxU|T_@$B?(K$l^iRx=R{l=qMxi@+Z9B== zWuyLaX>2`dbwIM9y0Zhu&A2Honp5_6V3RDf0aSJG^5S%(Ozr6jaCtkYd|BF8b@#F! zh@WoSwZ2MhE91G)OuDj>Q9KH65NJ3qh+sAv3(1lrACRGR)19Q}Qh54HJ}tQUiR%8+_jRLL$OGV|qzAE6l{US9J?{;= zwf!Z(;wkxFxV^A9&UVqx#V;51y@N&82G)qEI)Ru2E1E@5(=r9-f}rfJNj8XUj8Ss< zocFG+(NfTBiTw;fXVuikL$~ww1I$>{57J{nx~=Oobf=in@wxV8sCi8f#Oc(X8dOaC zaU6&-sq14M?3Y_c4xd$!HA{^r@eL!w)9=BG-=l-9-zR0<&S%$X)nZV%up6{5fe%<@ zU__GLH&@v%nmoI5=fIQ_BzdlO`T2>SA4ITwd3DS$8_j)9nN#|EC8IfQ)+)BrY{ntz z5)bpOdf`JOt=z(V~CAB0cvc8{B4YK0=bD&}?NIdo9!e%h>{t{=!yYQXW z`wz7e_z1VqgE`TUSnT!eU`j;j0F!{4kVhbOgYO$ukP3?QFRqV%f!SYE*7h^rN4lRk zx1sE`q?;yQ&iFLSx9O5!U(GKZYgeN>Ev25UNpiir_ukgL&dPB>E~58>bsn0zJ2kA+ z`EUw&RQ8qt2iacs%FdoLK6q_O2y9PEMSj`bD~;UQ&1*xYNW}}Ejp?kny=W-~)d1Vr zXNo7qfAv+Rb}Qsx-IoD^bl>*DSFJGq)lZ_(Dc1$f`La zg2&T`kAglQR-d{pIG#4orZ&Xq%LHxN5?ON3MNoV_+B{m~bO&uqCf$3sYBCGiXN%t# z=Cg;kXx3@wPvz$_C3`GrGs%%IY^u&J2;6WgxRRG=tJHK2;oR>Om>dkIT@o*~<#BDb zpS_r?j${HDm-!J8$%zKznW(Q2>T>LCLs}$fQ1BHqkD8*!Y6r;myvIIbNc(_oTS^1CK)n{wu7?uyorwm3!TBL{sVDWOZ);qG$c9uDi(Z z=Z&3#-2%08!@d&a8}KRPPXK;E)2zSuh57W_I_N5fP~~ZY?cuy^K_Y zYP)1-$hy?VUxCFIR?=GAD}+rvCCXfA@jS;Kv%(*DO%`yM_k)fJ6f>FJeISTdB{08t9%1%OU~#;{T*y2A2+MVzpz<#S_wE7JEId= zxvnc)FrIeCFxIRisXODg5GQNsv>*lYg>mh@yZA&0VL;(r{P#*2=@Gf`(D0 z$Z~>=fbm}?G#fD=u6<0LT+ZMxA(8 z9kPA(MhVQQFiVSnjBZus7Q77_7-XnlI#J}X&qni_*U3svk3H?MqSJUR#aU)T z<*MC^Iz|p#1{XX%u_>Xhmta)?5zjtypmsyu1vrxHLO$M^=}yOCcJlzRHJs(5Ejj01 zw+|@7v}tb_M^;jWQW9*+4j&vx&7Sd`ZkIotEGw4EVdIH7qC(pJu;|zdJA^E3YCaed z8E9R19-n;jpqw=N+D^Ot#)RgQaEYq@Jr{3;w^8Joh-o@~)sjHqQ%7-woI4AJ>5(Qg zY4J`uL5#YHzgi9}v%^lYD$6g|Q4aDg`kE1mB=?rVY%boV7>2a#kC#2=9G(5v+d$YA zZ-8=HimLnWhF^aInfe=H&q)XuMRAZHNE7%z@=$;4JtABm(;eCp$dn}*wQBqs1RI5w zi*3@Pw+6)m$w3^P^{%6Xcd%V=X7#2%Yg#Y(FW0o85_><~F`IaSEhN|$5zJo)iDn{4 z5CLveE{)3qfdNGZ#nXs@UoTEGx<{fJ^bm4|DTJ3!+hoQFydH>hzV6W>F{-g?vPHZ2 z+lpjU>zbSn9+Yuy&rIaNrpe%XMBG8VIi2B%3di5+JSA`;a%#8dU(tUDT(zwzo|sT# zfcP8zHG(slDZa4<%TtU%GN}x_OY1X`^V+0t$&&j820ev+M-on&`8<3|R8Y|$)_zuF zNQt316|t*@=<4Ib5xz-4CZ~3QlYkU~l1X&p85ygKa=8{%hr;8$5v$4WE{yq~}b`pBxVyD*Zr zEbChOx8=`%@bb#?$9tp^WRUX+I7_kZh{J#==5zL@AK&JH@n{IO^#g0lwYAac{6<)f zf>sWZg$xIen_q@;;6a1=<#AoY16hMM`l7Dyh=YuYn2kDQS!4&WkE~bHARb)ALnY52 zKxD(988U{S(ih!9s|E zJy%^De`BJlX-6ymT(!OOn9KO#y7w;I&h_2?g?sn=&RFP@N|np((Tdx5_*j+pf`8)uD)eMk2$T|-a?0D4csctb-q;M|wXrLMyF*0N=*S5`5_QYT^;UR_)L z#*qR`R(zR@P70)~M;bKyGIq&z2oc^^2%H9bKjfoJ`L+;yoZGbp+tyk6BiG4rapmtRV0rJ|j8 zDLLk)zTNp;@j~i3@I1oQV$ip1XBBLB50RhOxqc{8Vh&$5PW0M!JY6Dd>g{p-f^-T} zBECVg^lOC-oZ=oZnI>g&D)+H>b>T(L>En`85sv1d8TN(YT85l0BGNFOFzp(deN2YRg&MQR)yX)6Bl61{GUhU0j-Ghn!g%xuvVk1FZ zZl6vxAMf}s_K$XHsxemW+&Z{aJ-!LQS0w>fuP@;2(&vkqy^nhv_0U#g$I48}as6=i zlB!gpW5SG)(~P;(VUw4`H3R(7!tCSsz&*P#d%DxGOZJcQ{LGywgGu^20hXulzN%Np zuc%uZry(87&gmAuVLAYQ!(^~vcw6xtd#FgAK1kAcGsD+ zgweR{r8W3IOQ)UtWl^r+qDXObUaHeJWE%iu`*JQ-U}drp38W>lCGwvEky-bd35m}R zfOrITp*DFAnvP>1o@e4~JZjZlwB>I~^07+Wke+tS?`(*L`yofgKg~(z!KG>uo|$#P zn=XyTIq(Sf?QFj#dxIrv8d~zNo5bW84=Iqui}iWjTCSy8ltGa1*qFR)f#-^7Eryf% z$J>vg1GOSHF$>W;{F=TQKamoB&ZV7i(S1YFu5({{I7O_uBO|CObSi1fPsDExdm9Vh zBbP}?#iS$FWt!QCpN``Pki$c7J#3sCFi;u92x{^lB)Tj1UL3=vh0rBgfol z@~ZE(7W8Kh*!_O@D8m`?hgmAGYB_77`vop0e?mA$mfsb6@PUXxf-Rn}Io?)+r1%5a zp4s^pYt&I6Ju2j9hnLJfuEi|GtUTjCOfO&xB(|z_tyxO1q-uUxd7zI=C(bhQ@{D%3 z+F5OQ63*IrxUYF{Q_haDmZ2?S)u_$hNqMZvzmpSqhsO&YOOk=z)PnIM8_9{Ond~3#}brYv=y%eoFc zx}CBOHy9;NNvl(tBm5klGQcMr{r$=v09+SK43OhI#P9FSyPa3z%^z5Lwqgrdd%Nm?=x+4$H8)8oHDE2_IxVpkax6zBUJ3#R$ly3M+(N2 z6n^4Sp3^VtK;7#^C6YyftCoXOF ze8OK_nU@OS_Fk<}yFRo%;;py8tH5ghVJ?t}LETc-MxnKPh26z-JIg%`S^j*gOp>4A zX*}24*t>;;Aa^yk>m&%V>*Z6oXz#08qR6Dw2?&1fNH%_xMjJ{8e86oYNq9S%!t3wL z8;de(hO1%MW{`qai_ygd%wr8~V%(fT%Tw!` zpAPO9$=wz-__P`5E<&5`;WPaN6u7C2GVoK`O6(7Rhi`M;*Gtc7fnX~y6_agBuh)Og zrR>pGYKe@BM2gx`5kG}|b%1EQk#rq$cya~(#^>y>77npwmeQY*B4d0ig|Z0u6-bNP z0k3ZftB$=Wzn3L5blNQ~LcF|2xZf$%I}9*KGxO|f83)G1PQEqK6(7rMCh&mOo2!c^4F3+c#UoDaTRSFc*#l+M!ROq9QuQM#uld9 zf6HcJIKFU}Bxaf1fV^nSJmwZ+rc1ZeIW~h)ZU7)o&LKecQPC`F7TC)Ker${P2!+c$ z$IQQYzlgI3U?K!{%TjI60m7mnB)uCSd!mhctFo_6OE^7pOiZnY8}!%^Ca;_JwW-VV z>1xmc&mPIQqm@9&sfVM%%apNh#dEQuD(w&{n&G5ZjpKlrwM(h3ZrE07CJoU;4y)c+ z+bmDwoji7Ql+ug39#yVqxULVwceJryuN8XCsIPB+FbV64ulx(&eFQxX!`w<^s}dJs zeI>z2r@vhJee~_*rbBkgmTa)!PGn`vI>;905OTQgRC=M-nzo{LL$L|jSvI5Gak8^9 zbKR#ORGEf982jvOY(@A>azk@cI{#GIg+5pYlXL-T;Z2GDU?cUGp0Pg{<#N7FSE6}PwW2E`p2mrai_h3mb+VPysBIy zFV9jv@!wskwUg)p`}2v_9FhY|om*6J5|2;)4O`2FWoL`l&UWdoJ{B#5SP3HYAQI{8 zXWvdPoC8h#Q0E>Q(KTgf-7i|q&rgTajNeXpOk(tlPp zJc+Z0)$E0n^q={F%7%m(!Ydo0=jM%?7e9nPnlh34K9p*^%0%}G;NV`%5`Yqc zwtSljas0((San0a0sM!nVlbRx!uo6e1!ZVoL}fj_l_Cz~BN_mL=XV);Cm|*^{r&4K z086MPLTB+207#7gAap7Y1#e41_fA0Aw=(ptk-g048BVCJr7nUU*=?A;y~5_}>5OvaWfvh2Wt7ie|?xR+;7d^Al-h z0*pNH3pc%$@u-)f=FfoEDRTuOQz=^21Mfs z$`h`pEBk-bwMq!Wpy#iqD~L%cY5TdjW{qpW+cai(&`XVdp_C>&9U2sNHvf z<(M1bkyt=mSSkKHvqP$(-pN2$M7TLvB^*p`2Etw{k<{h$5XS*G468xj~8UD=3dNwQ0P9s<%}@be0(@b5Cj@)b}=qV(@JSg(e|@s1t$oVQvK z3!Fj^02Gz6fd8jqqbU8yQ7PYp6$6LI%RG6GiV3VO`XasnhyF8`JF4F7GF8C0S%E%* zZGHwJ6%=>RQ6i3DyZg$q=J&s4at91SqpptjM3rY1jlSQX7E!~M*JK%YKmSKgo)Do? zSyyeIY>vaU3o7Dz#mPA1LPEo9KL@om@xNyNGw3_ifb$K|H!fPH*S1-dqH~E2a$aTw z&@xT`rH<8`{p&KI!Xyz=5r9@xTZcJs3_dLYUP42uLl_KMu5T-SL!&F~yB7&;$b(hX zh9FVwR7_vF4I+5f`k@eeNBRy$V;T{74)-n?x6S^e16W>pQ`iYJ=UCWBrfqbBw0N@!=bLBD z4&@~=|Mnw%7w-3>Xzc~F1HIYBO^46-VW`MVp6ZYrZ;wt{fltyqlrZB+qZu*+_5Uay zaye+-9e_$t1EXxoHF>v^YdQw-F5_PGj}<1I9*n`C^?Gbb#`_>fG#tdU(!X>5q_|2$ zK^PpaabK4vf0I1i3pYzk?GKZJVb;44+^6a7XJrhKAnL=Q6>aJ7-~1-4|5cDUDrnxq zO&avuWhhHWV3h`^@MNRQecj#nFGswzOK@;*W$CU?Drl-@2pCA_Z^n^OCd@wjWxFiv$2aGN2i{BxWn*(a+};d=j) zuuaw8#9ntrf|zs63aVU9HY3r4JH0$vf>TLx`r8?Jk}=l^7bii-_z&x^rs$sDhzvs# z#Qg~?hvDm^oR`J|p2T`L=)QaNk!GgmDdZ^{XiodoPL8p6?Ptwn!GICw;>4JnJ>Bdr;)_Jqnx-khhlgj^BUx-MDuD0 z=#CRSIRCr$gc@D)0WT7&o!=2cyorb7=~4V=hrFuF#)|-|+Czx0su2GU?3@^bn9#qA z-a8f_RUAlmZEYt1G176k7sy*pf-`EM{D;(CPIzxJC5A^2;8lb$!cc8S(i3lSl_PKf zpb%gdPMj6*Z$f^+w)rltgqi!|c)lT3D=9HA24{rE4xBw|UaTxD(oP-t;Nu*ZY5&`N z#+Y~3?`k4|<<&xRAUJBHKEpKzK73h){ncW8C@=Tb6z2s6OHWIPe7^JP?|oW&Kn1-N z`L`a3H|XE-PkA{49rW5iJetFfH}=J#*d`NDslc@O(ZUkdm0BXb=IPdd)91zx?|oa6 z7iMT+)4v11g?P(Gvdhvu&#P@}tuUW}IzEA$9Lkey;^06ll4yVbW>FcM46DuPWbA07 zL)ybvvI8%}>y$j>^-pQmrxHwYg3bTOQh#F1E|8_4~l|o`25N3nI+?&1LCXF)M-3HGz{L0x#U)PetwgpEJb%+rPdP z(QaO2hd0qLJREDSsFg(d{25<(vyrIUA0mh_ap@~EW~k$Aul_?nRtH+HTNA)aw9)(! zP|a2STdxJTQ=`M@#Y&GaL=;6#LD3tPAR`GkoUC{A)l>5MtT1qlQcEIap5N*Z+vK5i zKRQ%_NVv385*!^B|5`Eb6BeVGoB!0`k!o*hll)c=NqcF5(viRkzVUWY+?oPY%Y6Tz z2GW7AyhFx)pI1h?+na=Y;s&Qh4N9^C)2aP04`3j5b@fJ^Yr9DEAij1tt)X5d+hAy; zA}zvHR2U~~fFa{ToJWCurc;W=xoqnr$3GpnU8KTEzH2AUZY4)GUOtooW)RazF8ttx zWeRBvSSWv&Llr1pJ@Kvl?*YVXrOC~jg@DNN>xFMaK%;${zcs@zK-hI=`n|ABeE}_e zexGX&ad6-R3!7t}pGRVYYG!l3A?+l79~*-Gi7>Ju=ZE9464vt-)!j{)kQ%Jn%xPn9 z!`iueNE0V`+9cxCHmdA$^ycsG7Z>_RM&hqz9xnTNL`tpFyqaroA9WO4r(ZBa@DG_2 zWpzftU)$oqKR3!%lv<)of!xZ!%Y@V%usZ}ZL*dP7;Y)enj90~<{ZkW+rA7nlVIpHs zgMz*J@KM+GfBs({)PAMcC3c~HHENYOn7nu6GpqZ98TbCFZVMy^peS&D4FMxGHE2{6 z!-t!4{uak_^M8I?OSWAri%MRt#AGo2{?$dZkFW1A@V(%t_8zBn7OAhqxqh%eeP#4Y zN$&gm9ZNIsOpisG-xuylhwHlq4s-hvo5c$ zY%8}>fV_@j6k;s~eaN9hx`bxWTl>vDnzU_zb#1u9;#i1*5%SGcHefN%v=F$rKCdfM jZ2aewIP81QxP&e4pTvG>TY{;Bv(?XObV7oqPx#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D2%AYnK~#8N?VJg) zmQxtVOHCLuC}Uq|gfL`ZrcfbjFjT{gtgtA} zDQG>LT3Hq(=^!-gKSO;98t(2^${{glp|6}PC2JPi1?`SLwQZP(uiTJ`!_XHYQ$YPY ziWA)(fo(__0F3Ej^U4E@UIU$rzH}axh#BZes%K+ER zbXe%==wBsDQ2!Dg=Y0c?Ar-;@MF z{Y-ZSXm>+(?t2UAv#$bd{XM++u$be#t})d2qCAoEQFJHjs4>{KqJ9VZK8ytFb5LKZ z?U6p)qHos{*z_&iAMJy#L<7S{iw+Ap+G`BZz6y0kx1itAXb&y@i(ZHpd#paU!oPJn z*nU6<$%k^d&ElF6sOYe$(w-K9O`mJS(aGpB^ddUOF7i3mLo2{O51oKIq8^xjw!Igc zi6%Qlv0))6d0{`HKC;o=nfePzhY#Ab_C!x39ePYh;q$8m&G{7D+IIl$MYa!;jdFXp z?@+t&u#hvnpavh**mgpT(T7N16r<4`jThA4rs$2-_V#fF9GTXBw?0osSK#)l~n zwn?^IwQ#d5?RC*F=pWP*z39FYVXwlzD*9Ch%26R$(P1GI&POiYPVy=DQM&}~)5E}`!$QV;K_lJP zC7$SXsWG&8idS8~D+B`SozOJQ8@OHm<)N{shJi(gg_QQR&ux{+lABp}#Iv#rp{o^sC&?mtGsL!xV1h&)MT~2hdvPHlmH$tT& z|0`_P-m|t!^{db5`dj(wlnymI2M2@gLH8-?H=(ZXYI(4@o?h&0C|v&+n6{GLC~47o zrl1{8&Z%xe{R7)>qXk{;>>$+X1J*@g|;H>8y z=7s1vf;mm0*v!+c3SuaEQ;|;c^^JO-yP5}ql(f0^Q_UaDZM>&iHN@DGP|f-SRN$oL zZckf^pPA!!o^tjunKKKJH0^PV(E6TswiG34f_ctHt9t6$QKX~^<~q?+&yJ!cO)%eM zJ^gGbXwn|{^s^yp(irW+?Hh6bYJ89Ibgcf6&O&?!ilopqV!Jf!2NKkK7bMY!3U z2~0d`(r&S9vmuM-e3Mbesmu(>pvgTu!LpXqi_pFAW@5OYr>}U7%VdIJJMlp7UoO=?gJ+bsSdi1zJT=03>VX}b<2tS6817mf{bswb;QuXAa zq^Al$LO;}xN(O%VMQ}e)DgQ9pq)A)uX%zi>%gQqzo|JddDh`!jsz_S&qpan@xDj?q z1b+G%bUwcTN-)8iBuy|@KgbWiPf7}Y@gE#c8zxt?qzT54v}+>pi+Jxky_ z+F=rbpWarL{bQpgm`rL(6ZlVds6^lwe$bx_GDw6NSBID8`T>*6r!!iFI>8PbD!eeGH^*hWXs<63li4C%ca6Y&}1 g5UsRQNZPddAH24c(!z^p$^ZZW07*qoM6N<$f_-{*2LJ#7 diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/favicon.ico b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/favicon.ico deleted file mode 100644 index a0785e84d2d446329a7b7a82fbd3c39c83156c8a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5430 zcmeI0OK4nG7=TZ1CX+OsB-11%&1+`znmn2gF-eOzUXCKkP@W0a22#v$)ZeKh-n;h{QjHX@n$mV%+QH~c;L@D zbI$)d|MT1^m8J~kb}MF|nsF%QS4#POo4>zg|3mib*kcLC<~~!>qoAN5zow?xskT@q7h>E-EStxm>O+3%R_!yaV}b%#GGw^o*|$?A^O}UFhNS zQS>=}_!c|NW80XvME5s^7XN8%)*4OE`HY-#mx1WB?Ck8U;^N|8gr0jZ#gc*i(~r+@ zz{k{~w6xU4U7ZIH9{gC&1d#nY^R`h^QgVq+EwO=b0(dUi z{37rM@S9R=e*h1adi1AK_a7wTqWfrqTM-UO*LKA;OoGgmB9JTfygjX)rfD?lEk zn0tJ70|Ns+#7!8Vtq%_mcg3ejEk<{D_hmR@aixzRKYn}PzJ1QrO4ykj`Q`>5Sn?%z zM@B{@$N!OW;>3v=1etfYX3?jyv9V;g6(H_ZXJ@C`gDlzBJT*0S*{VOgr3b$DQxn6M zOquCNni{TUpSTF_mTcjB^5n^jBGV2X9UZquM@K)CJ$$o7f8n)}`aunLw6?b16*+e3 z>+3sBjV+{xu1YLUOiW08q{C+T}B80boYbjbjx%N&h zzQp6O!{IRB6Jujzk@r9>+(h=UVSh8yXtSn6}HuAE)Bc;-4!*1CMoT zc0)Y;Sm)gRS&3)iV*&Ynk2uSYg>T;@4x6Ml3mx_Gy2O$FJdriA^o`Klfm}$)p7a9) z{qG1ZzS7uiAQ71s4sqwn&(B}C%clS7W5^!i?&3HBtI_gHm zZWg`t8tQPux!ly$R40D7=w+5Vg8u@nBcr{&z54Ls!`bvKmj2nc&Q{ak;)Dev#Ue*qgg2t)t? diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/index.html b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/index.html deleted file mode 100644 index ed557baa12..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/index.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - Simm Valuation Demo - - - - - - - - - - - - - - - - - - - - - - -

-
-
-
-
- - - - - - - - - - diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/highstock.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/highstock.js deleted file mode 100644 index 8e5adda93f..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/highstock.js +++ /dev/null @@ -1,7553 +0,0 @@ -/* - Highstock JS v4.2.6 (2016-08-02) - - (c) 2009-2016 Torstein Honsi - - License: www.highcharts.com/license -*/ -(function(M, ja) { typeof module === "object" && module.exports ? module.exports = M.document ? ja(M) : ja : M.Highcharts = ja(M) })(typeof window !== "undefined" ? window : this, function(M) { - function ja(a, b) { - var c = "Highcharts error #" + a + ": www.highcharts.com/errors/" + a; - if (b) throw Error(c); - M.console && console.log(c) } - - function Ab(a, b, c) { this.options = b; - this.elem = a; - this.prop = c } - - function D() { - var a, b = arguments, - c, d = {}, - e = function(a, b) { - var c, d; - typeof a !== "object" && (a = {}); - for (d in b) b.hasOwnProperty(d) && (c = b[d], a[d] = c && typeof c === "object" && - Object.prototype.toString.call(c) !== "[object Array]" && d !== "renderTo" && typeof c.nodeType !== "number" ? e(a[d] || {}, c) : b[d]); - return a - }; - b[0] === !0 && (d = b[1], b = Array.prototype.slice.call(b, 2)); - c = b.length; - for (a = 0; a < c; a++) d = e(d, b[a]); - return d - } - - function H(a, b) { - return parseInt(a, b || 10) } - - function Ea(a) { - return typeof a === "string" } - - function Ra(a) { - return Object.prototype.toString.call(a) === "[object Array]" } - - function Ba(a, b) { - for (var c = a.length; c--;) - if (a[c] === b) { a.splice(c, 1); - break } } - - function t(a) { - return a !== x && a !== null } - - function $(a, b, c) { - var d, e; - if (Ea(b)) t(c) ? a.setAttribute(b, c) : a && a.getAttribute && (e = a.getAttribute(b)); - else if (t(b) && ha(b)) - for (d in b) a.setAttribute(d, b[d]); - return e } - - function sa(a) { - return Ra(a) ? a : [a] } - - function bb(a, b, c) { - if (b) return setTimeout(a, b, c); - a.call(0, c) } - - function O(a, b) { - if (La && !ma && b && b.opacity !== x) b.filter = "alpha(opacity=" + b.opacity * 100 + ")"; - v(a.style, b) } - - function ia(a, b, c, d, e) { a = C.createElement(a); - b && v(a, b); - e && O(a, { padding: 0, border: "none", margin: 0 }); - c && O(a, c); - d && d.appendChild(a); - return a } - - function oa(a, - b) { - var c = function() {}; - c.prototype = new a; - v(c.prototype, b); - return c } - - function Sa(a, b, c) { - return Array((b || 2) + 1 - String(a).length).join(c || 0) + a } - - function gb(a) { - return (hb && hb(a) || Bb || 0) * 6E4 } - - function Ma(a, b) { - for (var c = "{", d = !1, e, f, g, h, i, j = []; - (c = a.indexOf(c)) !== -1;) { - e = a.slice(0, c); - if (d) { - f = e.split(":"); - g = f.shift().split("."); - i = g.length; - e = b; - for (h = 0; h < i; h++) e = e[g[h]]; - if (f.length) f = f.join(":"), g = /\.([0-9])/, h = Q.lang, i = void 0, /f$/.test(f) ? (i = (i = f.match(g)) ? i[1] : -1, e !== null && (e = B.numberFormat(e, i, h.decimalPoint, - f.indexOf(",") > -1 ? h.thousandsSep : ""))) : e = pa(f, e) - } - j.push(e); - a = a.slice(c + 1); - c = (d = !d) ? "}" : "{" - } - j.push(a); - return j.join("") - } - - function Cb(a) { - return aa.pow(10, Y(aa.log(a) / aa.LN10)) } - - function Db(a, b, c, d, e) { - var f, g = a, - c = q(c, 1); - f = a / c; - b || (b = [1, 2, 2.5, 5, 10], d === !1 && (c === 1 ? b = [1, 2, 5, 10] : c <= 0.1 && (b = [1 / c]))); - for (d = 0; d < b.length; d++) - if (g = b[d], e && g * c >= a || !e && f <= (b[d] + (b[d + 1] || b[d])) / 2) break; - g *= c; - return g } - - function pb(a, b) { - var c = a.length, - d, e; - for (e = 0; e < c; e++) a[e].safeI = e; - a.sort(function(a, c) { - d = b(a, c); - return d === 0 ? a.safeI - - c.safeI : d - }); - for (e = 0; e < c; e++) delete a[e].safeI - } - - function Na(a) { - for (var b = a.length, c = a[0]; b--;) a[b] < c && (c = a[b]); - return c } - - function Fa(a) { - for (var b = a.length, c = a[0]; b--;) a[b] > c && (c = a[b]); - return c } - - function Oa(a, b) { - for (var c in a) a[c] && a[c] !== b && a[c].destroy && a[c].destroy(), delete a[c] } - - function Wa(a) { qb || (qb = ia(Xa)); - a && qb.appendChild(a); - qb.innerHTML = "" } - - function V(a, b) { - return parseFloat(a.toPrecision(b || 14)) } - - function cb(a, b) { b.renderer.globalAnimation = q(a, b.animation) } - - function ib(a) { - return ha(a) ? D(a) : { - duration: a ? - 500 : 0 - } - } - - function Qb() { - var a = Q.global, - b = a.useUTC, - c = b ? "getUTC" : "get", - d = b ? "setUTC" : "set"; - ea = a.Date || M.Date; - Bb = b && a.timezoneOffset; - hb = b && a.getTimezoneOffset; - rb = function(a, c, d, h, i, j) { - var k; - b ? (k = ea.UTC.apply(0, arguments), k += gb(k)) : k = (new ea(a, c, q(d, 1), q(h, 0), q(i, 0), q(j, 0))).getTime(); - return k }; - Eb = c + "Minutes"; - Fb = c + "Hours"; - Gb = c + "Day"; - db = c + "Date"; - jb = c + "Month"; - kb = c + "FullYear"; - Rb = d + "Milliseconds"; - Sb = d + "Seconds"; - Tb = d + "Minutes"; - Ub = d + "Hours"; - sb = d + "Date"; - Hb = d + "Month"; - Ib = d + "FullYear" } - - function xa(a) { - if (!(this instanceof xa)) return new xa(a); - this.init(a) - } - - function ba() {} - - function eb(a, b, c, d) { this.axis = a; - this.pos = b; - this.type = c || ""; - this.isNew = !0;!c && !d && this.addLabel() } - - function Vb(a, b, c, d, e) { - var f = a.chart.inverted; - this.axis = a; - this.isNegative = c; - this.options = b; - this.x = d; - this.total = null; - this.points = {}; - this.stack = e; - this.rightCliff = this.leftCliff = 0; - this.alignOptions = { align: b.align || (f ? c ? "left" : "right" : "center"), verticalAlign: b.verticalAlign || (f ? "middle" : c ? "bottom" : "top"), y: q(b.y, f ? 4 : c ? 14 : -6), x: q(b.x, f ? c ? -6 : 6 : 0) }; - this.textAlign = - b.textAlign || (f ? c ? "right" : "left" : "center") - } - - function tb(a, b, c) { this.scrollbarButtons = []; - this.renderer = a; - this.userOptions = b; - this.options = D(Wb, b); - this.chart = c; - this.size = q(this.options.size, this.options.height); - this.render(); - this.initEvents(); - this.addEvents() } - - function Jb(a) { - var b = a.options, - c = b.navigator, - d = c.enabled, - e = b.scrollbar, - b = e.enabled, - f = d ? c.height : 0, - e = b ? e.height : 0; - this.handles = []; - this.elementsToDestroy = []; - this.chart = a; - this.setBaseSeries(); - this.height = f; - this.scrollbarHeight = e; - this.scrollbarEnabled = - b; - this.navigatorEnabled = d; - this.navigatorOptions = c; - this.outlineHeight = f + e; - this.init() - } - - function Kb(a) { this.init(a) } - var x, C = M.document, - aa = Math, - A = aa.round, - Y = aa.floor, - Ga = aa.ceil, - y = aa.max, - E = aa.min, - T = aa.abs, - fa = aa.cos, - na = aa.sin, - Ca = aa.PI, - ta = Ca * 2 / 360, - Pa = M.navigator && M.navigator.userAgent || "", - Xb = M.opera, - La = /(msie|trident|edge)/i.test(Pa) && !Xb, - ub = C && C.documentMode === 8, - vb = !La && /AppleWebKit/.test(Pa), - Ya = /Firefox/.test(Pa), - lb = /(Mobile|Android|Windows Phone)/.test(Pa), - Ta = "http://www.w3.org/2000/svg", - ma = C && C.createElementNS && - !!C.createElementNS(Ta, "svg").createSVGRect, - bc = Ya && parseInt(Pa.split("Firefox/")[1], 10) < 4, - ua = C && !ma && !La && !!C.createElement("canvas").getContext, - Za, $a, Yb = {}, - Lb = 0, - qb, Q, pa, N, va = function() {}, - ca = [], - mb = 0, - Xa = "div", - W = "M", - R = "L", - cc = /^[0-9]+$/, - wb = ["plotTop", "marginRight", "marginBottom", "plotLeft"], - ea, rb, Bb, hb, Eb, Fb, Gb, db, jb, kb, Rb, Sb, Tb, Ub, sb, Hb, Ib, I = {}, - B; - B = M.Highcharts ? ja(16, !0) : { win: M }; - B.seriesTypes = I; - var Ua = [], - ya, qa, o, Ha, Mb, wa, G, U, K, fb, Qa; - Ab.prototype = { - dSetter: function() { - var a = this.paths[0], - b = this.paths[1], - c = [], - d = this.now, - e = a.length, - f; - if (d === 1) c = this.toD; - else if (e === b.length && d < 1) - for (; e--;) f = parseFloat(a[e]), c[e] = isNaN(f) ? a[e] : d * parseFloat(b[e] - f) + f; - else c = b; - this.elem.attr("d", c) - }, - update: function() { - var a = this.elem, - b = this.prop, - c = this.now, - d = this.options.step; - if (this[b + "Setter"]) this[b + "Setter"](); - else a.attr ? a.element && a.attr(b, c) : a.style[b] = c + this.unit; - d && d.call(a, c, this) }, - run: function(a, b, c) { - var d = this, - e = function(a) { - return e.stopped ? !1 : d.step(a) }, - f; - this.startTime = +new ea; - this.start = a; - this.end = b; - this.unit = - c; - this.now = this.start; - this.pos = 0; - e.elem = this.elem; - if (e() && Ua.push(e) === 1) e.timerId = setInterval(function() { - for (f = 0; f < Ua.length; f++) Ua[f]() || Ua.splice(f--, 1); - Ua.length || clearInterval(e.timerId) }, 13) - }, - step: function(a) { - var b = +new ea, - c, d = this.options; - c = this.elem; - var e = d.complete, - f = d.duration, - g = d.curAnim, - h; - if (c.attr && !c.element) c = !1; - else if (a || b >= f + this.startTime) { this.now = this.end; - this.pos = 1; - this.update(); - a = g[this.prop] = !0; - for (h in g) g[h] !== !0 && (a = !1); - a && e && e.call(c); - c = !1 } else this.pos = d.easing((b - this.startTime) / - f), this.now = this.start + (this.end - this.start) * this.pos, this.update(), c = !0; - return c - }, - initPath: function(a, b, c) { - function d(a) { - for (n = a.length; n--;)(a[n] === W || a[n] === R) && a.splice(n + 1, 0, a[n + 1], a[n + 2], a[n + 1], a[n + 2]) } - - function e(a, b) { - for (; a.length < l;) { a[0] = b[l - a.length]; - var c = a.slice(0, k); - [].splice.apply(a, [0, 0].concat(c)); - p && (c = a.slice(a.length - k), [].splice.apply(a, [a.length, 0].concat(c)), n--) } - a[0] = "M" } - - function f(a, b) { - for (var c = (l - a.length) / k; c > 0 && c--;) m = a.slice().splice(a.length / r - k, k * r), m[0] = b[l - k - c * k], - j && (m[k - 6] = m[k - 2], m[k - 5] = m[k - 1]), [].splice.apply(a, [a.length / r, 0].concat(m)), p && c-- - } - var b = b || "", - g, h = a.startX, - i = a.endX, - j = b.indexOf("C") > -1, - k = j ? 7 : 3, - l, m, n, b = b.split(" "), - c = c.slice(), - p = a.isArea, - r = p ? 2 : 1, - s; - j && (d(b), d(c)); - if (h && i) { - for (n = 0; n < h.length; n++) - if (h[n] === i[0]) { g = n; - break } else if (h[0] === i[i.length - h.length + n]) { g = n; - s = !0; - break } - g === void 0 && (b = []) } - b.length && B.isNumber(g) && (l = c.length + g * r * k, s ? (e(b, c), f(c, b)) : (e(c, b), f(b, c))); - return [b, c] - } - }; - var v = B.extend = function(a, b) { - var c; - a || (a = {}); - for (c in b) a[c] = b[c]; - return a - }, - ha = B.isObject = function(a, b) { - return a && typeof a === "object" && (!b || !Ra(a)) }, - z = B.isNumber = function(a) { - return typeof a === "number" && !isNaN(a) }, - q = B.pick = function() { - var a = arguments, - b, c, d = a.length; - for (b = 0; b < d; b++) - if (c = a[b], c !== x && c !== null) return c }, - S = B.wrap = function(a, b, c) { - var d = a[b]; - a[b] = function() { - var a = Array.prototype.slice.call(arguments); - a.unshift(d); - return c.apply(this, a) } }; - pa = function(a, b, c) { - if (!t(b) || isNaN(b)) return Q.lang.invalidDate || ""; - var a = q(a, "%Y-%m-%d %H:%M:%S"), - d = new ea(b - gb(b)), - e, f = d[Fb](), - g = d[Gb](), - h = d[db](), - i = d[jb](), - j = d[kb](), - k = Q.lang, - l = k.weekdays, - m = k.shortWeekdays, - d = v({ a: m ? m[g] : l[g].substr(0, 3), A: l[g], d: Sa(h), e: Sa(h, 2, " "), w: g, b: k.shortMonths[i], B: k.months[i], m: Sa(i + 1), y: j.toString().substr(2, 2), Y: j, H: Sa(f), k: f, I: Sa(f % 12 || 12), l: f % 12 || 12, M: Sa(d[Eb]()), p: f < 12 ? "AM" : "PM", P: f < 12 ? "am" : "pm", S: Sa(d.getSeconds()), L: Sa(A(b % 1E3), 3) }, B.dateFormats); - for (e in d) - for (; a.indexOf("%" + e) !== -1;) a = a.replace("%" + e, typeof d[e] === "function" ? d[e](b) : d[e]); - return c ? a.substr(0, 1).toUpperCase() + - a.substr(1) : a - }; - N = { millisecond: 1, second: 1E3, minute: 6E4, hour: 36E5, day: 864E5, week: 6048E5, month: 24192E5, year: 314496E5 }; - B.numberFormat = function(a, b, c, d) { - var a = +a || 0, - b = +b, - e = Q.lang, - f = (a.toString().split(".")[1] || "").length, - g, h, i = Math.abs(a); - b === -1 ? b = Math.min(f, 20) : z(b) || (b = 2); - g = String(H(i.toFixed(b))); - h = g.length > 3 ? g.length % 3 : 0; - c = q(c, e.decimalPoint); - d = q(d, e.thousandsSep); - a = a < 0 ? "-" : ""; - a += h ? g.substr(0, h) + d : ""; - a += g.substr(h).replace(/(\d{3})(?=\d)/g, "$1" + d); - b && (d = Math.abs(i - g + Math.pow(10, -Math.max(b, f) - 1)), - a += c + d.toFixed(b).slice(2)); - return a - }; - Math.easeInOutSine = function(a) { - return -0.5 * (Math.cos(Math.PI * a) - 1) }; - ya = function(a, b) { - var c; - if (b === "width") return Math.min(a.offsetWidth, a.scrollWidth) - ya(a, "padding-left") - ya(a, "padding-right"); - else if (b === "height") return Math.min(a.offsetHeight, a.scrollHeight) - ya(a, "padding-top") - ya(a, "padding-bottom"); - return (c = M.getComputedStyle(a, void 0)) && H(c.getPropertyValue(b)) }; - qa = function(a, b) { - return b.indexOf ? b.indexOf(a) : [].indexOf.call(b, a) }; - Ha = function(a, b) { - return [].filter.call(a, - b) - }; - wa = function(a, b) { - for (var c = [], d = 0, e = a.length; d < e; d++) c[d] = b.call(a[d], a[d], d, a); - return c }; - Mb = function(a) { - var b = C.documentElement, - a = a.getBoundingClientRect(); - return { top: a.top + (M.pageYOffset || b.scrollTop) - (b.clientTop || 0), left: a.left + (M.pageXOffset || b.scrollLeft) - (b.clientLeft || 0) } }; - Qa = function(a) { - for (var b = Ua.length; b--;) - if (Ua[b].elem === a) Ua[b].stopped = !0 }; - o = function(a, b) { - return Array.prototype.forEach.call(a, b) }; - G = function(a, b, c) { - function d(b) { b.target = b.srcElement || M; - c.call(a, b) } - var e = a.hcEvents = - a.hcEvents || {}; - if (a.addEventListener) a.addEventListener(b, c, !1); - else if (a.attachEvent) { - if (!a.hcEventsIE) a.hcEventsIE = {}; - a.hcEventsIE[c.toString()] = d; - a.attachEvent("on" + b, d) } - e[b] || (e[b] = []); - e[b].push(c) - }; - U = function(a, b, c) { - function d(b, c) { a.removeEventListener ? a.removeEventListener(b, c, !1) : a.attachEvent && (c = a.hcEventsIE[c.toString()], a.detachEvent("on" + b, c)) } - - function e() { - var c, e, f; - if (a.nodeName) - for (f in b ? (c = {}, c[b] = !0) : c = g, c) - if (g[f]) - for (e = g[f].length; e--;) d(f, g[f][e]) } - var f, g = a.hcEvents, - h; - if (g) b ? (f = - g[b] || [], c ? (h = qa(c, f), h > -1 && (f.splice(h, 1), g[b] = f), d(b, c)) : (e(), g[b] = [])) : (e(), a.hcEvents = {}) - }; - K = function(a, b, c, d) { - var e; - e = a.hcEvents; - var f, g, c = c || {}; - if (C.createEvent && (a.dispatchEvent || a.fireEvent)) e = C.createEvent("Events"), e.initEvent(b, !0, !0), e.target = a, v(e, c), a.dispatchEvent ? a.dispatchEvent(e) : a.fireEvent(b, e); - else if (e) { e = e[b] || []; - f = e.length; - if (!c.preventDefault) c.preventDefault = function() { c.defaultPrevented = !0 }; - c.target = a; - if (!c.type) c.type = b; - for (b = 0; b < f; b++)(g = e[b]) && g.call(a, c) === !1 && c.preventDefault() } - d && - !c.defaultPrevented && d(c) - }; - fb = function(a, b, c) { - var d, e = "", - f, g, h; - ha(c) || (d = arguments, c = { duration: d[2], easing: d[3], complete: d[4] }); - if (!z(c.duration)) c.duration = 400; - c.easing = typeof c.easing === "function" ? c.easing : Math[c.easing] || Math.easeInOutSine; - c.curAnim = D(b); - for (h in b) g = new Ab(a, c, h), f = null, h === "d" ? (g.paths = g.initPath(a, a.d, b.d), g.toD = b.d, d = 0, f = 1) : a.attr ? d = a.attr(h) : (d = parseFloat(ya(a, h)) || 0, h !== "opacity" && (e = "px")), f || (f = b[h]), f.match && f.match("px") && (f = f.replace(/px/g, "")), g.run(d, f, e) }; - if (M.jQuery) M.jQuery.fn.highcharts = - function() { - var a = [].slice.call(arguments); - if (this[0]) return a[0] ? (new(B[Ea(a[0]) ? a.shift() : "Chart"])(this[0], a[0], a[1]), this) : ca[$(this[0], "data-highcharts-chart")] }; - C && !C.defaultView && (ya = function(a, b) { - var c; - c = { width: "clientWidth", height: "clientHeight" }[b]; - if (a.style[b]) return H(a.style[b]); - b === "opacity" && (b = "filter"); - if (c) return a.style.zoom = 1, Math.max(a[c] - 2 * ya(a, "padding"), 0); - c = a.currentStyle[b.replace(/\-(\w)/g, function(a, b) { - return b.toUpperCase() })]; - b === "filter" && (c = c.replace(/alpha\(opacity=([0-9]+)\)/, - function(a, b) { - return b / 100 })); - return c === "" ? 1 : H(c) - }); - Array.prototype.forEach || (o = function(a, b) { - for (var c = 0, d = a.length; c < d; c++) - if (b.call(a[c], a[c], c, a) === !1) return c }); - Array.prototype.indexOf || (qa = function(a, b) { - var c, d = 0; - if (b) - for (c = b.length; d < c; d++) - if (b[d] === a) return d; - return -1 }); - Array.prototype.filter || (Ha = function(a, b) { - for (var c = [], d = 0, e = a.length; d < e; d++) b(a[d], d) && c.push(a[d]); - return c }); - B.Fx = Ab; - B.inArray = qa; - B.each = o; - B.grep = Ha; - B.offset = Mb; - B.map = wa; - B.addEvent = G; - B.removeEvent = U; - B.fireEvent = K; - B.animate = - fb; - B.animObject = ib; - B.stop = Qa; - Q = { - colors: "#7cb5ec,#434348,#90ed7d,#f7a35c,#8085e9,#f15c80,#e4d354,#2b908f,#f45b5b,#91e8e1".split(","), - symbols: ["circle", "diamond", "square", "triangle", "triangle-down"], - lang: { - loading: "Loading...", - months: "January,February,March,April,May,June,July,August,September,October,November,December".split(","), - shortMonths: "Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","), - weekdays: "Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","), - decimalPoint: ".", - numericSymbols: "k,M,G,T,P,E".split(","), - resetZoom: "Reset zoom", - resetZoomTitle: "Reset zoom level 1:1", - thousandsSep: " " - }, - global: { useUTC: !0, canvasToolsURL: "http://code.highcharts.com/modules/canvas-tools.js", VMLRadialGradientURL: "http://code.highcharts.com/stock/4.2.6/gfx/vml-radial-gradient.png" }, - chart: { - borderColor: "#4572A7", - borderRadius: 0, - defaultSeriesType: "line", - ignoreHiddenSeries: !0, - spacing: [10, 10, 15, 10], - backgroundColor: "#FFFFFF", - plotBorderColor: "#C0C0C0", - resetZoomButton: { theme: { zIndex: 20 }, position: { align: "right", x: -10, y: 10 } }, - width: null, - height: null - }, - title: { text: "Chart title", align: "center", margin: 15, style: { color: "#333333", fontSize: "18px" }, widthAdjust: -44 }, - subtitle: { text: "", align: "center", style: { color: "#555555" }, widthAdjust: -44 }, - plotOptions: { - line: { - allowPointSelect: !1, - showCheckbox: !1, - animation: { duration: 1E3 }, - events: {}, - lineWidth: 2, - marker: { lineWidth: 0, radius: 4, lineColor: "#FFFFFF", states: { hover: { enabled: !0, lineWidthPlus: 1, radiusPlus: 2 }, select: { fillColor: "#FFFFFF", lineColor: "#000000", lineWidth: 2 } } }, - point: { events: {} }, - dataLabels: { - align: "center", - formatter: function() { - return this.y === null ? "" : B.numberFormat(this.y, -1) }, - style: { color: "contrast", fontSize: "11px", fontWeight: "bold", textShadow: "0 0 6px contrast, 0 0 3px contrast" }, - verticalAlign: "bottom", - x: 0, - y: 0, - padding: 5 - }, - cropThreshold: 300, - pointRange: 0, - softThreshold: !0, - states: { hover: { lineWidthPlus: 1, marker: {}, halo: { size: 10, opacity: 0.25 } }, select: { marker: {} } }, - stickyTracking: !0, - turboThreshold: 1E3 - } - }, - labels: { style: { position: "absolute", color: "#3E576F" } }, - legend: { - enabled: !0, - align: "center", - layout: "horizontal", - labelFormatter: function() { - return this.name }, - borderColor: "#909090", - borderRadius: 0, - navigation: { activeColor: "#274b6d", inactiveColor: "#CCC" }, - shadow: !1, - itemStyle: { color: "#333333", fontSize: "12px", fontWeight: "bold" }, - itemHoverStyle: { color: "#000" }, - itemHiddenStyle: { color: "#CCC" }, - itemCheckboxStyle: { position: "absolute", width: "13px", height: "13px" }, - symbolPadding: 5, - verticalAlign: "bottom", - x: 0, - y: 0, - title: { style: { fontWeight: "bold" } } - }, - loading: { - labelStyle: { fontWeight: "bold", position: "relative", top: "45%" }, - style: { - position: "absolute", - backgroundColor: "white", - opacity: 0.5, - textAlign: "center" - } - }, - tooltip: { - enabled: !0, - animation: ma, - backgroundColor: "rgba(249, 249, 249, .85)", - borderWidth: 1, - borderRadius: 3, - dateTimeLabelFormats: { millisecond: "%A, %b %e, %H:%M:%S.%L", second: "%A, %b %e, %H:%M:%S", minute: "%A, %b %e, %H:%M", hour: "%A, %b %e, %H:%M", day: "%A, %b %e, %Y", week: "Week from %A, %b %e, %Y", month: "%B %Y", year: "%Y" }, - footerFormat: "", - headerFormat: '{point.key}
', - pointFormat: '\u25cf {series.name}: {point.y}
', - shadow: !0, - snap: lb ? 25 : 10, - style: { color: "#333333", cursor: "default", fontSize: "12px", padding: "8px", pointerEvents: "none", whiteSpace: "nowrap" } - }, - credits: { enabled: !0, text: "Highcharts.com", href: "http://www.highcharts.com", position: { align: "right", x: -10, verticalAlign: "bottom", y: -5 }, style: { cursor: "pointer", color: "#909090", fontSize: "9px" } } - }; - var X = Q.plotOptions, - ga = X.line; - Qb(); - xa.prototype = { - parsers: [{ - regex: /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]?(?:\.[0-9]+)?)\s*\)/, - parse: function(a) { - return [H(a[1]), - H(a[2]), H(a[3]), parseFloat(a[4], 10) - ] - } - }, { regex: /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/, parse: function(a) { - return [H(a[1], 16), H(a[2], 16), H(a[3], 16), 1] } }, { regex: /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/, parse: function(a) { - return [H(a[1]), H(a[2]), H(a[3]), 1] } }], - init: function(a) { - var b, c, d, e; - if ((this.input = a) && a.stops) this.stops = wa(a.stops, function(a) { - return new xa(a[1]) }); - else - for (d = this.parsers.length; d-- && !c;) e = this.parsers[d], (b = e.regex.exec(a)) && (c = e.parse(b)); - this.rgba = - c || [] - }, - get: function(a) { - var b = this.input, - c = this.rgba, - d; - this.stops ? (d = D(b), d.stops = [].concat(d.stops), o(this.stops, function(b, c) { d.stops[c] = [d.stops[c][0], b.get(a)] })) : d = c && z(c[0]) ? a === "rgb" || !a && c[3] === 1 ? "rgb(" + c[0] + "," + c[1] + "," + c[2] + ")" : a === "a" ? c[3] : "rgba(" + c.join(",") + ")" : b; - return d }, - brighten: function(a) { - var b, c = this.rgba; - if (this.stops) o(this.stops, function(b) { b.brighten(a) }); - else if (z(a) && a !== 0) - for (b = 0; b < 3; b++) c[b] += H(a * 255), c[b] < 0 && (c[b] = 0), c[b] > 255 && (c[b] = 255); - return this }, - setOpacity: function(a) { - this.rgba[3] = - a; - return this - } - }; - ba.prototype = { - opacity: 1, - textProps: "direction,fontSize,fontWeight,fontFamily,fontStyle,color,lineHeight,width,textDecoration,textOverflow,textShadow".split(","), - init: function(a, b) { this.element = b === "span" ? ia(b) : C.createElementNS(Ta, b); - this.renderer = a }, - animate: function(a, b, c) { b = q(b, this.renderer.globalAnimation, !0); - Qa(this); - if (b) { - if (c) b.complete = c; - fb(this, a, b) } else this.attr(a, null, c); - return this }, - colorGradient: function(a, b, c) { - var d = this.renderer, - e, f, g, h, i, j, k, l, m, n, p, r = [], - s; - a.linearGradient ? - f = "linearGradient" : a.radialGradient && (f = "radialGradient"); - if (f) { - g = a[f]; - i = d.gradients; - k = a.stops; - n = c.radialReference; - Ra(g) && (a[f] = g = { x1: g[0], y1: g[1], x2: g[2], y2: g[3], gradientUnits: "userSpaceOnUse" }); - f === "radialGradient" && n && !t(g.gradientUnits) && (h = g, g = D(g, d.getRadialAttr(n, h), { gradientUnits: "userSpaceOnUse" })); - for (p in g) p !== "id" && r.push(p, g[p]); - for (p in k) r.push(k[p]); - r = r.join(","); - i[r] ? n = i[r].attr("id") : (g.id = n = "highcharts-" + Lb++, i[r] = j = d.createElement(f).attr(g).add(d.defs), j.radAttr = h, j.stops = [], - o(k, function(a) { a[1].indexOf("rgba") === 0 ? (e = xa(a[1]), l = e.get("rgb"), m = e.get("a")) : (l = a[1], m = 1); - a = d.createElement("stop").attr({ offset: a[0], "stop-color": l, "stop-opacity": m }).add(j); - j.stops.push(a) })); - s = "url(" + d.url + "#" + n + ")"; - c.setAttribute(b, s); - c.gradient = r; - a.toString = function() { - return s } - } - }, - applyTextShadow: function(a) { - var b = this.element, - c, d = a.indexOf("contrast") !== -1, - e = {}, - f = this.renderer.forExport, - g = f || b.style.textShadow !== x && !La; - if (d) e.textShadow = a = a.replace(/contrast/g, this.renderer.getContrast(b.style.fill)); - if (vb || f) e.textRendering = "geometricPrecision"; - g ? this.css(e) : (this.fakeTS = !0, this.ySetter = this.xSetter, c = [].slice.call(b.getElementsByTagName("tspan")), o(a.split(/\s?,\s?/g), function(a) { - var d = b.firstChild, - e, f, a = a.split(" "); - e = a[a.length - 1]; - (f = a[a.length - 2]) && o(c, function(a, c) { - var g; - c === 0 && (a.setAttribute("x", b.getAttribute("x")), c = b.getAttribute("y"), a.setAttribute("y", c || 0), c === null && b.setAttribute("y", 0)); - g = a.cloneNode(1); - $(g, { - "class": "highcharts-text-shadow", - fill: e, - stroke: e, - "stroke-opacity": 1 / y(H(f), - 3), - "stroke-width": f, - "stroke-linejoin": "round" - }); - b.insertBefore(g, d) - }) - })) - }, - attr: function(a, b, c) { - var d, e = this.element, - f, g = this, - h; - typeof a === "string" && b !== x && (d = a, a = {}, a[d] = b); - if (typeof a === "string") g = (this[a + "Getter"] || this._defaultGetter).call(this, a, e); - else { - for (d in a) { - b = a[d]; - h = !1; - this.symbolName && /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(d) && (f || (this.symbolAttr(a), f = !0), h = !0); - if (this.rotation && (d === "x" || d === "y")) this.doTransform = !0; - h || (h = this[d + "Setter"] || this._defaultSetter, - h.call(this, b, d, e), this.shadows && /^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(d) && this.updateShadows(d, b, h)) - } - if (this.doTransform) this.updateTransform(), this.doTransform = !1 - } - c && c(); - return g - }, - updateShadows: function(a, b, c) { - for (var d = this.shadows, e = d.length; e--;) c.call(d[e], a === "height" ? Math.max(b - (d[e].cutHeight || 0), 0) : a === "d" ? this.d : b, a, d[e]) }, - addClass: function(a) { - var b = this.element, - c = $(b, "class") || ""; - c.indexOf(a) === -1 && $(b, "class", c + " " + a); - return this }, - symbolAttr: function(a) { - var b = this; - o("x,y,r,start,end,width,height,innerR,anchorX,anchorY".split(","), function(c) { b[c] = q(a[c], b[c]) }); - b.attr({ d: b.renderer.symbols[b.symbolName](b.x, b.y, b.width, b.height, b) }) - }, - clip: function(a) { - return this.attr("clip-path", a ? "url(" + this.renderer.url + "#" + a.id + ")" : "none") }, - crisp: function(a) { - var b, c = {}, - d, e = this.strokeWidth || 0; - d = A(e) % 2 / 2; - a.x = Y(a.x || this.x || 0) + d; - a.y = Y(a.y || this.y || 0) + d; - a.width = Y((a.width || this.width || 0) - 2 * d); - a.height = Y((a.height || this.height || 0) - 2 * d); - a.strokeWidth = e; - for (b in a) this[b] !== a[b] && - (this[b] = c[b] = a[b]); - return c - }, - css: function(a) { - var b = this.styles, - c = {}, - d = this.element, - e, f, g = ""; - e = !b; - if (a && a.color) a.fill = a.color; - if (b) - for (f in a) a[f] !== b[f] && (c[f] = a[f], e = !0); - if (e) { - e = this.textWidth = a && a.width && d.nodeName.toLowerCase() === "text" && H(a.width) || this.textWidth; - b && (a = v(b, c)); - this.styles = a; - e && (ua || !ma && this.renderer.forExport) && delete a.width; - if (La && !ma) O(this.element, a); - else { b = function(a, b) { - return "-" + b.toLowerCase() }; - for (f in a) g += f.replace(/([A-Z])/g, b) + ":" + a[f] + ";"; - $(d, "style", g) } - e && this.added && - this.renderer.buildText(this) - } - return this - }, - on: function(a, b) { - var c = this, - d = c.element; - $a && a === "click" ? (d.ontouchstart = function(a) { c.touchEventFired = ea.now(); - a.preventDefault(); - b.call(d, a) }, d.onclick = function(a) { - (Pa.indexOf("Android") === -1 || ea.now() - (c.touchEventFired || 0) > 1100) && b.call(d, a) }) : d["on" + a] = b; - return this }, - setRadialReference: function(a) { - var b = this.renderer.gradients[this.element.gradient]; - this.element.radialReference = a; - b && b.radAttr && b.animate(this.renderer.getRadialAttr(a, b.radAttr)); - return this }, - translate: function(a, b) { - return this.attr({ translateX: a, translateY: b }) }, - invert: function() { this.inverted = !0; - this.updateTransform(); - return this }, - updateTransform: function() { - var a = this.translateX || 0, - b = this.translateY || 0, - c = this.scaleX, - d = this.scaleY, - e = this.inverted, - f = this.rotation, - g = this.element; - e && (a += this.attr("width"), b += this.attr("height")); - a = ["translate(" + a + "," + b + ")"]; - e ? a.push("rotate(90) scale(-1,1)") : f && a.push("rotate(" + f + " " + (g.getAttribute("x") || 0) + " " + (g.getAttribute("y") || 0) + ")"); - (t(c) || t(d)) && - a.push("scale(" + q(c, 1) + " " + q(d, 1) + ")"); - a.length && g.setAttribute("transform", a.join(" ")) - }, - toFront: function() { - var a = this.element; - a.parentNode.appendChild(a); - return this }, - align: function(a, b, c) { - var d, e, f, g, h = {}; - e = this.renderer; - f = e.alignedObjects; - if (a) { - if (this.alignOptions = a, this.alignByTranslate = b, !c || Ea(c)) this.alignTo = d = c || "renderer", Ba(f, this), f.push(this), c = null } else a = this.alignOptions, b = this.alignByTranslate, d = this.alignTo; - c = q(c, e[d], e); - d = a.align; - e = a.verticalAlign; - f = (c.x || 0) + (a.x || 0); - g = (c.y || 0) + - (a.y || 0); - if (d === "right" || d === "center") f += (c.width - (a.width || 0)) / { right: 1, center: 2 }[d]; - h[b ? "translateX" : "x"] = A(f); - if (e === "bottom" || e === "middle") g += (c.height - (a.height || 0)) / ({ bottom: 1, middle: 2 }[e] || 1); - h[b ? "translateY" : "y"] = A(g); - this[this.placed ? "animate" : "attr"](h); - this.placed = !0; - this.alignAttr = h; - return this - }, - getBBox: function(a, b) { - var c, d = this.renderer, - e, f, g, h = this.element, - i = this.styles; - e = this.textStr; - var j, k = h.style, - l, m = d.cache, - n = d.cacheKeys, - p; - f = q(b, this.rotation); - g = f * ta; - e !== x && (p = ["", f || 0, i && i.fontSize, - h.style.width - ].join(","), p = e === "" || cc.test(e) ? "num:" + e.toString().length + p : e + p); - p && !a && (c = m[p]); - if (!c) { - if (h.namespaceURI === Ta || d.forExport) { - try { l = this.fakeTS && function(a) { o(h.querySelectorAll(".highcharts-text-shadow"), function(b) { b.style.display = a }) }, Ya && k.textShadow ? (j = k.textShadow, k.textShadow = "") : l && l("none"), c = h.getBBox ? v({}, h.getBBox()) : { width: h.offsetWidth, height: h.offsetHeight }, j ? k.textShadow = j : l && l("") } catch (r) {} - if (!c || c.width < 0) c = { width: 0, height: 0 } } else c = this.htmlGetBBox(); - if (d.isSVG) { - d = - c.width; - e = c.height; - if (La && i && i.fontSize === "11px" && e.toPrecision(3) === "16.9") c.height = e = 14; - if (f) c.width = T(e * na(g)) + T(d * fa(g)), c.height = T(e * fa(g)) + T(d * na(g)) - } - if (p) { - for (; n.length > 250;) delete m[n.shift()]; - m[p] || n.push(p); - m[p] = c } - } - return c - }, - show: function(a) { - return this.attr({ visibility: a ? "inherit" : "visible" }) }, - hide: function() { - return this.attr({ visibility: "hidden" }) }, - fadeOut: function(a) { - var b = this; - b.animate({ opacity: 0 }, { duration: a || 150, complete: function() { b.attr({ y: -9999 }) } }) }, - add: function(a) { - var b = this.renderer, - c = this.element, - d; - if (a) this.parentGroup = a; - this.parentInverted = a && a.inverted; - this.textStr !== void 0 && b.buildText(this); - this.added = !0; - if (!a || a.handleZ || this.zIndex) d = this.zIndexSetter(); - d || (a ? a.element : b.box).appendChild(c); - if (this.onAdd) this.onAdd(); - return this - }, - safeRemoveChild: function(a) { - var b = a.parentNode; - b && b.removeChild(a) }, - destroy: function() { - var a = this, - b = a.element || {}, - c = a.shadows, - d = a.renderer.isSVG && b.nodeName === "SPAN" && a.parentGroup, - e, f; - b.onclick = b.onmouseout = b.onmouseover = b.onmousemove = b.point = - null; - Qa(a); - if (a.clipPath) a.clipPath = a.clipPath.destroy(); - if (a.stops) { - for (f = 0; f < a.stops.length; f++) a.stops[f] = a.stops[f].destroy(); - a.stops = null } - a.safeRemoveChild(b); - for (c && o(c, function(b) { a.safeRemoveChild(b) }); d && d.div && d.div.childNodes.length === 0;) b = d.parentGroup, a.safeRemoveChild(d.div), delete d.div, d = b; - a.alignTo && Ba(a.renderer.alignedObjects, a); - for (e in a) delete a[e]; - return null - }, - shadow: function(a, b, c) { - var d = [], - e, f, g = this.element, - h, i, j, k; - if (a) { - i = q(a.width, 3); - j = (a.opacity || 0.15) / i; - k = this.parentInverted ? - "(-1,-1)" : "(" + q(a.offsetX, 1) + ", " + q(a.offsetY, 1) + ")"; - for (e = 1; e <= i; e++) { f = g.cloneNode(0); - h = i * 2 + 1 - 2 * e; - $(f, { isShadow: "true", stroke: a.color || "black", "stroke-opacity": j * e, "stroke-width": h, transform: "translate" + k, fill: "none" }); - if (c) $(f, "height", y($(f, "height") - h, 0)), f.cutHeight = h; - b ? b.element.appendChild(f) : g.parentNode.insertBefore(f, g); - d.push(f) } - this.shadows = d - } - return this - }, - xGetter: function(a) { this.element.nodeName === "circle" && (a = { x: "cx", y: "cy" }[a] || a); - return this._defaultGetter(a) }, - _defaultGetter: function(a) { - a = - q(this[a], this.element ? this.element.getAttribute(a) : null, 0); - /^[\-0-9\.]+$/.test(a) && (a = parseFloat(a)); - return a - }, - dSetter: function(a, b, c) { a && a.join && (a = a.join(" ")); /(NaN| {2}|^$)/.test(a) && (a = "M 0 0"); - c.setAttribute(b, a); - this[b] = a }, - dashstyleSetter: function(a) { - var b, c = this["stroke-width"]; - c === "inherit" && (c = 1); - if (a = a && a.toLowerCase()) { - a = a.replace("shortdashdotdot", "3,1,1,1,1,1,").replace("shortdashdot", "3,1,1,1").replace("shortdot", "1,1,").replace("shortdash", "3,1,").replace("longdash", "8,3,").replace(/dot/g, - "1,3,").replace("dash", "4,3,").replace(/,$/, "").split(","); - for (b = a.length; b--;) a[b] = H(a[b]) * c; - a = a.join(",").replace(/NaN/g, "none"); - this.element.setAttribute("stroke-dasharray", a) - } - }, - alignSetter: function(a) { this.element.setAttribute("text-anchor", { left: "start", center: "middle", right: "end" }[a]) }, - opacitySetter: function(a, b, c) { this[b] = a; - c.setAttribute(b, a) }, - titleSetter: function(a) { - var b = this.element.getElementsByTagName("title")[0]; - b || (b = C.createElementNS(Ta, "title"), this.element.appendChild(b)); - b.firstChild && - b.removeChild(b.firstChild); - b.appendChild(C.createTextNode(String(q(a), "").replace(/<[^>]*>/g, ""))) - }, - textSetter: function(a) { - if (a !== this.textStr) delete this.bBox, this.textStr = a, this.added && this.renderer.buildText(this) }, - fillSetter: function(a, b, c) { typeof a === "string" ? c.setAttribute(b, a) : a && this.colorGradient(a, b, c) }, - visibilitySetter: function(a, b, c) { a === "inherit" ? c.removeAttribute(b) : c.setAttribute(b, a) }, - zIndexSetter: function(a, b) { - var c = this.renderer, - d = this.parentGroup, - c = (d || c).element || c.box, - e, f, g = - this.element, - h; - e = this.added; - var i; - if (t(a)) g.zIndex = a, a = +a, this[b] === a && (e = !1), this[b] = a; - if (e) { - if ((a = this.zIndex) && d) d.handleZ = !0; - d = c.childNodes; - for (i = 0; i < d.length && !h; i++) - if (e = d[i], f = e.zIndex, e !== g && (H(f) > a || !t(a) && t(f))) c.insertBefore(g, e), h = !0; - h || c.appendChild(g) } - return h - }, - _defaultSetter: function(a, b, c) { c.setAttribute(b, a) } - }; - ba.prototype.yGetter = ba.prototype.xGetter; - ba.prototype.translateXSetter = ba.prototype.translateYSetter = ba.prototype.rotationSetter = ba.prototype.verticalAlignSetter = ba.prototype.scaleXSetter = - ba.prototype.scaleYSetter = function(a, b) { this[b] = a; - this.doTransform = !0 }; - ba.prototype["stroke-widthSetter"] = ba.prototype.strokeSetter = function(a, b, c) { this[b] = a; - if (this.stroke && this["stroke-width"]) this.strokeWidth = this["stroke-width"], ba.prototype.fillSetter.call(this, this.stroke, "stroke", c), c.setAttribute("stroke-width", this["stroke-width"]), this.hasStroke = !0; - else if (b === "stroke-width" && a === 0 && this.hasStroke) c.removeAttribute("stroke"), this.hasStroke = !1 }; - var za = function() { this.init.apply(this, arguments) }; - za.prototype = { - Element: ba, - init: function(a, b, c, d, e, f) { - var g, d = this.createElement("svg").attr({ version: "1.1" }).css(this.getStyle(d)); - g = d.element; - a.appendChild(g); - a.innerHTML.indexOf("xmlns") === -1 && $(g, "xmlns", Ta); - this.isSVG = !0; - this.box = g; - this.boxWrapper = d; - this.alignedObjects = []; - this.url = (Ya || vb) && C.getElementsByTagName("base").length ? M.location.href.replace(/#.*?$/, "").replace(/([\('\)])/g, "\\$1").replace(/ /g, "%20") : ""; - this.createElement("desc").add().element.appendChild(C.createTextNode("Created with Highstock 4.2.6")); - this.defs = this.createElement("defs").add(); - this.allowHTML = f; - this.forExport = e; - this.gradients = {}; - this.cache = {}; - this.cacheKeys = []; - this.imgCount = 0; - this.setSize(b, c, !1); - var h; - if (Ya && a.getBoundingClientRect) this.subPixelFix = b = function() { O(a, { left: 0, top: 0 }); - h = a.getBoundingClientRect(); - O(a, { left: Ga(h.left) - h.left + "px", top: Ga(h.top) - h.top + "px" }) }, b(), G(M, "resize", b) - }, - getStyle: function(a) { - return this.style = v({ fontFamily: '"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif', fontSize: "12px" }, - a) - }, - isHidden: function() { - return !this.boxWrapper.getBBox().width }, - destroy: function() { - var a = this.defs; - this.box = null; - this.boxWrapper = this.boxWrapper.destroy(); - Oa(this.gradients || {}); - this.gradients = null; - if (a) this.defs = a.destroy(); - this.subPixelFix && U(M, "resize", this.subPixelFix); - return this.alignedObjects = null }, - createElement: function(a) { - var b = new this.Element; - b.init(this, a); - return b }, - draw: function() {}, - getRadialAttr: function(a, b) { - return { cx: a[0] - a[2] / 2 + b.cx * a[2], cy: a[1] - a[2] / 2 + b.cy * a[2], r: b.r * a[2] } }, - buildText: function(a) { - for (var b = - a.element, c = this, d = c.forExport, e = q(a.textStr, "").toString(), f = e.indexOf("<") !== -1, g = b.childNodes, h, i, j, k = $(b, "x"), l = a.styles, m = a.textWidth, n = l && l.lineHeight, p = l && l.textShadow, r = l && l.textOverflow === "ellipsis", s = g.length, Z = m && !a.added && this.box, u = function(a) { - return n ? H(n) : c.fontMetrics(/(px|em)$/.test(a && a.style.fontSize) ? a.style.fontSize : l && l.fontSize || c.style.fontSize || 12, a).h }, w = function(a) { - return a.replace(/</g, "<").replace(/>/g, ">") }; s--;) b.removeChild(g[s]); - !f && !p && !r && !m && e.indexOf(" ") === - -1 ? b.appendChild(C.createTextNode(w(e))) : (h = /<.*style="([^"]+)".*>/, i = /<.*href="(http[^"]+)".*>/, Z && Z.appendChild(b), e = f ? e.replace(/<(b|strong)>/g, '').replace(/<(i|em)>/g, '').replace(//g, "").split(//g) : [e], e = Ha(e, function(a) { - return a !== "" }), o(e, function(e, f) { - var g, n = 0, - e = e.replace(/^\s+|\s+$/g, "").replace(//g, "|||"); - g = e.split("|||"); - o(g, - function(e) { - if (e !== "" || g.length === 1) { - var p = {}, - s = C.createElementNS(Ta, "tspan"), - q; - h.test(e) && (q = e.match(h)[1].replace(/(;| |^)color([ :])/, "$1fill$2"), $(s, "style", q)); - i.test(e) && !d && ($(s, "onclick", 'location.href="' + e.match(i)[1] + '"'), O(s, { cursor: "pointer" })); - e = w(e.replace(/<(.|\n)*?>/g, "") || " "); - if (e !== " ") { - s.appendChild(C.createTextNode(e)); - if (n) p.dx = 0; - else if (f && k !== null) p.x = k; - $(s, p); - b.appendChild(s); - !n && f && (!ma && d && O(s, { display: "block" }), $(s, "dy", u(s))); - if (m) { - for (var p = e.replace(/([^\^])-/g, "$1- ").split(" "), - Z = g.length > 1 || f || p.length > 1 && l.whiteSpace !== "nowrap", o, F, t = [], y = u(s), x = 1, A = a.rotation, v = e, B = v.length; - (Z || r) && (p.length || t.length);) a.rotation = 0, o = a.getBBox(!0), F = o.width, !ma && c.forExport && (F = c.measureSpanWidth(s.firstChild.data, a.styles)), o = F > m, j === void 0 && (j = o), r && j ? (B /= 2, v === "" || !o && B < 0.5 ? p = [] : (v = e.substring(0, v.length + (o ? -1 : 1) * Ga(B)), p = [v + (m > 3 ? "\u2026" : "")], s.removeChild(s.firstChild))) : !o || p.length === 1 ? (p = t, t = [], p.length && (x++, s = C.createElementNS(Ta, "tspan"), $(s, { dy: y, x: k }), q && $(s, "style", q), - b.appendChild(s)), F > m && (m = F)) : (s.removeChild(s.firstChild), t.unshift(p.pop())), p.length && s.appendChild(C.createTextNode(p.join(" ").replace(/- /g, "-"))); - a.rotation = A - } - n++ - } - } - }) - }), j && a.attr("title", a.textStr), Z && Z.removeChild(b), p && a.applyTextShadow && a.applyTextShadow(p)) - }, - getContrast: function(a) { a = xa(a).rgba; - return a[0] + a[1] + a[2] > 384 ? "#000000" : "#FFFFFF" }, - button: function(a, b, c, d, e, f, g, h, i) { - var j = this.label(a, b, c, i, null, null, null, null, "button"), - k = 0, - l, m, n, p, r, s, a = { x1: 0, y1: 0, x2: 0, y2: 1 }, - e = D({ - "stroke-width": 1, - stroke: "#CCCCCC", - fill: { linearGradient: a, stops: [ - [0, "#FEFEFE"], - [1, "#F6F6F6"] - ] }, - r: 2, - padding: 5, - style: { color: "black" } - }, e); - n = e.style; - delete e.style; - f = D(e, { stroke: "#68A", fill: { linearGradient: a, stops: [ - [0, "#FFF"], - [1, "#ACF"] - ] } }, f); - p = f.style; - delete f.style; - g = D(e, { stroke: "#68A", fill: { linearGradient: a, stops: [ - [0, "#9BD"], - [1, "#CDF"] - ] } }, g); - r = g.style; - delete g.style; - h = D(e, { style: { color: "#CCC" } }, h); - s = h.style; - delete h.style; - G(j.element, La ? "mouseover" : "mouseenter", function() { k !== 3 && j.attr(f).css(p) }); - G(j.element, La ? "mouseout" : - "mouseleave", - function() { k !== 3 && (l = [e, f, g][k], m = [n, p, r][k], j.attr(l).css(m)) }); - j.setState = function(a) { - (j.state = k = a) ? a === 2 ? j.attr(g).css(r) : a === 3 && j.attr(h).css(s): j.attr(e).css(n) }; - return j.on("click", function(a) { k !== 3 && d.call(j, a) }).attr(e).css(v({ cursor: "default" }, n)) - }, - crispLine: function(a, b) { a[1] === a[4] && (a[1] = a[4] = A(a[1]) - b % 2 / 2); - a[2] === a[5] && (a[2] = a[5] = A(a[2]) + b % 2 / 2); - return a }, - path: function(a) { - var b = { fill: "none" }; - Ra(a) ? b.d = a : ha(a) && v(b, a); - return this.createElement("path").attr(b) }, - circle: function(a, - b, c) { a = ha(a) ? a : { x: a, y: b, r: c }; - b = this.createElement("circle"); - b.xSetter = b.ySetter = function(a, b, c) { c.setAttribute("c" + b, a) }; - return b.attr(a) }, - arc: function(a, b, c, d, e, f) { - if (ha(a)) b = a.y, c = a.r, d = a.innerR, e = a.start, f = a.end, a = a.x; - a = this.symbol("arc", a || 0, b || 0, c || 0, c || 0, { innerR: d || 0, start: e || 0, end: f || 0 }); - a.r = c; - return a }, - rect: function(a, b, c, d, e, f) { - var e = ha(a) ? a.r : e, - g = this.createElement("rect"), - a = ha(a) ? a : a === x ? {} : { x: a, y: b, width: y(c, 0), height: y(d, 0) }; - if (f !== x) g.strokeWidth = f, a = g.crisp(a); - if (e) a.r = e; - g.rSetter = - function(a, b, c) { $(c, { rx: a, ry: a }) }; - return g.attr(a) - }, - setSize: function(a, b, c) { - var d = this.alignedObjects, - e = d.length; - this.width = a; - this.height = b; - for (this.boxWrapper[q(c, !0) ? "animate" : "attr"]({ width: a, height: b }); e--;) d[e].align() }, - g: function(a) { - var b = this.createElement("g"); - return t(a) ? b.attr({ "class": "highcharts-" + a }) : b }, - image: function(a, b, c, d, e) { - var f = { preserveAspectRatio: "none" }; - arguments.length > 1 && v(f, { x: b, y: c, width: d, height: e }); - f = this.createElement("image").attr(f); - f.element.setAttributeNS ? f.element.setAttributeNS("http://www.w3.org/1999/xlink", - "href", a) : f.element.setAttribute("hc-svg-href", a); - return f - }, - symbol: function(a, b, c, d, e, f) { - var g = this, - h, i = this.symbols[a], - i = i && i(A(b), A(c), d, e, f), - j = /^url\((.*?)\)$/, - k, l; - if (i) h = this.path(i), v(h, { symbolName: a, x: b, y: c, width: d, height: e }), f && v(h, f); - else if (j.test(a)) l = function(a, b) { a.element && (a.attr({ width: b[0], height: b[1] }), a.alignByTranslate || a.translate(A((d - b[0]) / 2), A((e - b[1]) / 2))) }, k = a.match(j)[1], a = Yb[k] || f && f.width && f.height && [f.width, f.height], h = this.image(k).attr({ x: b, y: c }), h.isImg = !0, a ? l(h, a) : - (h.attr({ width: 0, height: 0 }), ia("img", { onload: function() { this.width === 0 && (O(this, { position: "absolute", top: "-999em" }), C.body.appendChild(this)); - l(h, Yb[k] = [this.width, this.height]); - this.parentNode && this.parentNode.removeChild(this); - g.imgCount--; - if (!g.imgCount && ca[g.chartIndex].onload) ca[g.chartIndex].onload() }, src: k }), this.imgCount++); - return h - }, - symbols: { - circle: function(a, b, c, d) { - var e = 0.166 * c; - return [W, a + c / 2, b, "C", a + c + e, b, a + c + e, b + d, a + c / 2, b + d, "C", a - e, b + d, a - e, b, a + c / 2, b, "Z"] }, - square: function(a, b, c, d) { - return [W, - a, b, R, a + c, b, a + c, b + d, a, b + d, "Z" - ] - }, - triangle: function(a, b, c, d) { - return [W, a + c / 2, b, R, a + c, b + d, a, b + d, "Z"] }, - "triangle-down": function(a, b, c, d) { - return [W, a, b, R, a + c, b, a + c / 2, b + d, "Z"] }, - diamond: function(a, b, c, d) { - return [W, a + c / 2, b, R, a + c, b + d / 2, a + c / 2, b + d, a, b + d / 2, "Z"] }, - arc: function(a, b, c, d, e) { - var f = e.start, - c = e.r || c || d, - g = e.end - 0.001, - d = e.innerR, - h = e.open, - i = fa(f), - j = na(f), - k = fa(g), - g = na(g), - e = e.end - f < Ca ? 0 : 1; - return [W, a + c * i, b + c * j, "A", c, c, 0, e, 1, a + c * k, b + c * g, h ? W : R, a + d * k, b + d * g, "A", d, d, 0, e, 0, a + d * i, b + d * j, h ? "" : "Z"] }, - callout: function(a, - b, c, d, e) { - var f = E(e && e.r || 0, c, d), - g = f + 6, - h = e && e.anchorX, - e = e && e.anchorY, - i; - i = ["M", a + f, b, "L", a + c - f, b, "C", a + c, b, a + c, b, a + c, b + f, "L", a + c, b + d - f, "C", a + c, b + d, a + c, b + d, a + c - f, b + d, "L", a + f, b + d, "C", a, b + d, a, b + d, a, b + d - f, "L", a, b + f, "C", a, b, a, b, a + f, b]; - h && h > c && e > b + g && e < b + d - g ? i.splice(13, 3, "L", a + c, e - 6, a + c + 6, e, a + c, e + 6, a + c, b + d - f) : h && h < 0 && e > b + g && e < b + d - g ? i.splice(33, 3, "L", a, e + 6, a - 6, e, a, e - 6, a, b + f) : e && e > d && h > a + g && h < a + c - g ? i.splice(23, 3, "L", h + 6, b + d, h, b + d + 6, h - 6, b + d, a + f, b + d) : e && e < 0 && h > a + g && h < a + c - g && i.splice(3, 3, "L", h - 6, b, h, b - 6, h + 6, - b, c - f, b); - return i - } - }, - clipRect: function(a, b, c, d) { - var e = "highcharts-" + Lb++, - f = this.createElement("clipPath").attr({ id: e }).add(this.defs), - a = this.rect(a, b, c, d, 0).add(f); - a.id = e; - a.clipPath = f; - a.count = 0; - return a }, - text: function(a, b, c, d) { - var e = ua || !ma && this.forExport, - f = {}; - if (d && (this.allowHTML || !this.forExport)) return this.html(a, b, c); - f.x = Math.round(b || 0); - if (c) f.y = Math.round(c); - if (a || a === 0) f.text = a; - a = this.createElement("text").attr(f); - e && a.css({ position: "absolute" }); - if (!d) a.xSetter = function(a, b, c) { - var d = c.getElementsByTagName("tspan"), - e, f = c.getAttribute(b), - m; - for (m = 0; m < d.length; m++) e = d[m], e.getAttribute(b) === f && e.setAttribute(b, a); - c.setAttribute(b, a) - }; - return a - }, - fontMetrics: function(a, b) { - var c, d, a = a || this.style.fontSize;!a && b && M.getComputedStyle && (b = b.element || b, a = (c = M.getComputedStyle(b, "")) && c.fontSize); - a = /px/.test(a) ? H(a) : /em/.test(a) ? parseFloat(a) * 12 : 12; - c = a < 24 ? a + 3 : A(a * 1.2); - d = A(c * 0.8); - return { h: c, b: d, f: a } }, - rotCorr: function(a, b, c) { - var d = a; - b && c && (d = y(d * fa(b * ta), 4)); - return { x: -a / 3 * na(b * ta), y: d } }, - label: function(a, b, c, d, e, f, g, h, i) { - var j = - this, - k = j.g(i), - l = j.text("", 0, 0, g).attr({ zIndex: 1 }), - m, n, p = 0, - r = 3, - s = 0, - q, u, w, F, L = 0, - ka = {}, - y, B, C, E, z; - C = function() { - var a, b; - a = l.element.style; - n = (q === void 0 || u === void 0 || k.styles.textAlign) && t(l.textStr) && l.getBBox(); - k.width = (q || n.width || 0) + 2 * r + s; - k.height = (u || n.height || 0) + 2 * r; - y = r + j.fontMetrics(a && a.fontSize, l).b; - if (B) { - if (!m) a = L, b = (h ? -y : 0) + L, k.box = m = j.symbols[d] ? j.symbol(d, a, b, k.width, k.height, ka) : j.rect(a, b, k.width, k.height, 0, ka["stroke-width"]), m.isImg || m.attr("fill", "none"), m.add(k); - m.isImg || m.attr(v({ - width: A(k.width), - height: A(k.height) - }, ka)); - ka = null - } - }; - E = function() { - var a = k.styles, - a = a && a.textAlign, - b = s + r, - c; - c = h ? 0 : y; - if (t(q) && n && (a === "center" || a === "right")) b += { center: 0.5, right: 1 }[a] * (q - n.width); - if (b !== l.x || c !== l.y) l.attr("x", b), c !== x && l.attr("y", c); - l.x = b; - l.y = c }; - z = function(a, b) { m ? m.attr(a, b) : ka[a] = b }; - k.onAdd = function() { l.add(k); - k.attr({ text: a || a === 0 ? a : "", x: b, y: c }); - m && t(e) && k.attr({ anchorX: e, anchorY: f }) }; - k.widthSetter = function(a) { q = a }; - k.heightSetter = function(a) { u = a }; - k.paddingSetter = function(a) { - if (t(a) && a !== r) r = k.padding = - a, E() - }; - k.paddingLeftSetter = function(a) { t(a) && a !== s && (s = a, E()) }; - k.alignSetter = function(a) { a = { left: 0, center: 0.5, right: 1 }[a]; - a !== p && (p = a, n && k.attr({ x: w })) }; - k.textSetter = function(a) { a !== x && l.textSetter(a); - C(); - E() }; - k["stroke-widthSetter"] = function(a, b) { a && (B = !0); - L = a % 2 / 2; - z(b, a) }; - k.strokeSetter = k.fillSetter = k.rSetter = function(a, b) { b === "fill" && a && (B = !0); - z(b, a) }; - k.anchorXSetter = function(a, b) { e = a; - z(b, A(a) - L - w) }; - k.anchorYSetter = function(a, b) { f = a; - z(b, a - F) }; - k.xSetter = function(a) { - k.x = a; - p && (a -= p * ((q || n.width) + 2 * - r)); - w = A(a); - k.attr("translateX", w) - }; - k.ySetter = function(a) { F = k.y = A(a); - k.attr("translateY", F) }; - var G = k.css; - return v(k, { - css: function(a) { - if (a) { - var b = {}, - a = D(a); - o(k.textProps, function(c) { a[c] !== x && (b[c] = a[c], delete a[c]) }); - l.css(b) } - return G.call(k, a) }, - getBBox: function() { - return { width: n.width + 2 * r, height: n.height + 2 * r, x: n.x - r, y: n.y - r } }, - shadow: function(a) { m && m.shadow(a); - return k }, - destroy: function() { - U(k.element, "mouseenter"); - U(k.element, "mouseleave"); - l && (l = l.destroy()); - m && (m = m.destroy()); - ba.prototype.destroy.call(k); - k = j = C = E = z = null - } - }) - } - }; - Za = za; - v(ba.prototype, { - htmlCss: function(a) { - var b = this.element; - if (b = a && b.tagName === "SPAN" && a.width) delete a.width, this.textWidth = b, this.updateTransform(); - if (a && a.textOverflow === "ellipsis") a.whiteSpace = "nowrap", a.overflow = "hidden"; - this.styles = v(this.styles, a); - O(this.element, a); - return this }, - htmlGetBBox: function() { - var a = this.element; - if (a.nodeName === "text") a.style.position = "absolute"; - return { x: a.offsetLeft, y: a.offsetTop, width: a.offsetWidth, height: a.offsetHeight } }, - htmlUpdateTransform: function() { - if (this.added) { - var a = - this.renderer, - b = this.element, - c = this.translateX || 0, - d = this.translateY || 0, - e = this.x || 0, - f = this.y || 0, - g = this.textAlign || "left", - h = { left: 0, center: 0.5, right: 1 }[g], - i = this.shadows, - j = this.styles; - O(b, { marginLeft: c, marginTop: d }); - i && o(i, function(a) { O(a, { marginLeft: c + 1, marginTop: d + 1 }) }); - this.inverted && o(b.childNodes, function(c) { a.invertChild(c, b) }); - if (b.tagName === "SPAN") { - var i = this.rotation, - k = H(this.textWidth), - l = j && j.whiteSpace, - m = [i, g, b.innerHTML, this.textWidth, this.textAlign].join(","); - if (m !== this.cTT) { - j = a.fontMetrics(b.style.fontSize).b; - t(i) && this.setSpanRotation(i, h, j); - O(b, { width: "", whiteSpace: l || "nowrap" }); - if (b.offsetWidth > k && /[ \-]/.test(b.textContent || b.innerText)) O(b, { width: k + "px", display: "block", whiteSpace: l || "normal" }); - this.getSpanCorrection(b.offsetWidth, j, h, i, g) - } - O(b, { left: e + (this.xCorr || 0) + "px", top: f + (this.yCorr || 0) + "px" }); - if (vb) j = b.offsetHeight; - this.cTT = m - } - } else this.alignOnAdd = !0 - }, - setSpanRotation: function(a, b, c) { - var d = {}, - e = La ? "-ms-transform" : vb ? "-webkit-transform" : Ya ? "MozTransform" : Xb ? "-o-transform" : ""; - d[e] = d.transform = - "rotate(" + a + "deg)"; - d[e + (Ya ? "Origin" : "-origin")] = d.transformOrigin = b * 100 + "% " + c + "px"; - O(this.element, d) - }, - getSpanCorrection: function(a, b, c) { this.xCorr = -a * c; - this.yCorr = -b } - }); - v(za.prototype, { - html: function(a, b, c) { - var d = this.createElement("span"), - e = d.element, - f = d.renderer, - g = f.isSVG, - h = function(a, b) { o(["opacity", "visibility"], function(c) { S(a, c + "Setter", function(a, c, d, e) { a.call(this, c, d, e); - b[d] = c }) }) }; - d.textSetter = function(a) { a !== e.innerHTML && delete this.bBox; - e.innerHTML = this.textStr = a; - d.htmlUpdateTransform() }; - g && h(d, d.element.style); - d.xSetter = d.ySetter = d.alignSetter = d.rotationSetter = function(a, b) { b === "align" && (b = "textAlign"); - d[b] = a; - d.htmlUpdateTransform() }; - d.attr({ text: a, x: A(b), y: A(c) }).css({ position: "absolute", fontFamily: this.style.fontFamily, fontSize: this.style.fontSize }); - e.style.whiteSpace = "nowrap"; - d.css = d.htmlCss; - if (g) d.add = function(a) { - var b, c = f.box.parentNode, - g = []; - if (this.parentGroup = a) { - if (b = a.div, !b) { - for (; a;) g.push(a), a = a.parentGroup; - o(g.reverse(), function(a) { - var d, e = $(a.element, "class"); - e && (e = { className: e }); - b = a.div = a.div || ia(Xa, e, { position: "absolute", left: (a.translateX || 0) + "px", top: (a.translateY || 0) + "px", opacity: a.opacity }, b || c); - d = b.style; - v(a, { translateXSetter: function(b, c) { d.left = b + "px"; - a[c] = b; - a.doTransform = !0 }, translateYSetter: function(b, c) { d.top = b + "px"; - a[c] = b; - a.doTransform = !0 } }); - h(a, d) - }) - } - } else b = c; - b.appendChild(e); - d.added = !0; - d.alignOnAdd && d.htmlUpdateTransform(); - return d - }; - return d - } - }); - var nb, da; - if (!ma && !ua) da = { - init: function(a, b) { - var c = ["<", b, ' filled="f" stroked="f"'], - d = ["position: ", "absolute", ";"], - e = b === Xa; - (b === "shape" || e) && d.push("left:0;top:0;width:1px;height:1px;"); - d.push("visibility: ", e ? "hidden" : "visible"); - c.push(' style="', d.join(""), '"/>'); - if (b) c = e || b === "span" || b === "img" ? c.join("") : a.prepVML(c), this.element = ia(c); - this.renderer = a - }, - add: function(a) { - var b = this.renderer, - c = this.element, - d = b.box, - e = a && a.inverted, - d = a ? a.element || a : d; - if (a) this.parentGroup = a; - e && b.invertChild(c, d); - d.appendChild(c); - this.added = !0; - this.alignOnAdd && !this.deferUpdateTransform && this.updateTransform(); - if (this.onAdd) this.onAdd(); - return this - }, - updateTransform: ba.prototype.htmlUpdateTransform, - setSpanRotation: function() { - var a = this.rotation, - b = fa(a * ta), - c = na(a * ta); - O(this.element, { filter: a ? ["progid:DXImageTransform.Microsoft.Matrix(M11=", b, ", M12=", -c, ", M21=", c, ", M22=", b, ", sizingMethod='auto expand')"].join("") : "none" }) }, - getSpanCorrection: function(a, b, c, d, e) { - var f = d ? fa(d * ta) : 1, - g = d ? na(d * ta) : 0, - h = q(this.elemHeight, this.element.offsetHeight), - i; - this.xCorr = f < 0 && -a; - this.yCorr = g < 0 && -h; - i = f * g < 0; - this.xCorr += g * b * (i ? 1 - c : c); - this.yCorr -= f * b * - (d ? i ? c : 1 - c : 1); - e && e !== "left" && (this.xCorr -= a * c * (f < 0 ? -1 : 1), d && (this.yCorr -= h * c * (g < 0 ? -1 : 1)), O(this.element, { textAlign: e })) - }, - pathToVML: function(a) { - for (var b = a.length, c = []; b--;) - if (z(a[b])) c[b] = A(a[b] * 10) - 5; - else if (a[b] === "Z") c[b] = "x"; - else if (c[b] = a[b], a.isArc && (a[b] === "wa" || a[b] === "at")) c[b + 5] === c[b + 7] && (c[b + 7] += a[b + 7] > a[b + 5] ? 1 : -1), c[b + 6] === c[b + 8] && (c[b + 8] += a[b + 8] > a[b + 6] ? 1 : -1); - return c.join(" ") || "x" }, - clip: function(a) { - var b = this, - c; - a ? (c = a.members, Ba(c, b), c.push(b), b.destroyClip = function() { Ba(c, b) }, a = a.getCSS(b)) : - (b.destroyClip && b.destroyClip(), a = { clip: ub ? "inherit" : "rect(auto)" }); - return b.css(a) - }, - css: ba.prototype.htmlCss, - safeRemoveChild: function(a) { a.parentNode && Wa(a) }, - destroy: function() { this.destroyClip && this.destroyClip(); - return ba.prototype.destroy.apply(this) }, - on: function(a, b) { this.element["on" + a] = function() { - var a = M.event; - a.target = a.srcElement; - b(a) }; - return this }, - cutOffPath: function(a, b) { - var c, a = a.split(/[ ,]/); - c = a.length; - if (c === 9 || c === 11) a[c - 4] = a[c - 2] = H(a[c - 2]) - 10 * b; - return a.join(" ") }, - shadow: function(a, - b, c) { - var d = [], - e, f = this.element, - g = this.renderer, - h, i = f.style, - j, k = f.path, - l, m, n, p; - k && typeof k.value !== "string" && (k = "x"); - m = k; - if (a) { - n = q(a.width, 3); - p = (a.opacity || 0.15) / n; - for (e = 1; e <= 3; e++) { - l = n * 2 + 1 - 2 * e; - c && (m = this.cutOffPath(k.value, l + 0.5)); - j = ['']; - h = ia(g.prepVML(j), null, { left: H(i.left) + q(a.offsetX, 1), top: H(i.top) + q(a.offsetY, 1) }); - if (c) h.cutOff = l + 1; - j = ['' - ]; - ia(g.prepVML(j), null, null, h); - b ? b.element.appendChild(h) : f.parentNode.insertBefore(h, f); - d.push(h) - } - this.shadows = d - } - return this - }, - updateShadows: va, - setAttr: function(a, b) { ub ? this.element[a] = b : this.element.setAttribute(a, b) }, - classSetter: function(a) { this.element.className = a }, - dashstyleSetter: function(a, b, c) { - (c.getElementsByTagName("stroke")[0] || ia(this.renderer.prepVML([""]), null, null, c))[b] = a || "solid"; - this[b] = a }, - dSetter: function(a, b, c) { - var d = this.shadows, - a = a || []; - this.d = a.join && a.join(" "); - c.path = a = this.pathToVML(a); - if (d) - for (c = d.length; c--;) d[c].path = d[c].cutOff ? this.cutOffPath(a, d[c].cutOff) : a; - this.setAttr(b, a) - }, - fillSetter: function(a, b, c) { - var d = c.nodeName; - if (d === "SPAN") c.style.color = a; - else if (d !== "IMG") c.filled = a !== "none", this.setAttr("fillcolor", this.renderer.color(a, c, b, this)) }, - "fill-opacitySetter": function(a, b, c) { ia(this.renderer.prepVML(["<", b.split("-")[0], ' opacity="', a, '"/>']), null, null, c) }, - opacitySetter: va, - rotationSetter: function(a, b, c) { - c = c.style; - this[b] = c[b] = a; - c.left = -A(na(a * - ta) + 1) + "px"; - c.top = A(fa(a * ta)) + "px" - }, - strokeSetter: function(a, b, c) { this.setAttr("strokecolor", this.renderer.color(a, c, b, this)) }, - "stroke-widthSetter": function(a, b, c) { c.stroked = !!a; - this[b] = a; - z(a) && (a += "px"); - this.setAttr("strokeweight", a) }, - titleSetter: function(a, b) { this.setAttr(b, a) }, - visibilitySetter: function(a, b, c) { - a === "inherit" && (a = "visible"); - this.shadows && o(this.shadows, function(c) { c.style[b] = a }); - c.nodeName === "DIV" && (a = a === "hidden" ? "-999em" : 0, ub || (c.style[b] = a ? "visible" : "hidden"), b = "top"); - c.style[b] = - a - }, - xSetter: function(a, b, c) { this[b] = a; - b === "x" ? b = "left" : b === "y" && (b = "top"); - this.updateClipping ? (this[b] = a, this.updateClipping()) : c.style[b] = a }, - zIndexSetter: function(a, b, c) { c.style[b] = a } - }, da["stroke-opacitySetter"] = da["fill-opacitySetter"], B.VMLElement = da = oa(ba, da), da.prototype.ySetter = da.prototype.widthSetter = da.prototype.heightSetter = da.prototype.xSetter, da = { - Element: da, - isIE8: Pa.indexOf("MSIE 8.0") > -1, - init: function(a, b, c, d) { - var e; - this.alignedObjects = []; - d = this.createElement(Xa).css(v(this.getStyle(d), { position: "relative" })); - e = d.element; - a.appendChild(d.element); - this.isVML = !0; - this.box = e; - this.boxWrapper = d; - this.gradients = {}; - this.cache = {}; - this.cacheKeys = []; - this.imgCount = 0; - this.setSize(b, c, !1); - if (!C.namespaces.hcv) { C.namespaces.add("hcv", "urn:schemas-microsoft-com:vml"); - try { C.createStyleSheet().cssText = "hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } " } catch (f) { C.styleSheets[0].cssText += "hcv\\:fill, hcv\\:path, hcv\\:shape, hcv\\:stroke{ behavior:url(#default#VML); display: inline-block; } " } } - }, - isHidden: function() { - return !this.box.offsetWidth }, - clipRect: function(a, b, c, d) { - var e = this.createElement(), - f = ha(a); - return v(e, { - members: [], - count: 0, - left: (f ? a.x : a) + 1, - top: (f ? a.y : b) + 1, - width: (f ? a.width : c) - 1, - height: (f ? a.height : d) - 1, - getCSS: function(a) { - var b = a.element, - c = b.nodeName, - a = a.inverted, - d = this.top - (c === "shape" ? b.offsetTop : 0), - e = this.left, - b = e + this.width, - f = d + this.height, - d = { clip: "rect(" + A(a ? e : d) + "px," + A(a ? f : b) + "px," + A(a ? b : f) + "px," + A(a ? d : e) + "px)" };!a && ub && c === "DIV" && v(d, { width: b + "px", height: f + "px" }); - return d }, - updateClipping: function() { o(e.members, function(a) { a.element && a.css(e.getCSS(a)) }) } - }) - }, - color: function(a, b, c, d) { - var e = this, - f, g = /^rgba/, - h, i, j = "none"; - a && a.linearGradient ? i = "gradient" : a && a.radialGradient && (i = "pattern"); - if (i) { - var k, l, m = a.linearGradient || a.radialGradient, - n, p, r, s, q, u = "", - a = a.stops, - w, F = [], - L = function() { h = ['']; - ia(e.prepVML(h), null, null, b) }; - n = a[0]; - w = a[a.length - 1]; - n[0] > 0 && a.unshift([0, - n[1] - ]); - w[0] < 1 && a.push([1, w[1]]); - o(a, function(a, b) { g.test(a[1]) ? (f = xa(a[1]), k = f.get("rgb"), l = f.get("a")) : (k = a[1], l = 1); - F.push(a[0] * 100 + "% " + k); - b ? (r = l, s = k) : (p = l, q = k) }); - if (c === "fill") - if (i === "gradient") c = m.x1 || m[0] || 0, a = m.y1 || m[1] || 0, n = m.x2 || m[2] || 0, m = m.y2 || m[3] || 0, u = 'angle="' + (90 - aa.atan((m - a) / (n - c)) * 180 / Ca) + '"', L(); - else { - var j = m.r, - ka = j * 2, - t = j * 2, - y = m.cx, - x = m.cy, - A = b.radialReference, - v, j = function() { - A && (v = d.getBBox(), y += (A[0] - v.x) / v.width - 0.5, x += (A[1] - v.y) / v.height - 0.5, ka *= A[2] / v.width, t *= A[2] / v.height); - u = 'src="' + - Q.global.VMLRadialGradientURL + '" size="' + ka + "," + t + '" origin="0.5,0.5" position="' + y + "," + x + '" color2="' + q + '" '; - L() - }; - d.added ? j() : d.onAdd = j; - j = s - } - else j = k - } else if (g.test(a) && b.tagName !== "IMG") f = xa(a), d[c + "-opacitySetter"](f.get("a"), c, b), j = f.get("rgb"); - else { j = b.getElementsByTagName(c); - if (j.length) j[0].opacity = 1, j[0].type = "solid"; - j = a } - return j - }, - prepVML: function(a) { - var b = this.isIE8, - a = a.join(""); - b ? (a = a.replace("/>", ' xmlns="urn:schemas-microsoft-com:vml" />'), a = a.indexOf('style="') === -1 ? a.replace("/>", ' style="display:inline-block;behavior:url(#default#VML);" />') : - a.replace('style="', 'style="display:inline-block;behavior:url(#default#VML);')) : a = a.replace("<", " 1 && f.attr({ x: b, y: c, width: d, height: e }); - return f }, - createElement: function(a) { - return a === "rect" ? this.symbol(a) : za.prototype.createElement.call(this, a) }, - invertChild: function(a, b) { - var c = this, - d = b.style, - e = a.tagName === "IMG" && a.style; - O(a, { flip: "x", left: H(d.width) - (e ? H(e.top) : 1), top: H(d.height) - (e ? H(e.left) : 1), rotation: -90 }); - o(a.childNodes, function(b) { c.invertChild(b, a) }) }, - symbols: { - arc: function(a, b, c, d, e) { - var f = e.start, - g = e.end, - h = e.r || c || - d, - c = e.innerR, - d = fa(f), - i = na(f), - j = fa(g), - k = na(g); - if (g - f === 0) return ["x"]; - f = ["wa", a - h, b - h, a + h, b + h, a + h * d, b + h * i, a + h * j, b + h * k]; - e.open && !c && f.push("e", W, a, b); - f.push("at", a - c, b - c, a + c, b + c, a + c * j, b + c * k, a + c * d, b + c * i, "x", "e"); - f.isArc = !0; - return f - }, - circle: function(a, b, c, d, e) { e && (c = d = 2 * e.r); - e && e.isCircle && (a -= c / 2, b -= d / 2); - return ["wa", a, b, a + c, b + d, a + c, b + d / 2, a + c, b + d / 2, "e"] }, - rect: function(a, b, c, d, e) { - return za.prototype.symbols[!t(e) || !e.r ? "square" : "callout"].call(0, a, b, c, d, e) } - } - }, B.VMLRenderer = nb = function() { - this.init.apply(this, - arguments) - }, nb.prototype = D(za.prototype, da), Za = nb; - za.prototype.measureSpanWidth = function(a, b) { - var c = C.createElement("span"), - d; - d = C.createTextNode(a); - c.appendChild(d); - O(c, b); - this.box.appendChild(c); - d = c.offsetWidth; - Wa(c); - return d }; - var Zb; - if (ua) B.CanVGRenderer = da = function() { Ta = "http://www.w3.org/1999/xhtml" }, da.prototype.symbols = {}, Zb = function() { - function a() { - var a = b.length, - d; - for (d = 0; d < a; d++) b[d](); - b = [] } - var b = []; - return { - push: function(c, d) { - if (b.length === 0) { - var e = C.getElementsByTagName("head")[0], - f = C.createElement("script"); - f.type = "text/javascript"; - f.src = d; - f.onload = a; - e.appendChild(f) - } - b.push(c) - } - } - }(), Za = da; - eb.prototype = { - addLabel: function() { - var a = this.axis, - b = a.options, - c = a.chart, - d = a.categories, - e = a.names, - f = this.pos, - g = b.labels, - h = a.tickPositions, - i = f === h[0], - j = f === h[h.length - 1], - e = d ? q(d[f], e[f], f) : f, - d = this.label, - h = h.info, - k; - a.isDatetimeAxis && h && (k = b.dateTimeLabelFormats[h.higherRanks[f] || h.unitName]); - this.isFirst = i; - this.isLast = j; - b = a.labelFormatter.call({ - axis: a, - chart: c, - isFirst: i, - isLast: j, - dateTimeLabelFormat: k, - value: a.isLog ? V(a.lin2log(e)) : e - }); - t(d) ? d && d.attr({ text: b }) : (this.labelLength = (this.label = d = t(b) && g.enabled ? c.renderer.text(b, 0, 0, g.useHTML).css(D(g.style)).add(a.labelGroup) : null) && d.getBBox().width, this.rotation = 0) - }, - getLabelSize: function() { - return this.label ? this.label.getBBox()[this.axis.horiz ? "height" : "width"] : 0 }, - handleOverflow: function(a) { - var b = this.axis, - c = a.x, - d = b.chart.chartWidth, - e = b.chart.spacing, - f = q(b.labelLeft, E(b.pos, e[3])), - e = q(b.labelRight, y(b.pos + b.len, d - e[1])), - g = this.label, - h = this.rotation, - i = { left: 0, center: 0.5, right: 1 }[b.labelAlign], - j = g.getBBox().width, - k = b.getSlotWidth(), - l = k, - m = 1, - n, p = {}; - if (h) h < 0 && c - i * j < f ? n = A(c / fa(h * ta) - f) : h > 0 && c + i * j > e && (n = A((d - c) / fa(h * ta))); - else if (d = c + (1 - i) * j, c - i * j < f ? l = a.x + l * (1 - i) - f : d > e && (l = e - a.x + l * i, m = -1), l = E(k, l), l < k && b.labelAlign === "center" && (a.x += m * (k - l - i * (k - E(j, l)))), j > l || b.autoRotation && g.styles.width) n = l; - if (n) { p.width = n; - if (!b.options.labels.style.textOverflow) p.textOverflow = "ellipsis"; - g.css(p) } - }, - getPosition: function(a, b, c, d) { - var e = this.axis, - f = e.chart, - g = d && f.oldChartHeight || f.chartHeight; - return { - x: a ? e.translate(b + - c, null, null, d) + e.transB : e.left + e.offset + (e.opposite ? (d && f.oldChartWidth || f.chartWidth) - e.right - e.left : 0), - y: a ? g - e.bottom + e.offset - (e.opposite ? e.height : 0) : g - e.translate(b + c, null, null, d) - e.transB - } - }, - getLabelPosition: function(a, b, c, d, e, f, g, h) { - var i = this.axis, - j = i.transA, - k = i.reversed, - l = i.staggerLines, - m = i.tickRotCorr || { x: 0, y: 0 }, - n = e.y; - t(n) || (n = i.side === 0 ? c.rotation ? -8 : -c.getBBox().height : i.side === 2 ? m.y + 8 : fa(c.rotation * ta) * (m.y - c.getBBox(!1, 0).height / 2)); - a = a + e.x + m.x - (f && d ? f * j * (k ? -1 : 1) : 0); - b = b + n - (f && !d ? f * j * (k ? - 1 : -1) : 0); - l && (c = g / (h || 1) % l, i.opposite && (c = l - c - 1), b += c * (i.labelOffset / l)); - return { x: a, y: A(b) } - }, - getMarkPath: function(a, b, c, d, e, f) { - return f.crispLine([W, a, b, R, a + (e ? 0 : -c), b + (e ? c : 0)], d) }, - render: function(a, b, c) { - var d = this.axis, - e = d.options, - f = d.chart.renderer, - g = d.horiz, - h = this.type, - i = this.label, - j = this.pos, - k = e.labels, - l = this.gridLine, - m = h ? h + "Grid" : "grid", - n = h ? h + "Tick" : "tick", - p = e[m + "LineWidth"], - r = e[m + "LineColor"], - s = e[m + "LineDashStyle"], - m = d.tickSize(n), - n = e[n + "Color"], - o = this.mark, - u = k.step, - w = !0, - F = d.tickmarkOffset, - L = - this.getPosition(g, j, F, b), - ka = L.x, - L = L.y, - t = g && ka === d.pos + d.len || !g && L === d.pos ? -1 : 1, - c = q(c, 1); - this.isActive = !0; - if (p) { j = d.getPlotLinePath(j + F, p * t, b, !0); - if (l === x) { l = { stroke: r, "stroke-width": p }; - if (s) l.dashstyle = s; - if (!h) l.zIndex = 1; - if (b) l.opacity = 0; - this.gridLine = l = p ? f.path(j).attr(l).add(d.gridGroup) : null } - if (!b && l && j) l[this.isNew ? "attr" : "animate"]({ d: j, opacity: c }) } - if (m) d.opposite && (m[0] = -m[0]), h = this.getMarkPath(ka, L, m[0], m[1] * t, g, f), o ? o.animate({ d: h, opacity: c }) : this.mark = f.path(h).attr({ - stroke: n, - "stroke-width": m[1], - opacity: c - }).add(d.axisGroup); - if (i && z(ka)) i.xy = L = this.getLabelPosition(ka, L, i, g, k, F, a, u), this.isFirst && !this.isLast && !q(e.showFirstLabel, 1) || this.isLast && !this.isFirst && !q(e.showLastLabel, 1) ? w = !1 : g && !d.isRadial && !k.step && !k.rotation && !b && c !== 0 && this.handleOverflow(L), u && a % u && (w = !1), w && z(L.y) ? (L.opacity = c, i[this.isNew ? "attr" : "animate"](L)) : (Qa(i), i.attr("y", -9999)), this.isNew = !1 - }, - destroy: function() { Oa(this, this.axis) } - }; - B.PlotLineOrBand = function(a, b) { this.axis = a; - if (b) this.options = b, this.id = b.id }; - B.PlotLineOrBand.prototype = { - render: function() { - var a = this, - b = a.axis, - c = b.horiz, - d = a.options, - e = d.label, - f = a.label, - g = d.width, - h = d.to, - i = d.from, - j = t(i) && t(h), - k = d.value, - l = d.dashStyle, - m = a.svgElem, - n = [], - p, r = d.color, - s = q(d.zIndex, 0), - o = d.events, - u = {}, - w = b.chart.renderer, - n = b.log2lin; - b.isLog && (i = n(i), h = n(h), k = n(k)); - if (g) { - if (n = b.getPlotLinePath(k, g), u = { stroke: r, "stroke-width": g }, l) u.dashstyle = l } else if (j) { n = b.getPlotBandPath(i, h, d); - if (r) u.fill = r; - if (d.borderWidth) u.stroke = d.borderColor, u["stroke-width"] = d.borderWidth } else return; - u.zIndex = s; - if (m) - if (n) m.show(), - m.animate({ d: n }); - else { - if (m.hide(), f) a.label = f = f.destroy() } - else if (n && n.length && (a.svgElem = m = w.path(n).attr(u).add(), o)) - for (p in d = function(b) { m.on(b, function(c) { o[b].apply(a, [c]) }) }, o) d(p); - e && t(e.text) && n && n.length && b.width > 0 && b.height > 0 && !n.flat ? (e = D({ align: c && j && "center", x: c ? !j && 4 : 10, verticalAlign: !c && j && "middle", y: c ? j ? 16 : 10 : j ? 6 : -4, rotation: c && !j && 90 }, e), this.renderLabel(e, n, j, s)) : f && f.hide(); - return a - }, - renderLabel: function(a, b, c, d) { - var e = this.label, - f = this.axis.chart.renderer; - if (!e) e = { - align: a.textAlign || - a.align, - rotation: a.rotation - }, e.zIndex = d, this.label = e = f.text(a.text, 0, 0, a.useHTML).attr(e).css(a.style).add(); - d = [b[1], b[4], c ? b[6] : b[1]]; - b = [b[2], b[5], c ? b[7] : b[2]]; - c = Na(d); - f = Na(b); - e.align(a, !1, { x: c, y: f, width: Fa(d) - c, height: Fa(b) - f }); - e.show() - }, - destroy: function() { Ba(this.axis.plotLinesAndBands, this); - delete this.axis; - Oa(this) } - }; - var J = B.Axis = function() { this.init.apply(this, arguments) }; - J.prototype = { - defaultOptions: { - dateTimeLabelFormats: { - millisecond: "%H:%M:%S.%L", - second: "%H:%M:%S", - minute: "%H:%M", - hour: "%H:%M", - day: "%e. %b", - week: "%e. %b", - month: "%b '%y", - year: "%Y" - }, - endOnTick: !1, - gridLineColor: "#D8D8D8", - labels: { enabled: !0, style: { color: "#606060", cursor: "default", fontSize: "11px" }, x: 0 }, - lineColor: "#C0D0E0", - lineWidth: 1, - minPadding: 0.01, - maxPadding: 0.01, - minorGridLineColor: "#E0E0E0", - minorGridLineWidth: 1, - minorTickColor: "#A0A0A0", - minorTickLength: 2, - minorTickPosition: "outside", - startOfWeek: 1, - startOnTick: !1, - tickColor: "#C0D0E0", - tickLength: 10, - tickmarkPlacement: "between", - tickPixelInterval: 100, - tickPosition: "outside", - title: { - align: "middle", - style: { color: "#707070" } - }, - type: "linear" - }, - defaultYAxisOptions: { endOnTick: !0, gridLineWidth: 1, tickPixelInterval: 72, showLastLabel: !0, labels: { x: -8 }, lineWidth: 0, maxPadding: 0.05, minPadding: 0.05, startOnTick: !0, title: { rotation: 270, text: "Values" }, stackLabels: { enabled: !1, formatter: function() { - return B.numberFormat(this.total, -1) }, style: D(X.line.dataLabels.style, { color: "#000000" }) } }, - defaultLeftAxisOptions: { labels: { x: -15 }, title: { rotation: 270 } }, - defaultRightAxisOptions: { labels: { x: 15 }, title: { rotation: 90 } }, - defaultBottomAxisOptions: { - labels: { - autoRotation: [-45], - x: 0 - }, - title: { rotation: 0 } - }, - defaultTopAxisOptions: { labels: { autoRotation: [-45], x: 0 }, title: { rotation: 0 } }, - init: function(a, b) { - var c = b.isX; - this.chart = a; - this.horiz = a.inverted ? !c : c; - this.coll = (this.isXAxis = c) ? "xAxis" : "yAxis"; - this.opposite = b.opposite; - this.side = b.side || (this.horiz ? this.opposite ? 0 : 2 : this.opposite ? 1 : 3); - this.setOptions(b); - var d = this.options, - e = d.type; - this.labelFormatter = d.labels.formatter || this.defaultLabelFormatter; - this.userOptions = b; - this.minPixelPadding = 0; - this.reversed = d.reversed; - this.visible = d.visible !== - !1; - this.zoomEnabled = d.zoomEnabled !== !1; - this.categories = d.categories || e === "category"; - this.names = this.names || []; - this.isLog = e === "logarithmic"; - this.isDatetimeAxis = e === "datetime"; - this.isLinked = t(d.linkedTo); - this.ticks = {}; - this.labelEdge = []; - this.minorTicks = {}; - this.plotLinesAndBands = []; - this.alternateBands = {}; - this.len = 0; - this.minRange = this.userMinRange = d.minRange || d.maxZoom; - this.range = d.range; - this.offset = d.offset || 0; - this.stacks = {}; - this.oldStacks = {}; - this.stacksTouched = 0; - this.min = this.max = null; - this.crosshair = - q(d.crosshair, sa(a.options.tooltip.crosshairs)[c ? 0 : 1], !1); - var f, d = this.options.events; - qa(this, a.axes) === -1 && (c && !this.isColorAxis ? a.axes.splice(a.xAxis.length, 0, this) : a.axes.push(this), a[this.coll].push(this)); - this.series = this.series || []; - if (a.inverted && c && this.reversed === x) this.reversed = !0; - this.removePlotLine = this.removePlotBand = this.removePlotBandOrLine; - for (f in d) G(this, f, d[f]); - if (this.isLog) this.val2lin = this.log2lin, this.lin2val = this.lin2log - }, - setOptions: function(a) { - this.options = D(this.defaultOptions, - this.isXAxis ? {} : this.defaultYAxisOptions, [this.defaultTopAxisOptions, this.defaultRightAxisOptions, this.defaultBottomAxisOptions, this.defaultLeftAxisOptions][this.side], D(Q[this.coll], a)) - }, - defaultLabelFormatter: function() { - var a = this.axis, - b = this.value, - c = a.categories, - d = this.dateTimeLabelFormat, - e = Q.lang.numericSymbols, - f = e && e.length, - g, h = a.options.labels.format, - a = a.isLog ? b : a.tickInterval; - if (h) g = Ma(h, this); - else if (c) g = b; - else if (d) g = pa(d, b); - else if (f && a >= 1E3) - for (; f-- && g === x;) c = Math.pow(1E3, f + 1), a >= c && b * 10 % - c === 0 && e[f] !== null && b !== 0 && (g = B.numberFormat(b / c, -1) + e[f]); - g === x && (g = T(b) >= 1E4 ? B.numberFormat(b, -1) : B.numberFormat(b, -1, x, "")); - return g - }, - getSeriesExtremes: function() { - var a = this, - b = a.chart; - a.hasVisibleSeries = !1; - a.dataMin = a.dataMax = a.threshold = null; - a.softThreshold = !a.isXAxis; - a.buildStacks && a.buildStacks(); - o(a.series, function(c) { - if (c.visible || !b.options.chart.ignoreHiddenSeries) { - var d = c.options, - e = d.threshold, - f; - a.hasVisibleSeries = !0; - a.isLog && e <= 0 && (e = null); - if (a.isXAxis) { - if (d = c.xData, d.length) c = Na(d), !z(c) && - !(c instanceof ea) && (d = Ha(d, function(a) { - return z(a) }), c = Na(d)), a.dataMin = E(q(a.dataMin, d[0]), c), a.dataMax = y(q(a.dataMax, d[0]), Fa(d)) - } else { c.getExtremes(); - f = c.dataMax; - c = c.dataMin; - if (t(c) && t(f)) a.dataMin = E(q(a.dataMin, c), c), a.dataMax = y(q(a.dataMax, f), f); - if (t(e)) a.threshold = e; - if (!d.softThreshold || a.isLog) a.softThreshold = !1 } - } - }) - }, - translate: function(a, b, c, d, e, f) { - var g = this.linkedParent || this, - h = 1, - i = 0, - j = d ? g.oldTransA : g.transA, - d = d ? g.oldMin : g.min, - k = g.minPixelPadding, - e = (g.isOrdinal || g.isBroken || g.isLog && e) && - g.lin2val; - if (!j) j = g.transA; - if (c) h *= -1, i = g.len; - g.reversed && (h *= -1, i -= h * (g.sector || g.len)); - b ? (a = a * h + i, a -= k, a = a / j + d, e && (a = g.lin2val(a))) : (e && (a = g.val2lin(a)), f === "between" && (f = 0.5), a = h * (a - d) * j + i + h * k + (z(f) ? j * f * g.pointRange : 0)); - return a - }, - toPixels: function(a, b) { - return this.translate(a, !1, !this.horiz, null, !0) + (b ? 0 : this.pos) }, - toValue: function(a, b) { - return this.translate(a - (b ? 0 : this.pos), !0, !this.horiz, null, !0) }, - getPlotLinePath: function(a, b, c, d, e) { - var f = this.chart, - g = this.left, - h = this.top, - i, j, k = c && f.oldChartHeight || - f.chartHeight, - l = c && f.oldChartWidth || f.chartWidth, - m; - i = this.transB; - var n = function(a, b, c) { - if (a < b || a > c) d ? a = E(y(b, a), c) : m = !0; - return a }, - e = q(e, this.translate(a, null, null, c)), - a = c = A(e + i); - i = j = A(k - e - i); - z(e) ? this.horiz ? (i = h, j = k - this.bottom, a = c = n(a, g, g + this.width)) : (a = g, c = l - this.right, i = j = n(i, h, h + this.height)) : m = !0; - return m && !d ? null : f.renderer.crispLine([W, a, i, R, c, j], b || 1) - }, - getLinearTickPositions: function(a, b, c) { - var d, e = V(Y(b / a) * a), - f = V(Ga(c / a) * a), - g = []; - if (b === c && z(b)) return [b]; - for (b = e; b <= f;) { - g.push(b); - b = V(b + a); - if (b === d) break; - d = b - } - return g - }, - getMinorTickPositions: function() { - var a = this.options, - b = this.tickPositions, - c = this.minorTickInterval, - d = [], - e, f = this.pointRangePadding || 0; - e = this.min - f; - var f = this.max + f, - g = f - e; - if (g && g / c < this.len / 3) - if (this.isLog) { f = b.length; - for (e = 1; e < f; e++) d = d.concat(this.getLogTickPositions(c, b[e - 1], b[e], !0)) } else if (this.isDatetimeAxis && a.minorTickInterval === "auto") d = d.concat(this.getTimeTicks(this.normalizeTimeTickInterval(c), e, f, a.startOfWeek)); - else - for (b = e + (b[0] - e) % c; b <= f; b += c) d.push(b); - d.length !== 0 && this.trimTicks(d, a.startOnTick, a.endOnTick); - return d - }, - adjustForMinRange: function() { - var a = this.options, - b = this.min, - c = this.max, - d, e = this.dataMax - this.dataMin >= this.minRange, - f, g, h, i, j, k; - if (this.isXAxis && this.minRange === x && !this.isLog) t(a.min) || t(a.max) ? this.minRange = null : (o(this.series, function(a) { i = a.xData; - for (g = j = a.xIncrement ? 1 : i.length - 1; g > 0; g--) - if (h = i[g] - i[g - 1], f === x || h < f) f = h }), this.minRange = E(f * 5, this.dataMax - this.dataMin)); - if (c - b < this.minRange) { - k = this.minRange; - d = (k - c + b) / 2; - d = [b - d, q(a.min, - b - d)]; - if (e) d[2] = this.dataMin; - b = Fa(d); - c = [b + k, q(a.max, b + k)]; - if (e) c[2] = this.dataMax; - c = Na(c); - c - b < k && (d[0] = c - k, d[1] = q(a.min, c - k), b = Fa(d)) - } - this.min = b; - this.max = c - }, - getClosest: function() { - var a; - this.categories ? a = 1 : o(this.series, function(b) { - var c = b.closestPointRange;!b.noSharedTooltip && t(c) && (a = t(a) ? E(a, c) : c) }); - return a }, - setAxisTranslation: function(a) { - var b = this, - c = b.max - b.min, - d = b.axisPointRange || 0, - e, f = 0, - g = 0, - h = b.linkedParent, - i = !!b.categories, - j = b.transA, - k = b.isXAxis; - if (k || i || d) - if (h ? (f = h.minPointOffset, g = h.pointRangePadding) : - (e = b.getClosest(), o(b.series, function(a) { - var c = i ? 1 : k ? q(a.options.pointRange, e, 0) : b.axisPointRange || 0, - a = a.options.pointPlacement; - d = y(d, c); - b.single || (f = y(f, Ea(a) ? 0 : c / 2), g = y(g, a === "on" ? 0 : c)) })), h = b.ordinalSlope && e ? b.ordinalSlope / e : 1, b.minPointOffset = f *= h, b.pointRangePadding = g *= h, b.pointRange = E(d, c), k) b.closestPointRange = e; - if (a) b.oldTransA = j; - b.translationSlope = b.transA = j = b.len / (c + g || 1); - b.transB = b.horiz ? b.left : b.bottom; - b.minPixelPadding = j * f - }, - minFromRange: function() { - return this.max - this.range }, - setTickInterval: function(a) { - var b = - this, - c = b.chart, - d = b.options, - e = b.isLog, - f = b.log2lin, - g = b.isDatetimeAxis, - h = b.isXAxis, - i = b.isLinked, - j = d.maxPadding, - k = d.minPadding, - l = d.tickInterval, - m = d.tickPixelInterval, - n = b.categories, - p = b.threshold, - r = b.softThreshold, - s, Z, u, w; - !g && !n && !i && this.getTickAmount(); - u = q(b.userMin, d.min); - w = q(b.userMax, d.max); - i ? (b.linkedParent = c[b.coll][d.linkedTo], c = b.linkedParent.getExtremes(), b.min = q(c.min, c.dataMin), b.max = q(c.max, c.dataMax), d.type !== b.linkedParent.options.type && ja(11, 1)) : (!r && t(p) && (b.dataMin >= p ? (s = p, k = 0) : b.dataMax <= - p && (Z = p, j = 0)), b.min = q(u, s, b.dataMin), b.max = q(w, Z, b.dataMax)); - if (e) !a && E(b.min, q(b.dataMin, b.min)) <= 0 && ja(10, 1), b.min = V(f(b.min), 15), b.max = V(f(b.max), 15); - if (b.range && t(b.max)) b.userMin = b.min = u = y(b.min, b.minFromRange()), b.userMax = w = b.max, b.range = null; - K(b, "foundExtremes"); - b.beforePadding && b.beforePadding(); - b.adjustForMinRange(); - if (!n && !b.axisPointRange && !b.usePercentage && !i && t(b.min) && t(b.max) && (f = b.max - b.min)) !t(u) && k && (b.min -= f * k), !t(w) && j && (b.max += f * j); - if (z(d.floor)) b.min = y(b.min, d.floor); - if (z(d.ceiling)) b.max = - E(b.max, d.ceiling); - if (r && t(b.dataMin)) - if (p = p || 0, !t(u) && b.min < p && b.dataMin >= p) b.min = p; - else if (!t(w) && b.max > p && b.dataMax <= p) b.max = p; - b.tickInterval = b.min === b.max || b.min === void 0 || b.max === void 0 ? 1 : i && !l && m === b.linkedParent.options.tickPixelInterval ? l = b.linkedParent.tickInterval : q(l, this.tickAmount ? (b.max - b.min) / y(this.tickAmount - 1, 1) : void 0, n ? 1 : (b.max - b.min) * m / y(b.len, m)); - h && !a && o(b.series, function(a) { a.processData(b.min !== b.oldMin || b.max !== b.oldMax) }); - b.setAxisTranslation(!0); - b.beforeSetTickPositions && - b.beforeSetTickPositions(); - if (b.postProcessTickInterval) b.tickInterval = b.postProcessTickInterval(b.tickInterval); - if (b.pointRange && !l) b.tickInterval = y(b.pointRange, b.tickInterval); - a = q(d.minTickInterval, b.isDatetimeAxis && b.closestPointRange); - if (!l && b.tickInterval < a) b.tickInterval = a; - if (!g && !e && !l) b.tickInterval = Db(b.tickInterval, null, Cb(b.tickInterval), q(d.allowDecimals, !(b.tickInterval > 0.5 && b.tickInterval < 5 && b.max > 1E3 && b.max < 9999)), !!this.tickAmount); - if (!this.tickAmount && this.len) b.tickInterval = b.unsquish(); - this.setTickPositions() - }, - setTickPositions: function() { - var a = this.options, - b, c = a.tickPositions, - d = a.tickPositioner, - e = a.startOnTick, - f = a.endOnTick, - g; - this.tickmarkOffset = this.categories && a.tickmarkPlacement === "between" && this.tickInterval === 1 ? 0.5 : 0; - this.minorTickInterval = a.minorTickInterval === "auto" && this.tickInterval ? this.tickInterval / 5 : a.minorTickInterval; - this.tickPositions = b = c && c.slice(); - if (!b && (b = this.isDatetimeAxis ? this.getTimeTicks(this.normalizeTimeTickInterval(this.tickInterval, a.units), this.min, - this.max, a.startOfWeek, this.ordinalPositions, this.closestPointRange, !0) : this.isLog ? this.getLogTickPositions(this.tickInterval, this.min, this.max) : this.getLinearTickPositions(this.tickInterval, this.min, this.max), b.length > this.len && (b = [b[0], b.pop()]), this.tickPositions = b, d && (d = d.apply(this, [this.min, this.max])))) this.tickPositions = b = d; - if (!this.isLinked) this.trimTicks(b, e, f), this.min === this.max && t(this.min) && !this.tickAmount && (g = !0, this.min -= 0.5, this.max += 0.5), this.single = g, !c && !d && this.adjustTickAmount() - }, - trimTicks: function(a, b, c) { - var d = a[0], - e = a[a.length - 1], - f = this.minPointOffset || 0; - if (b) this.min = d; - else - for (; this.min - f > a[0];) a.shift(); - if (c) this.max = e; - else - for (; this.max + f < a[a.length - 1];) a.pop(); - a.length === 0 && t(d) && a.push((e + d) / 2) }, - alignToOthers: function() { - var a = {}, - b, c = this.options; - this.chart.options.chart.alignTicks !== !1 && c.alignTicks !== !1 && o(this.chart[this.coll], function(c) { - var e = c.options, - e = [c.horiz ? e.left : e.top, e.width, e.height, e.pane].join(","); - c.series.length && (a[e] ? b = !0 : a[e] = 1) }); - return b }, - getTickAmount: function() { - var a = - this.options, - b = a.tickAmount, - c = a.tickPixelInterval; - !t(a.tickInterval) && this.len < c && !this.isRadial && !this.isLog && a.startOnTick && a.endOnTick && (b = 2); - !b && this.alignToOthers() && (b = Ga(this.len / c) + 1); - if (b < 4) this.finalTickAmt = b, b = 5; - this.tickAmount = b - }, - adjustTickAmount: function() { - var a = this.tickInterval, - b = this.tickPositions, - c = this.tickAmount, - d = this.finalTickAmt, - e = b && b.length; - if (e < c) { - for (; b.length < c;) b.push(V(b[b.length - 1] + a)); - this.transA *= (e - 1) / (c - 1); - this.max = b[b.length - 1] } else e > c && (this.tickInterval *= 2, this.setTickPositions()); - if (t(d)) { - for (a = c = b.length; a--;)(d === 3 && a % 2 === 1 || d <= 2 && a > 0 && a < c - 1) && b.splice(a, 1); - this.finalTickAmt = x } - }, - setScale: function() { - var a, b; - this.oldMin = this.min; - this.oldMax = this.max; - this.oldAxisLength = this.len; - this.setAxisSize(); - b = this.len !== this.oldAxisLength; - o(this.series, function(b) { - if (b.isDirtyData || b.isDirty || b.xAxis.isDirty) a = !0 }); - if (b || a || this.isLinked || this.forceRedraw || this.userMin !== this.oldUserMin || this.userMax !== this.oldUserMax || this.alignToOthers()) { - if (this.resetStacks && this.resetStacks(), this.forceRedraw = !1, this.getSeriesExtremes(), this.setTickInterval(), this.oldUserMin = this.userMin, this.oldUserMax = this.userMax, !this.isDirty) this.isDirty = b || this.min !== this.oldMin || this.max !== this.oldMax - } else this.cleanStacks && this.cleanStacks() - }, - setExtremes: function(a, b, c, d, e) { - var f = this, - g = f.chart, - c = q(c, !0); - o(f.series, function(a) { delete a.kdTree }); - e = v(e, { min: a, max: b }); - K(f, "setExtremes", e, function() { f.userMin = a; - f.userMax = b; - f.eventArgs = e; - c && g.redraw(d) }) }, - zoom: function(a, b) { - var c = this.dataMin, - d = this.dataMax, - e = this.options, - f = E(c, q(e.min, c)), - e = y(d, q(e.max, d)); - this.allowZoomOutside || (t(c) && a <= f && (a = f), t(d) && b >= e && (b = e)); - this.displayBtn = a !== x || b !== x; - this.setExtremes(a, b, !1, x, { trigger: "zoom" }); - return !0 - }, - setAxisSize: function() { - var a = this.chart, - b = this.options, - c = b.offsetLeft || 0, - d = this.horiz, - e = q(b.width, a.plotWidth - c + (b.offsetRight || 0)), - f = q(b.height, a.plotHeight), - g = q(b.top, a.plotTop), - b = q(b.left, a.plotLeft + c), - c = /%$/; - c.test(f) && (f = Math.round(parseFloat(f) / 100 * a.plotHeight)); - c.test(g) && (g = Math.round(parseFloat(g) / 100 * a.plotHeight + - a.plotTop)); - this.left = b; - this.top = g; - this.width = e; - this.height = f; - this.bottom = a.chartHeight - f - g; - this.right = a.chartWidth - e - b; - this.len = y(d ? e : f, 0); - this.pos = d ? b : g - }, - getExtremes: function() { - var a = this.isLog, - b = this.lin2log; - return { min: a ? V(b(this.min)) : this.min, max: a ? V(b(this.max)) : this.max, dataMin: this.dataMin, dataMax: this.dataMax, userMin: this.userMin, userMax: this.userMax } }, - getThreshold: function(a) { - var b = this.isLog, - c = this.lin2log, - d = b ? c(this.min) : this.min, - b = b ? c(this.max) : this.max; - a === null ? a = d : d > a ? a = d : b < a && (a = b); - return this.translate(a, 0, 1, 0, 1) - }, - autoLabelAlign: function(a) { a = (q(a, 0) - this.side * 90 + 720) % 360; - return a > 15 && a < 165 ? "right" : a > 195 && a < 345 ? "left" : "center" }, - tickSize: function(a) { - var b = this.options, - c = b[a + "Length"], - d = q(b[a + "Width"], a === "tick" && this.isXAxis ? 1 : 0); - if (d && c) return b[a + "Position"] === "inside" && (c = -c), [c, d] }, - labelMetrics: function() { - return this.chart.renderer.fontMetrics(this.options.labels.style.fontSize, this.ticks[0] && this.ticks[0].label) }, - unsquish: function() { - var a = this.options.labels, - b = this.horiz, - c = this.tickInterval, - d = c, - e = this.len / (((this.categories ? 1 : 0) + this.max - this.min) / c), - f, g = a.rotation, - h = this.labelMetrics(), - i, j = Number.MAX_VALUE, - k, l = function(a) { a /= e || 1; - a = a > 1 ? Ga(a) : 1; - return a * c }; - b ? (k = !a.staggerLines && !a.step && (t(g) ? [g] : e < q(a.autoRotationLimit, 80) && a.autoRotation)) && o(k, function(a) { - var b; - if (a === g || a && a >= -90 && a <= 90) i = l(T(h.h / na(ta * a))), b = i + T(a / 360), b < j && (j = b, f = a, d = i) }) : a.step || (d = l(h.h)); - this.autoRotation = k; - this.labelRotation = q(f, g); - return d - }, - getSlotWidth: function() { - var a = this.chart, - b = this.horiz, - c = this.options.labels, - d = Math.max(this.tickPositions.length - (this.categories ? 0 : 1), 1), - e = a.margin[3]; - return b && (c.step || 0) < 2 && !c.rotation && (this.staggerLines || 1) * a.plotWidth / d || !b && (e && e - a.spacing[3] || a.chartWidth * 0.33) - }, - renderUnsquish: function() { - var a = this.chart, - b = a.renderer, - c = this.tickPositions, - d = this.ticks, - e = this.options.labels, - f = this.horiz, - g = this.getSlotWidth(), - h = y(1, A(g - 2 * (e.padding || 5))), - i = {}, - j = this.labelMetrics(), - k = e.style.textOverflow, - l, m = 0, - n, p; - if (!Ea(e.rotation)) i.rotation = e.rotation || 0; - if (this.autoRotation) o(c, - function(a) { - if ((a = d[a]) && a.labelLength > m) m = a.labelLength }), m > h && m > j.h ? i.rotation = this.labelRotation : this.labelRotation = 0; - else if (g && (l = { width: h + "px" }, !k)) { l.textOverflow = "clip"; - for (n = c.length; !f && n--;) - if (p = c[n], h = d[p].label) - if (h.styles.textOverflow === "ellipsis" ? h.css({ textOverflow: "clip" }) : d[p].labelLength > g && h.css({ width: g + "px" }), h.getBBox().height > this.len / c.length - (j.h - j.f)) h.specCss = { textOverflow: "ellipsis" } } - if (i.rotation && (l = { width: (m > a.chartHeight * 0.5 ? a.chartHeight * 0.33 : a.chartHeight) + "px" }, !k)) l.textOverflow = "ellipsis"; - if (this.labelAlign = e.align || this.autoLabelAlign(this.labelRotation)) i.align = this.labelAlign; - o(c, function(a) { - var b = (a = d[a]) && a.label; - if (b) b.attr(i), l && b.css(D(l, b.specCss)), delete b.specCss, a.rotation = i.rotation }); - this.tickRotCorr = b.rotCorr(j.b, this.labelRotation || 0, this.side !== 0) - }, - hasData: function() { - return this.hasVisibleSeries || t(this.min) && t(this.max) && !!this.tickPositions }, - getOffset: function() { - var a = this, - b = a.chart, - c = b.renderer, - d = a.options, - e = a.tickPositions, - f = a.ticks, - g = a.horiz, - h = a.side, - i = b.inverted ? [1, 0, 3, 2][h] : h, - j, k, l = 0, - m, n = 0, - p = d.title, - r = d.labels, - s = 0, - Z = a.opposite, - u = b.axisOffset, - b = b.clipOffset, - w = [-1, 1, 1, -1][h], - F, L = a.axisParent, - ka = this.tickSize("tick"); - j = a.hasData(); - a.showAxis = k = j || q(d.showEmpty, !0); - a.staggerLines = a.horiz && r.staggerLines; - if (!a.axisGroup) a.gridGroup = c.g("grid").attr({ zIndex: d.gridZIndex || 1 }).add(L), a.axisGroup = c.g("axis").attr({ zIndex: d.zIndex || 2 }).add(L), a.labelGroup = c.g("axis-labels").attr({ zIndex: r.zIndex || 7 }).addClass("highcharts-" + a.coll.toLowerCase() + - "-labels").add(L); - if (j || a.isLinked) { - if (o(e, function(b) { f[b] ? f[b].addLabel() : f[b] = new eb(a, b) }), a.renderUnsquish(), r.reserveSpace !== !1 && (h === 0 || h === 2 || { 1: "left", 3: "right" }[h] === a.labelAlign || a.labelAlign === "center") && o(e, function(a) { s = y(f[a].getLabelSize(), s) }), a.staggerLines) s *= a.staggerLines, a.labelOffset = s * (a.opposite ? -1 : 1) } else - for (F in f) f[F].destroy(), delete f[F]; - if (p && p.text && p.enabled !== !1) { - if (!a.axisTitle)(F = p.textAlign) || (F = (g ? { low: "left", middle: "center", high: "right" } : { - low: Z ? "right" : "left", - middle: "center", - high: Z ? "left" : "right" - })[p.align]), a.axisTitle = c.text(p.text, 0, 0, p.useHTML).attr({ zIndex: 7, rotation: p.rotation || 0, align: F }).addClass("highcharts-" + this.coll.toLowerCase() + "-title").css(p.style).add(a.axisGroup), a.axisTitle.isNew = !0; - if (k) l = a.axisTitle.getBBox()[g ? "height" : "width"], m = p.offset, n = t(m) ? 0 : q(p.margin, g ? 5 : 10); - a.axisTitle[k ? "show" : "hide"](!0) - } - a.offset = w * q(d.offset, u[h]); - a.tickRotCorr = a.tickRotCorr || { x: 0, y: 0 }; - c = h === 0 ? -a.labelMetrics().h : h === 2 ? a.tickRotCorr.y : 0; - n = Math.abs(s) + - n; - s && (n -= c, n += w * (g ? q(r.y, a.tickRotCorr.y + w * 8) : r.x)); - a.axisTitleMargin = q(m, n); - u[h] = y(u[h], a.axisTitleMargin + l + w * a.offset, n, j && e.length && ka ? ka[0] : 0); - d = d.offset ? 0 : Y(d.lineWidth / 2) * 2; - b[i] = y(b[i], d) - }, - getLinePath: function(a) { - var b = this.chart, - c = this.opposite, - d = this.offset, - e = this.horiz, - f = this.left + (c ? this.width : 0) + d, - d = b.chartHeight - this.bottom - (c ? this.height : 0) + d; - c && (a *= -1); - return b.renderer.crispLine([W, e ? this.left : f, e ? d : this.top, R, e ? b.chartWidth - this.right : f, e ? d : b.chartHeight - this.bottom], a) }, - getTitlePosition: function() { - var a = - this.horiz, - b = this.left, - c = this.top, - d = this.len, - e = this.options.title, - f = a ? b : c, - g = this.opposite, - h = this.offset, - i = e.x || 0, - j = e.y || 0, - k = this.chart.renderer.fontMetrics(e.style.fontSize).f, - d = { low: f + (a ? 0 : d), middle: f + d / 2, high: f + (a ? d : 0) }[e.align], - b = (a ? c + this.height : b) + (a ? 1 : -1) * (g ? -1 : 1) * this.axisTitleMargin + (this.side === 2 ? k : 0); - return { x: a ? d + i : b + (g ? this.width : 0) + h + i, y: a ? b + j - (g ? this.height : 0) + h : d + j } - }, - render: function() { - var a = this, - b = a.chart, - c = b.renderer, - d = a.options, - e = a.isLog, - f = a.lin2log, - g = a.isLinked, - h = a.tickPositions, - i = a.axisTitle, - j = a.ticks, - k = a.minorTicks, - l = a.alternateBands, - m = d.stackLabels, - n = d.alternateGridColor, - p = a.tickmarkOffset, - r = d.lineWidth, - s, q = b.hasRendered && z(a.oldMin), - u = a.showAxis, - w = ib(c.globalAnimation), - F, L; - a.labelEdge.length = 0; - a.overlap = !1; - o([j, k, l], function(a) { - for (var b in a) a[b].isActive = !1 }); - if (a.hasData() || g) { - a.minorTickInterval && !a.categories && o(a.getMinorTickPositions(), function(b) { k[b] || (k[b] = new eb(a, b, "minor")); - q && k[b].isNew && k[b].render(null, !0); - k[b].render(null, !1, 1) }); - if (h.length && (o(h, function(b, - c) { - if (!g || b >= a.min && b <= a.max) j[b] || (j[b] = new eb(a, b)), q && j[b].isNew && j[b].render(c, !0, 0.1), j[b].render(c) }), p && (a.min === 0 || a.single))) j[-1] || (j[-1] = new eb(a, -1, null, !0)), j[-1].render(-1); - n && o(h, function(c, d) { L = h[d + 1] !== x ? h[d + 1] + p : a.max - p; - if (d % 2 === 0 && c < a.max && L <= a.max + (b.polar ? -p : p)) l[c] || (l[c] = new B.PlotLineOrBand(a)), F = c + p, l[c].options = { from: e ? f(F) : F, to: e ? f(L) : L, color: n }, l[c].render(), l[c].isActive = !0 }); - if (!a._addedPlotLB) o((d.plotLines || []).concat(d.plotBands || []), function(b) { a.addPlotBandOrLine(b) }), - a._addedPlotLB = !0 - } - o([j, k, l], function(a) { - var c, d, e = [], - f = w.duration; - for (c in a) - if (!a[c].isActive) a[c].render(c, !1, 0), a[c].isActive = !1, e.push(c); - bb(function() { - for (d = e.length; d--;) a[e[d]] && !a[e[d]].isActive && (a[e[d]].destroy(), delete a[e[d]]) }, a === l || !b.hasRendered || !f ? 0 : f) }); - if (r) s = a.getLinePath(r), a.axisLine ? a.axisLine.animate({ d: s }) : a.axisLine = c.path(s).attr({ stroke: d.lineColor, "stroke-width": r, zIndex: 7 }).add(a.axisGroup), a.axisLine[u ? "show" : "hide"](!0); - if (i && u) i[i.isNew ? "attr" : "animate"](a.getTitlePosition()), - i.isNew = !1; - m && m.enabled && a.renderStackTotals(); - a.isDirty = !1 - }, - redraw: function() { this.visible && (this.render(), o(this.plotLinesAndBands, function(a) { a.render() })); - o(this.series, function(a) { a.isDirty = !0 }) }, - destroy: function(a) { - var b = this, - c = b.stacks, - d, e = b.plotLinesAndBands; - a || U(b); - for (d in c) Oa(c[d]), c[d] = null; - o([b.ticks, b.minorTicks, b.alternateBands], function(a) { Oa(a) }); - for (a = e.length; a--;) e[a].destroy(); - o("stackTotalGroup,axisLine,axisTitle,axisGroup,gridGroup,labelGroup,cross".split(","), function(a) { - b[a] && - (b[a] = b[a].destroy()) - }); - this._addedPlotLB = this.chart._labelPanes = this.ordinalSlope = void 0 - }, - drawCrosshair: function(a, b) { - var c, d = this.crosshair, - e, f; - a || (a = this.cross && this.cross.e); - if (!this.crosshair || (t(b) || !q(d.snap, !0)) === !1) this.hideCrosshair(); - else if (q(d.snap, !0) ? t(b) && (c = this.isXAxis ? b.plotX : this.len - b.plotY) : c = this.horiz ? a.chartX - this.pos : this.len - a.chartY + this.pos, c = this.isRadial ? this.getPlotLinePath(this.isXAxis ? b.x : q(b.stackY, b.y)) || null : this.getPlotLinePath(null, null, null, null, c) || null, c === - null) this.hideCrosshair(); - else { e = this.categories && !this.isRadial; - f = q(d.width, e ? this.transA : 1); - if (this.cross) this.cross.attr({ d: c, visibility: "visible", "stroke-width": f }); - else { e = { "pointer-events": "none", "stroke-width": f, stroke: d.color || (e ? "rgba(155,200,255,0.2)" : "#C0C0C0"), zIndex: q(d.zIndex, 2) }; - if (d.dashStyle) e.dashstyle = d.dashStyle; - this.cross = this.chart.renderer.path(c).attr(e).add() } - this.cross.e = a } - }, - hideCrosshair: function() { this.cross && this.cross.hide() } - }; - v(J.prototype, { - getPlotBandPath: function(a, - b) { - var c = this.getPlotLinePath(b, null, null, !0), - d = this.getPlotLinePath(a, null, null, !0); - d && c ? (d.flat = d.toString() === c.toString(), d.push(c[4], c[5], c[1], c[2])) : d = null; - return d }, - addPlotBand: function(a) { - return this.addPlotBandOrLine(a, "plotBands") }, - addPlotLine: function(a) { - return this.addPlotBandOrLine(a, "plotLines") }, - addPlotBandOrLine: function(a, b) { - var c = (new B.PlotLineOrBand(this, a)).render(), - d = this.userOptions; - c && (b && (d[b] = d[b] || [], d[b].push(a)), this.plotLinesAndBands.push(c)); - return c }, - removePlotBandOrLine: function(a) { - for (var b = - this.plotLinesAndBands, c = this.options, d = this.userOptions, e = b.length; e--;) b[e].id === a && b[e].destroy(); - o([c.plotLines || [], d.plotLines || [], c.plotBands || [], d.plotBands || []], function(b) { - for (e = b.length; e--;) b[e].id === a && Ba(b, b[e]) }) - } - }); - J.prototype.getTimeTicks = function(a, b, c, d) { - var e = [], - f = {}, - g = Q.global.useUTC, - h, i = new ea(b - gb(b)), - j = a.unitRange, - k = a.count; - if (t(b)) { - i[Rb](j >= N.second ? 0 : k * Y(i.getMilliseconds() / k)); - if (j >= N.second) i[Sb](j >= N.minute ? 0 : k * Y(i.getSeconds() / k)); - if (j >= N.minute) i[Tb](j >= N.hour ? 0 : k * Y(i[Eb]() / - k)); - if (j >= N.hour) i[Ub](j >= N.day ? 0 : k * Y(i[Fb]() / k)); - if (j >= N.day) i[sb](j >= N.month ? 1 : k * Y(i[db]() / k)); - j >= N.month && (i[Hb](j >= N.year ? 0 : k * Y(i[jb]() / k)), h = i[kb]()); - j >= N.year && (h -= h % k, i[Ib](h)); - if (j === N.week) i[sb](i[db]() - i[Gb]() + q(d, 1)); - b = 1; - if (Bb || hb) i = i.getTime(), i = new ea(i + gb(i)); - h = i[kb](); - for (var d = i.getTime(), l = i[jb](), m = i[db](), n = !g || !!hb, p = (N.day + (g ? gb(i) : i.getTimezoneOffset() * 6E4)) % N.day; d < c;) e.push(d), j === N.year ? d = rb(h + b * k, 0) : j === N.month ? d = rb(h, l + b * k) : n && (j === N.day || j === N.week) ? d = rb(h, l, m + b * k * (j === - N.day ? 1 : 7)) : d += j * k, b++; - e.push(d); - o(Ha(e, function(a) { - return j <= N.hour && a % N.day === p }), function(a) { f[a] = "day" }) - } - e.info = v(a, { higherRanks: f, totalRange: j * k }); - return e - }; - J.prototype.normalizeTimeTickInterval = function(a, b) { - var c = b || [ - ["millisecond", [1, 2, 5, 10, 20, 25, 50, 100, 200, 500]], - ["second", [1, 2, 5, 10, 15, 30]], - ["minute", [1, 2, 5, 10, 15, 30]], - ["hour", [1, 2, 3, 4, 6, 8, 12]], - ["day", [1, 2]], - ["week", [1, 2]], - ["month", [1, 2, 3, 4, 6]], - ["year", null] - ], - d = c[c.length - 1], - e = N[d[0]], - f = d[1], - g; - for (g = 0; g < c.length; g++) - if (d = c[g], e = N[d[0]], f = d[1], - c[g + 1] && a <= (e * f[f.length - 1] + N[c[g + 1][0]]) / 2) break; - e === N.year && a < 5 * e && (f = [1, 2, 5]); - c = Db(a / e, f, d[0] === "year" ? y(Cb(a / e), 1) : 1); - return { unitRange: e, count: c, unitName: d[0] } - }; - J.prototype.getLogTickPositions = function(a, b, c, d) { - var e = this.options, - f = this.len, - g = this.lin2log, - h = this.log2lin, - i = []; - if (!d) this._minorAutoInterval = null; - if (a >= 0.5) a = A(a), i = this.getLinearTickPositions(a, b, c); - else if (a >= 0.08) - for (var f = Y(b), j, k, l, m, n, e = a > 0.3 ? [1, 2, 4] : a > 0.15 ? [1, 2, 4, 6, 8] : [1, 2, 3, 4, 5, 6, 7, 8, 9]; f < c + 1 && !n; f++) { - k = e.length; - for (j = 0; j < - k && !n; j++) l = h(g(f) * e[j]), l > b && (!d || m <= c) && m !== x && i.push(m), m > c && (n = !0), m = l - } else if (b = g(b), c = g(c), a = e[d ? "minorTickInterval" : "tickInterval"], a = q(a === "auto" ? null : a, this._minorAutoInterval, (c - b) * (e.tickPixelInterval / (d ? 5 : 1)) / ((d ? f / this.tickPositions.length : f) || 1)), a = Db(a, null, Cb(a)), i = wa(this.getLinearTickPositions(a, b, c), h), !d) this._minorAutoInterval = a / 5; - if (!d) this.tickInterval = a; - return i - }; - J.prototype.log2lin = function(a) { - return aa.log(a) / aa.LN10 }; - J.prototype.lin2log = function(a) { - return aa.pow(10, a) }; - var Nb = B.Tooltip = function() { this.init.apply(this, arguments) }; - Nb.prototype = { - init: function(a, b) { - var c = b.borderWidth, - d = b.style, - e = H(d.padding); - this.chart = a; - this.options = b; - this.crosshairs = []; - this.now = { x: 0, y: 0 }; - this.isHidden = !0; - this.label = a.renderer.label("", 0, 0, b.shape || "callout", null, null, b.useHTML, null, "tooltip").attr({ padding: e, fill: b.backgroundColor, "stroke-width": c, r: b.borderRadius, zIndex: 8 }).css(d).css({ padding: 0 }).add().attr({ y: -9E9 }); - ua || this.label.shadow(b.shadow); - this.shared = b.shared }, - destroy: function() { - if (this.label) this.label = - this.label.destroy(); - clearTimeout(this.hideTimer); - clearTimeout(this.tooltipTimeout) - }, - move: function(a, b, c, d) { - var e = this, - f = e.now, - g = e.options.animation !== !1 && !e.isHidden && (T(a - f.x) > 1 || T(b - f.y) > 1), - h = e.followPointer || e.len > 1; - v(f, { x: g ? (2 * f.x + a) / 3 : a, y: g ? (f.y + b) / 2 : b, anchorX: h ? x : g ? (2 * f.anchorX + c) / 3 : c, anchorY: h ? x : g ? (f.anchorY + d) / 2 : d }); - e.label.attr(f); - if (g) clearTimeout(this.tooltipTimeout), this.tooltipTimeout = setTimeout(function() { e && e.move(a, b, c, d) }, 32) }, - hide: function(a) { - var b = this; - clearTimeout(this.hideTimer); - a = q(a, this.options.hideDelay, 500); - if (!this.isHidden) this.hideTimer = bb(function() { b.label[a ? "fadeOut" : "hide"](); - b.isHidden = !0 }, a) - }, - getAnchor: function(a, b) { - var c, d = this.chart, - e = d.inverted, - f = d.plotTop, - g = d.plotLeft, - h = 0, - i = 0, - j, k, a = sa(a); - c = a[0].tooltipPos; - this.followPointer && b && (b.chartX === x && (b = d.pointer.normalize(b)), c = [b.chartX - d.plotLeft, b.chartY - f]); - c || (o(a, function(a) { j = a.series.yAxis; - k = a.series.xAxis; - h += a.plotX + (!e && k ? k.left - g : 0); - i += (a.plotLow ? (a.plotLow + a.plotHigh) / 2 : a.plotY) + (!e && j ? j.top - f : 0) }), - h /= a.length, i /= a.length, c = [e ? d.plotWidth - i : h, this.shared && !e && a.length > 1 && b ? b.chartY - f : e ? d.plotHeight - h : i]); - return wa(c, A) - }, - getPosition: function(a, b, c) { - var d = this.chart, - e = this.distance, - f = {}, - g = c.h || 0, - h, i = ["y", d.chartHeight, b, c.plotY + d.plotTop, d.plotTop, d.plotTop + d.plotHeight], - j = ["x", d.chartWidth, a, c.plotX + d.plotLeft, d.plotLeft, d.plotLeft + d.plotWidth], - k = !this.followPointer && q(c.ttBelow, !d.inverted === !!c.negative), - l = function(a, b, c, d, h, i) { - var j = c < d - e, - m = d + e + c < b, - l = d - e - c; - d += e; - if (k && m) f[a] = d; - else if (!k && - j) f[a] = l; - else if (j) f[a] = E(i - c, l - g < 0 ? l : l - g); - else if (m) f[a] = y(h, d + g + c > b ? d : d + g); - else return !1 - }, - m = function(a, b, c, d) { - var g; - d < e || d > b - e ? g = !1 : f[a] = d < c / 2 ? 1 : d > b - c / 2 ? b - c - 2 : d - c / 2; - return g }, - n = function(a) { - var b = i; - i = j; - j = b; - h = a }, - p = function() { l.apply(0, i) !== !1 ? m.apply(0, j) === !1 && !h && (n(!0), p()) : h ? f.x = f.y = 0 : (n(!0), p()) }; - (d.inverted || this.len > 1) && n(); - p(); - return f - }, - defaultFormatter: function(a) { - var b = this.points || sa(this), - c; - c = [a.tooltipFooterHeaderFormatter(b[0])]; - c = c.concat(a.bodyFormatter(b)); - c.push(a.tooltipFooterHeaderFormatter(b[0], !0)); - return c.join("") - }, - refresh: function(a, b) { - var c = this.chart, - d = this.label, - e = this.options, - f, g, h, i = {}, - j, k = []; - j = e.formatter || this.defaultFormatter; - var i = c.hoverPoints, - l, m = this.shared; - clearTimeout(this.hideTimer); - this.followPointer = sa(a)[0].series.tooltipOptions.followPointer; - h = this.getAnchor(a, b); - f = h[0]; - g = h[1]; - m && (!a.series || !a.series.noSharedTooltip) ? (c.hoverPoints = a, i && o(i, function(a) { a.setState() }), o(a, function(a) { a.setState("hover"); - k.push(a.getLabelConfig()) }), i = { x: a[0].category, y: a[0].y }, i.points = - k, this.len = k.length, a = a[0]) : i = a.getLabelConfig(); - j = j.call(i, this); - i = a.series; - this.distance = q(i.tooltipOptions.distance, 16); - j === !1 ? this.hide() : (this.isHidden && (Qa(d), d.attr("opacity", 1).show()), d.attr({ text: j }), l = e.borderColor || a.color || i.color || "#606060", d.attr({ stroke: l }), this.updatePosition({ plotX: f, plotY: g, negative: a.negative, ttBelow: a.ttBelow, h: h[2] || 0 }), this.isHidden = !1); - K(c, "tooltipRefresh", { text: j, x: f + c.plotLeft, y: g + c.plotTop, borderColor: l }) - }, - updatePosition: function(a) { - var b = this.chart, - c = this.label, - c = (this.options.positioner || this.getPosition).call(this, c.width, c.height, a); - this.move(A(c.x), A(c.y || 0), a.plotX + b.plotLeft, a.plotY + b.plotTop) - }, - getXDateFormat: function(a, b, c) { - var d, b = b.dateTimeLabelFormats, - e = c && c.closestPointRange, - f, g = { millisecond: 15, second: 12, minute: 9, hour: 6, day: 3 }, - h, i = "millisecond"; - if (e) { - h = pa("%m-%d %H:%M:%S.%L", a.x); - for (f in N) { - if (e === N.week && +pa("%w", a.x) === c.options.startOfWeek && h.substr(6) === "00:00:00.000") { f = "week"; - break } - if (N[f] > e) { f = i; - break } - if (g[f] && h.substr(g[f]) !== "01-01 00:00:00.000".substr(g[f])) break; - f !== "week" && (i = f) - } - f && (d = b[f]) - } else d = b.day; - return d || b.year - }, - tooltipFooterHeaderFormatter: function(a, b) { - var c = b ? "footer" : "header", - d = a.series, - e = d.tooltipOptions, - f = e.xDateFormat, - g = d.xAxis, - h = g && g.options.type === "datetime" && z(a.key), - c = e[c + "Format"]; - h && !f && (f = this.getXDateFormat(a, e, g)); - h && f && (c = c.replace("{point.key}", "{point.key:" + f + "}")); - return Ma(c, { point: a, series: d }) }, - bodyFormatter: function(a) { - return wa(a, function(a) { - var c = a.series.tooltipOptions; - return (c.pointFormatter || a.point.tooltipFormatter).call(a.point, - c.pointFormat) - }) - } - }; - var ra; - $a = C && C.documentElement.ontouchstart !== x; - var ab = B.Pointer = function(a, b) { this.init(a, b) }; - ab.prototype = { - init: function(a, b) { - var c = b.chart, - d = c.events, - e = ua ? "" : c.zoomType, - c = a.inverted, - f; - this.options = b; - this.chart = a; - this.zoomX = f = /x/.test(e); - this.zoomY = e = /y/.test(e); - this.zoomHor = f && !c || e && c; - this.zoomVert = e && !c || f && c; - this.hasZoom = f || e; - this.runChartClick = d && !!d.click; - this.pinchDown = []; - this.lastValidTouch = {}; - if (B.Tooltip && b.tooltip.enabled) a.tooltip = new Nb(a, b.tooltip), this.followTouchMove = - q(b.tooltip.followTouchMove, !0); - this.setDOMEvents() - }, - normalize: function(a, b) { - var c, d, a = a || M.event; - if (!a.target) a.target = a.srcElement; - d = a.touches ? a.touches.length ? a.touches.item(0) : a.changedTouches[0] : a; - if (!b) this.chartPosition = b = Mb(this.chart.container); - d.pageX === x ? (c = y(a.x, a.clientX - b.left), d = a.y) : (c = d.pageX - b.left, d = d.pageY - b.top); - return v(a, { chartX: A(c), chartY: A(d) }) }, - getCoordinates: function(a) { - var b = { xAxis: [], yAxis: [] }; - o(this.chart.axes, function(c) { - b[c.isXAxis ? "xAxis" : "yAxis"].push({ - axis: c, - value: c.toValue(a[c.horiz ? - "chartX" : "chartY"]) - }) - }); - return b - }, - runPointActions: function(a) { - var b = this.chart, - c = b.series, - d = b.tooltip, - e = d ? d.shared : !1, - f = b.hoverPoint, - g = b.hoverSeries, - h, i = [Number.MAX_VALUE, Number.MAX_VALUE], - j, k, l = [], - m = [], - n; - if (!e && !g) - for (h = 0; h < c.length; h++) - if (c[h].directTouch || !c[h].options.stickyTracking) c = []; - g && (e ? g.noSharedTooltip : g.directTouch) && f ? m = [f] : (o(c, function(b) { - j = b.noSharedTooltip && e; - k = !e && b.directTouch; - b.visible && !j && !k && q(b.options.enableMouseTracking, !0) && (n = b.searchPoint(a, !j && b.kdDimensions === 1)) && - n.series && l.push(n) - }), o(l, function(a) { a && o(["dist", "distX"], function(b, c) { - if (z(a[b])) { - var d = a[b] === i[c] && a.series.group.zIndex >= m[c].series.group.zIndex; - if (a[b] < i[c] || d) i[c] = a[b], m[c] = a } }) })); - if (e) - for (h = l.length; h--;)(l[h].clientX !== m[1].clientX || l[h].series.noSharedTooltip) && l.splice(h, 1); - if (m[0] && (m[0] !== this.prevKDPoint || d && d.isHidden)) - if (e && !m[0].series.noSharedTooltip) l.length && d && d.refresh(l, a), o(l, function(b) { b.onMouseOver(a, b !== (g && g.directTouch && f || m[0])) }), this.prevKDPoint = m[1]; - else { - d && - d.refresh(m[0], a); - if (!g || !g.directTouch) m[0].onMouseOver(a); - this.prevKDPoint = m[0] - } - else c = g && g.tooltipOptions.followPointer, d && c && !d.isHidden && (c = d.getAnchor([{}], a), d.updatePosition({ plotX: c[0], plotY: c[1] })); - if (!this._onDocumentMouseMove) this._onDocumentMouseMove = function(a) { - if (ca[ra]) ca[ra].pointer.onDocumentMouseMove(a) }, G(C, "mousemove", this._onDocumentMouseMove); - o(e ? l : [q(f, m[1])], function(c) { o(b.axes, function(b) { - (!c || c.series[b.coll] === b) && b.drawCrosshair(a, c) }) }) - }, - reset: function(a, b) { - var c = this.chart, - d = c.hoverSeries, - e = c.hoverPoint, - f = c.hoverPoints, - g = c.tooltip, - h = g && g.shared ? f : e; - a && h && o(sa(h), function(b) { b.series.isCartesian && b.plotX === void 0 && (a = !1) }); - if (a) g && h && (g.refresh(h), e && (e.setState(e.state, !0), o(c.axes, function(a) { a.crosshair && a.drawCrosshair(null, e) }))); - else { - if (e) e.onMouseOut(); - f && o(f, function(a) { a.setState() }); - if (d) d.onMouseOut(); - g && g.hide(b); - if (this._onDocumentMouseMove) U(C, "mousemove", this._onDocumentMouseMove), this._onDocumentMouseMove = null; - o(c.axes, function(a) { a.hideCrosshair() }); - this.hoverX = this.prevKDPoint = c.hoverPoints = c.hoverPoint = null - } - }, - scaleGroups: function(a, b) { - var c = this.chart, - d; - o(c.series, function(e) { d = a || e.getPlotBox(); - e.xAxis && e.xAxis.zoomEnabled && (e.group.attr(d), e.markerGroup && (e.markerGroup.attr(d), e.markerGroup.clip(b ? c.clipRect : null)), e.dataLabelsGroup && e.dataLabelsGroup.attr(d)) }); - c.clipRect.attr(b || c.clipBox) }, - dragStart: function(a) { - var b = this.chart; - b.mouseIsDown = a.type; - b.cancelClick = !1; - b.mouseDownX = this.mouseDownX = a.chartX; - b.mouseDownY = this.mouseDownY = a.chartY }, - drag: function(a) { - var b = this.chart, - c = b.options.chart, - d = a.chartX, - e = a.chartY, - f = this.zoomHor, - g = this.zoomVert, - h = b.plotLeft, - i = b.plotTop, - j = b.plotWidth, - k = b.plotHeight, - l, m = this.selectionMarker, - n = this.mouseDownX, - p = this.mouseDownY, - r = c.panKey && a[c.panKey + "Key"]; - if (!m || !m.touch) - if (d < h ? d = h : d > h + j && (d = h + j), e < i ? e = i : e > i + k && (e = i + k), this.hasDragged = Math.sqrt(Math.pow(n - d, 2) + Math.pow(p - e, 2)), this.hasDragged > 10) { - l = b.isInsidePlot(n - h, p - i); - if (b.hasCartesianSeries && (this.zoomX || this.zoomY) && l && !r && !m) this.selectionMarker = - m = b.renderer.rect(h, i, f ? 1 : j, g ? 1 : k, 0).attr({ fill: c.selectionMarkerFill || "rgba(69,114,167,0.25)", zIndex: 7 }).add(); - m && f && (d -= n, m.attr({ width: T(d), x: (d > 0 ? 0 : d) + n })); - m && g && (d = e - p, m.attr({ height: T(d), y: (d > 0 ? 0 : d) + p })); - l && !m && c.panning && b.pan(a, c.panning) - } - }, - drop: function(a) { - var b = this, - c = this.chart, - d = this.hasPinched; - if (this.selectionMarker) { - var e = { originalEvent: a, xAxis: [], yAxis: [] }, - f = this.selectionMarker, - g = f.attr ? f.attr("x") : f.x, - h = f.attr ? f.attr("y") : f.y, - i = f.attr ? f.attr("width") : f.width, - j = f.attr ? f.attr("height") : - f.height, - k; - if (this.hasDragged || d) o(c.axes, function(c) { - if (c.zoomEnabled && t(c.min) && (d || b[{ xAxis: "zoomX", yAxis: "zoomY" }[c.coll]])) { - var f = c.horiz, - n = a.type === "touchend" ? c.minPixelPadding : 0, - p = c.toValue((f ? g : h) + n), - f = c.toValue((f ? g + i : h + j) - n); - e[c.coll].push({ axis: c, min: E(p, f), max: y(p, f) }); - k = !0 } }), k && K(c, "selection", e, function(a) { c.zoom(v(a, d ? { animation: !1 } : null)) }); - this.selectionMarker = this.selectionMarker.destroy(); - d && this.scaleGroups() - } - if (c) O(c.container, { cursor: c._cursor }), c.cancelClick = this.hasDragged > - 10, c.mouseIsDown = this.hasDragged = this.hasPinched = !1, this.pinchDown = [] - }, - onContainerMouseDown: function(a) { a = this.normalize(a); - a.preventDefault && a.preventDefault(); - this.dragStart(a) }, - onDocumentMouseUp: function(a) { ca[ra] && ca[ra].pointer.drop(a) }, - onDocumentMouseMove: function(a) { - var b = this.chart, - c = this.chartPosition, - a = this.normalize(a, c); - c && !this.inClass(a.target, "highcharts-tracker") && !b.isInsidePlot(a.chartX - b.plotLeft, a.chartY - b.plotTop) && this.reset() }, - onContainerMouseLeave: function(a) { - var b = ca[ra]; - if (b && (a.relatedTarget || a.toElement)) b.pointer.reset(), b.pointer.chartPosition = null - }, - onContainerMouseMove: function(a) { - var b = this.chart; - if (!t(ra) || !ca[ra] || !ca[ra].mouseIsDown) ra = b.index; - a = this.normalize(a); - a.returnValue = !1; - b.mouseIsDown === "mousedown" && this.drag(a); - (this.inClass(a.target, "highcharts-tracker") || b.isInsidePlot(a.chartX - b.plotLeft, a.chartY - b.plotTop)) && !b.openMenu && this.runPointActions(a) }, - inClass: function(a, b) { - for (var c; a;) { - if (c = $(a, "class")) { - if (c.indexOf(b) !== -1) return !0; - if (c.indexOf("highcharts-container") !== - -1) return !1 - } - a = a.parentNode - } - }, - onTrackerMouseOut: function(a) { - var b = this.chart.hoverSeries, - a = a.relatedTarget || a.toElement; - if (b && a && !b.options.stickyTracking && !this.inClass(a, "highcharts-tooltip") && !this.inClass(a, "highcharts-series-" + b.index)) b.onMouseOut() }, - onContainerClick: function(a) { - var b = this.chart, - c = b.hoverPoint, - d = b.plotLeft, - e = b.plotTop, - a = this.normalize(a); - b.cancelClick || (c && this.inClass(a.target, "highcharts-tracker") ? (K(c.series, "click", v(a, { point: c })), b.hoverPoint && c.firePointEvent("click", a)) : - (v(a, this.getCoordinates(a)), b.isInsidePlot(a.chartX - d, a.chartY - e) && K(b, "click", a))) - }, - setDOMEvents: function() { - var a = this, - b = a.chart.container; - b.onmousedown = function(b) { a.onContainerMouseDown(b) }; - b.onmousemove = function(b) { a.onContainerMouseMove(b) }; - b.onclick = function(b) { a.onContainerClick(b) }; - G(b, "mouseleave", a.onContainerMouseLeave); - mb === 1 && G(C, "mouseup", a.onDocumentMouseUp); - if ($a) b.ontouchstart = function(b) { a.onContainerTouchStart(b) }, b.ontouchmove = function(b) { a.onContainerTouchMove(b) }, mb === 1 && G(C, - "touchend", a.onDocumentTouchEnd) - }, - destroy: function() { - var a; - U(this.chart.container, "mouseleave", this.onContainerMouseLeave); - mb || (U(C, "mouseup", this.onDocumentMouseUp), U(C, "touchend", this.onDocumentTouchEnd)); - clearInterval(this.tooltipTimeout); - for (a in this) this[a] = null } - }; - v(B.Pointer.prototype, { - pinchTranslate: function(a, b, c, d, e, f) { - (this.zoomHor || this.pinchHor) && this.pinchTranslateDirection(!0, a, b, c, d, e, f); - (this.zoomVert || this.pinchVert) && this.pinchTranslateDirection(!1, a, b, c, d, e, f) }, - pinchTranslateDirection: function(a, - b, c, d, e, f, g, h) { - var i = this.chart, - j = a ? "x" : "y", - k = a ? "X" : "Y", - l = "chart" + k, - m = a ? "width" : "height", - n = i["plot" + (a ? "Left" : "Top")], - p, r, s = h || 1, - q = i.inverted, - o = i.bounds[a ? "h" : "v"], - w = b.length === 1, - F = b[0][l], - L = c[0][l], - t = !w && b[1][l], - y = !w && c[1][l], - x, c = function() {!w && T(F - t) > 20 && (s = h || T(L - y) / T(F - t)); - r = (n - L) / s + F; - p = i["plot" + (a ? "Width" : "Height")] / s }; - c(); - b = r; - b < o.min ? (b = o.min, x = !0) : b + p > o.max && (b = o.max - p, x = !0); - x ? (L -= 0.8 * (L - g[j][0]), w || (y -= 0.8 * (y - g[j][1])), c()) : g[j] = [L, y]; - q || (f[j] = r - n, f[m] = p); - f = q ? 1 / s : s; - e[m] = p; - e[j] = b; - d[q ? a ? "scaleY" : - "scaleX" : "scale" + k] = s; - d["translate" + k] = f * n + (L - f * F) - }, - pinch: function(a) { - var b = this, - c = b.chart, - d = b.pinchDown, - e = a.touches, - f = e.length, - g = b.lastValidTouch, - h = b.hasZoom, - i = b.selectionMarker, - j = {}, - k = f === 1 && (b.inClass(a.target, "highcharts-tracker") && c.runTrackerClick || b.runChartClick), - l = {}; - if (f > 1) b.initiated = !0; - h && b.initiated && !k && a.preventDefault(); - wa(e, function(a) { - return b.normalize(a) }); - if (a.type === "touchstart") o(e, function(a, b) { d[b] = { chartX: a.chartX, chartY: a.chartY } }), g.x = [d[0].chartX, d[1] && d[1].chartX], g.y = [d[0].chartY, d[1] && d[1].chartY], o(c.axes, function(a) { - if (a.zoomEnabled) { - var b = c.bounds[a.horiz ? "h" : "v"], - d = a.minPixelPadding, - e = a.toPixels(q(a.options.min, a.dataMin)), - f = a.toPixels(q(a.options.max, a.dataMax)), - g = E(e, f), - e = y(e, f); - b.min = E(a.pos, g - d); - b.max = y(a.pos + a.len, e + d) } }), b.res = !0; - else if (d.length) { - if (!i) b.selectionMarker = i = v({ destroy: va, touch: !0 }, c.plotBox); - b.pinchTranslate(d, e, j, i, l, g); - b.hasPinched = h; - b.scaleGroups(j, l); - if (!h && b.followTouchMove && f === 1) this.runPointActions(b.normalize(a)); - else if (b.res) b.res = !1, this.reset(!1, 0) - } - }, - touch: function(a, b) { - var c = this.chart, - d; - ra = c.index; - if (a.touches.length === 1) - if (a = this.normalize(a), c.isInsidePlot(a.chartX - c.plotLeft, a.chartY - c.plotTop) && !c.openMenu) { b && this.runPointActions(a); - if (a.type === "touchmove") c = this.pinchDown, d = c[0] ? Math.sqrt(Math.pow(c[0].chartX - a.chartX, 2) + Math.pow(c[0].chartY - a.chartY, 2)) >= 4 : !1; - q(d, !0) && this.pinch(a) } else b && this.reset(); - else a.touches.length === 2 && this.pinch(a) }, - onContainerTouchStart: function(a) { this.touch(a, !0) }, - onContainerTouchMove: function(a) { this.touch(a) }, - onDocumentTouchEnd: function(a) { ca[ra] && ca[ra].pointer.drop(a) } - }); - if (M.PointerEvent || M.MSPointerEvent) { - var Ia = {}, - Ob = !!M.PointerEvent, - dc = function() { - var a, b = []; - b.item = function(a) { - return this[a] }; - for (a in Ia) Ia.hasOwnProperty(a) && b.push({ pageX: Ia[a].pageX, pageY: Ia[a].pageY, target: Ia[a].target }); - return b }, - Pb = function(a, b, c, d) { - if ((a.pointerType === "touch" || a.pointerType === a.MSPOINTER_TYPE_TOUCH) && ca[ra]) d(a), d = ca[ra].pointer, d[b]({ type: c, target: a.currentTarget, preventDefault: va, touches: dc() }) }; - v(ab.prototype, { - onContainerPointerDown: function(a) { Pb(a, "onContainerTouchStart", "touchstart", function(a) { Ia[a.pointerId] = { pageX: a.pageX, pageY: a.pageY, target: a.currentTarget } }) }, - onContainerPointerMove: function(a) { Pb(a, "onContainerTouchMove", "touchmove", function(a) { Ia[a.pointerId] = { pageX: a.pageX, pageY: a.pageY }; - if (!Ia[a.pointerId].target) Ia[a.pointerId].target = a.currentTarget }) }, - onDocumentPointerUp: function(a) { Pb(a, "onDocumentTouchEnd", "touchend", function(a) { delete Ia[a.pointerId] }) }, - batchMSEvents: function(a) { - a(this.chart.container, - Ob ? "pointerdown" : "MSPointerDown", this.onContainerPointerDown); - a(this.chart.container, Ob ? "pointermove" : "MSPointerMove", this.onContainerPointerMove); - a(C, Ob ? "pointerup" : "MSPointerUp", this.onDocumentPointerUp) - } - }); - S(ab.prototype, "init", function(a, b, c) { a.call(this, b, c); - this.hasZoom && O(b.container, { "-ms-touch-action": "none", "touch-action": "none" }) }); - S(ab.prototype, "setDOMEvents", function(a) { a.apply(this); - (this.hasZoom || this.followTouchMove) && this.batchMSEvents(G) }); - S(ab.prototype, "destroy", function(a) { - this.batchMSEvents(U); - a.call(this) - }) - } - var xb = B.Legend = function(a, b) { this.init(a, b) }; - xb.prototype = { - init: function(a, b) { - var c = this, - d = b.itemStyle, - e = b.itemMarginTop || 0; - this.options = b; - if (b.enabled) c.itemStyle = d, c.itemHiddenStyle = D(d, b.itemHiddenStyle), c.itemMarginTop = e, c.padding = d = q(b.padding, 8), c.initialItemX = d, c.initialItemY = d - 5, c.maxItemWidth = 0, c.chart = a, c.itemHeight = 0, c.symbolWidth = q(b.symbolWidth, 16), c.pages = [], c.render(), G(c.chart, "endResize", function() { c.positionCheckboxes() }) }, - colorizeItem: function(a, b) { - var c = this.options, - d = a.legendItem, - e = a.legendLine, - f = a.legendSymbol, - g = this.itemHiddenStyle.color, - c = b ? c.itemStyle.color : g, - h = b ? a.legendColor || a.color || "#CCC" : g, - g = a.options && a.options.marker, - i = { fill: h }, - j; - d && d.css({ fill: c, color: c }); - e && e.attr({ stroke: h }); - if (f) { - if (g && f.isMarker) - for (j in i.stroke = h, g = a.convertAttribs(g), g) d = g[j], d !== x && (i[j] = d); - f.attr(i) } - }, - positionItem: function(a) { - var b = this.options, - c = b.symbolPadding, - b = !b.rtl, - d = a._legendItemPos, - e = d[0], - d = d[1], - f = a.checkbox; - (a = a.legendGroup) && a.element && a.translate(b ? e : this.legendWidth - - e - 2 * c - 4, d); - if (f) f.x = e, f.y = d - }, - destroyItem: function(a) { - var b = a.checkbox; - o(["legendItem", "legendLine", "legendSymbol", "legendGroup"], function(b) { a[b] && (a[b] = a[b].destroy()) }); - b && Wa(a.checkbox) }, - destroy: function() { - var a = this.group, - b = this.box; - if (b) this.box = b.destroy(); - if (a) this.group = a.destroy() }, - positionCheckboxes: function(a) { - var b = this.group.alignAttr, - c, d = this.clipHeight || this.legendHeight, - e = this.titleHeight; - if (b) c = b.translateY, o(this.allItems, function(f) { - var g = f.checkbox, - h; - g && (h = c + e + g.y + (a || 0) + 3, O(g, { left: b.translateX + f.checkboxOffset + g.x - 20 + "px", top: h + "px", display: h > c - 6 && h < c + d - 6 ? "" : "none" })) - }) - }, - renderTitle: function() { - var a = this.padding, - b = this.options.title, - c = 0; - if (b.text) { - if (!this.title) this.title = this.chart.renderer.label(b.text, a - 3, a - 4, null, null, null, null, null, "legend-title").attr({ zIndex: 1 }).css(b.style).add(this.group); - a = this.title.getBBox(); - c = a.height; - this.offsetWidth = a.width; - this.contentGroup.attr({ translateY: c }) } - this.titleHeight = c }, - setText: function(a) { - var b = this.options; - a.legendItem.attr({ - text: b.labelFormat ? - Ma(b.labelFormat, a) : b.labelFormatter.call(a) - }) - }, - renderItem: function(a) { - var b = this.chart, - c = b.renderer, - d = this.options, - e = d.layout === "horizontal", - f = this.symbolWidth, - g = d.symbolPadding, - h = this.itemStyle, - i = this.itemHiddenStyle, - j = this.padding, - k = e ? q(d.itemDistance, 20) : 0, - l = !d.rtl, - m = d.width, - n = d.itemMarginBottom || 0, - p = this.itemMarginTop, - r = this.initialItemX, - s = a.legendItem, - o = a.series && a.series.drawLegendSymbol ? a.series : a, - u = o.options, - u = this.createCheckboxForItem && u && u.showCheckbox, - w = d.useHTML; - if (!s) { - a.legendGroup = - c.g("legend-item").attr({ zIndex: 1 }).add(this.scrollGroup); - a.legendItem = s = c.text("", l ? f + g : -g, this.baseline || 0, w).css(D(a.visible ? h : i)).attr({ align: l ? "left" : "right", zIndex: 2 }).add(a.legendGroup); - if (!this.baseline) this.fontMetrics = c.fontMetrics(h.fontSize, s), this.baseline = this.fontMetrics.f + 3 + p, s.attr("y", this.baseline); - o.drawLegendSymbol(this, a); - this.setItemEvents && this.setItemEvents(a, s, w, h, i); - u && this.createCheckboxForItem(a) - } - this.colorizeItem(a, a.visible); - this.setText(a); - c = s.getBBox(); - f = a.checkboxOffset = - d.itemWidth || a.legendItemWidth || f + g + c.width + k + (u ? 20 : 0); - this.itemHeight = g = A(a.legendItemHeight || c.height); - if (e && this.itemX - r + f > (m || b.chartWidth - 2 * j - r - d.x)) this.itemX = r, this.itemY += p + this.lastLineHeight + n, this.lastLineHeight = 0; - this.maxItemWidth = y(this.maxItemWidth, f); - this.lastItemY = p + this.itemY + n; - this.lastLineHeight = y(g, this.lastLineHeight); - a._legendItemPos = [this.itemX, this.itemY]; - e ? this.itemX += f : (this.itemY += p + g + n, this.lastLineHeight = g); - this.offsetWidth = m || y((e ? this.itemX - r - k : f) + j, this.offsetWidth) - }, - getAllItems: function() { - var a = []; - o(this.chart.series, function(b) { - var c = b.options; - if (q(c.showInLegend, !t(c.linkedTo) ? x : !1, !0)) a = a.concat(b.legendItems || (c.legendType === "point" ? b.data : b)) }); - return a }, - adjustMargins: function(a, b) { - var c = this.chart, - d = this.options, - e = d.align.charAt(0) + d.verticalAlign.charAt(0) + d.layout.charAt(0); - d.floating || o([/(lth|ct|rth)/, /(rtv|rm|rbv)/, /(rbh|cb|lbh)/, /(lbv|lm|ltv)/], function(f, g) { - f.test(e) && !t(a[g]) && (c[wb[g]] = y(c[wb[g]], c.legend[(g + 1) % 2 ? "legendHeight" : "legendWidth"] + [1, -1, -1, 1][g] * d[g % 2 ? "x" : "y"] + q(d.margin, 12) + b[g])) - }) - }, - render: function() { - var a = this, - b = a.chart, - c = b.renderer, - d = a.group, - e, f, g, h, i = a.box, - j = a.options, - k = a.padding, - l = j.borderWidth, - m = j.backgroundColor; - a.itemX = a.initialItemX; - a.itemY = a.initialItemY; - a.offsetWidth = 0; - a.lastItemY = 0; - if (!d) a.group = d = c.g("legend").attr({ zIndex: 7 }).add(), a.contentGroup = c.g().attr({ zIndex: 1 }).add(d), a.scrollGroup = c.g().add(a.contentGroup); - a.renderTitle(); - e = a.getAllItems(); - pb(e, function(a, b) { - return (a.options && a.options.legendIndex || - 0) - (b.options && b.options.legendIndex || 0) - }); - j.reversed && e.reverse(); - a.allItems = e; - a.display = f = !!e.length; - a.lastLineHeight = 0; - o(e, function(b) { a.renderItem(b) }); - g = (j.width || a.offsetWidth) + k; - h = a.lastItemY + a.lastLineHeight + a.titleHeight; - h = a.handleOverflow(h); - h += k; - if (l || m) { - if (i) { - if (g > 0 && h > 0) i[i.isNew ? "attr" : "animate"](i.crisp({ width: g, height: h })), i.isNew = !1 } else a.box = i = c.rect(0, 0, g, h, j.borderRadius, l || 0).attr({ stroke: j.borderColor, "stroke-width": l || 0, fill: m || "none" }).add(d).shadow(j.shadow), i.isNew = !0; - i[f ? - "show" : "hide"]() - } - a.legendWidth = g; - a.legendHeight = h; - o(e, function(b) { a.positionItem(b) }); - f && d.align(v({ width: g, height: h }, j), !0, "spacingBox"); - b.isResizing || this.positionCheckboxes() - }, - handleOverflow: function(a) { - var b = this, - c = this.chart, - d = c.renderer, - e = this.options, - f = e.y, - f = c.spacingBox.height + (e.verticalAlign === "top" ? -f : f) - this.padding, - g = e.maxHeight, - h, i = this.clipRect, - j = e.navigation, - k = q(j.animation, !0), - l = j.arrowSize || 12, - m = this.nav, - n = this.pages, - p = this.padding, - r, s = this.allItems, - Z = function(a) { - i.attr({ height: a }); - if (b.contentGroup.div) b.contentGroup.div.style.clip = "rect(" + p + "px,9999px," + (p + a) + "px,0)" - }; - e.layout === "horizontal" && (f /= 2); - g && (f = E(f, g)); - n.length = 0; - if (a > f && j.enabled !== !1) { - this.clipHeight = h = y(f - 20 - this.titleHeight - p, 0); - this.currentPage = q(this.currentPage, 1); - this.fullHeight = a; - o(s, function(a, b) { - var c = a._legendItemPos[1], - d = A(a.legendItem.getBBox().height), - e = n.length; - if (!e || c - n[e - 1] > h && (r || c) !== n[e - 1]) n.push(r || c), e++; - b === s.length - 1 && c + d - n[e - 1] > h && n.push(c); - c !== r && (r = c) }); - if (!i) i = b.clipRect = d.clipRect(0, - p, 9999, 0), b.contentGroup.clip(i); - Z(h); - if (!m) this.nav = m = d.g().attr({ zIndex: 1 }).add(this.group), this.up = d.symbol("triangle", 0, 0, l, l).on("click", function() { b.scroll(-1, k) }).add(m), this.pager = d.text("", 15, 10).css(j.style).add(m), this.down = d.symbol("triangle-down", 0, 0, l, l).on("click", function() { b.scroll(1, k) }).add(m); - b.scroll(0); - a = f - } else if (m) Z(c.chartHeight), m.hide(), this.scrollGroup.attr({ translateY: 1 }), this.clipHeight = 0; - return a - }, - scroll: function(a, b) { - var c = this.pages, - d = c.length, - e = this.currentPage + a, - f = this.clipHeight, - g = this.options.navigation, - h = g.activeColor, - g = g.inactiveColor, - i = this.pager, - j = this.padding; - e > d && (e = d); - if (e > 0) b !== x && cb(b, this.chart), this.nav.attr({ translateX: j, translateY: f + this.padding + 7 + this.titleHeight, visibility: "visible" }), this.up.attr({ fill: e === 1 ? g : h }).css({ cursor: e === 1 ? "default" : "pointer" }), i.attr({ text: e + "/" + d }), this.down.attr({ x: 18 + this.pager.getBBox().width, fill: e === d ? g : h }).css({ cursor: e === d ? "default" : "pointer" }), c = -c[e - 1] + this.initialItemY, this.scrollGroup.animate({ translateY: c }), - this.currentPage = e, this.positionCheckboxes(c) - } - }; - da = B.LegendSymbolMixin = { - drawRectangle: function(a, b) { - var c = a.options.symbolHeight || a.fontMetrics.f; - b.legendSymbol = this.chart.renderer.rect(0, a.baseline - c + 1, a.symbolWidth, c, a.options.symbolRadius || 0).attr({ zIndex: 3 }).add(b.legendGroup) }, - drawLineMarker: function(a) { - var b = this.options, - c = b.marker, - d = a.symbolWidth, - e = this.chart.renderer, - f = this.legendGroup, - a = a.baseline - A(a.fontMetrics.b * 0.3), - g; - if (b.lineWidth) { - g = { "stroke-width": b.lineWidth }; - if (b.dashStyle) g.dashstyle = - b.dashStyle; - this.legendLine = e.path([W, 0, a, R, d, a]).attr(g).add(f) - } - if (c && c.enabled !== !1) b = c.radius, this.legendSymbol = c = e.symbol(this.symbol, d / 2 - b, a - b, 2 * b, 2 * b, c).add(f), c.isMarker = !0 - } - }; - (/Trident\/7\.0/.test(Pa) || Ya) && S(xb.prototype, "positionItem", function(a, b) { - var c = this, - d = function() { b._legendItemPos && a.call(c, b) }; - d(); - setTimeout(d) }); - var Da = B.Chart = function() { this.getArgs.apply(this, arguments) }; - B.chart = function(a, b, c) { - return new Da(a, b, c) }; - Da.prototype = { - callbacks: [], - getArgs: function() { - var a = [].slice.call(arguments); - if (Ea(a[0]) || a[0].nodeName) this.renderTo = a.shift(); - this.init(a[0], a[1]) - }, - init: function(a, b) { - var c, d = a.series; - a.series = null; - c = D(Q, a); - c.series = a.series = d; - this.userOptions = a; - d = c.chart; - this.margin = this.splashArray("margin", d); - this.spacing = this.splashArray("spacing", d); - var e = d.events; - this.bounds = { h: {}, v: {} }; - this.callback = b; - this.isResizing = 0; - this.options = c; - this.axes = []; - this.series = []; - this.hasCartesianSeries = d.showAxes; - var f = this, - g; - f.index = ca.length; - ca.push(f); - mb++; - d.reflow !== !1 && G(f, "load", function() { f.initReflow() }); - if (e) - for (g in e) G(f, g, e[g]); - f.xAxis = []; - f.yAxis = []; - f.animation = ua ? !1 : q(d.animation, !0); - f.pointCount = f.colorCounter = f.symbolCounter = 0; - f.firstRender() - }, - initSeries: function(a) { - var b = this.options.chart; - (b = I[a.type || b.type || b.defaultSeriesType]) || ja(17, !0); - b = new b; - b.init(this, a); - return b }, - isInsidePlot: function(a, b, c) { - var d = c ? b : a, - a = c ? a : b; - return d >= 0 && d <= this.plotWidth && a >= 0 && a <= this.plotHeight }, - redraw: function(a) { - var b = this.axes, - c = this.series, - d = this.pointer, - e = this.legend, - f = this.isDirtyLegend, - g, h, i = this.hasCartesianSeries, - j = this.isDirtyBox, - k = c.length, - l = k, - m = this.renderer, - n = m.isHidden(), - p = []; - cb(a, this); - n && this.cloneRenderTo(); - for (this.layOutTitles(); l--;) - if (a = c[l], a.options.stacking && (g = !0, a.isDirty)) { h = !0; - break } - if (h) - for (l = k; l--;) - if (a = c[l], a.options.stacking) a.isDirty = !0; - o(c, function(a) { a.isDirty && a.options.legendType === "point" && (a.updateTotals && a.updateTotals(), f = !0); - a.isDirtyData && K(a, "updatedData") }); - if (f && e.options.enabled) e.render(), this.isDirtyLegend = !1; - g && this.getStacks(); - if (i && !this.isResizing) this.maxTicks = - null, o(b, function(a) { a.setScale() }); - this.getMargins(); - i && (o(b, function(a) { a.isDirty && (j = !0) }), o(b, function(a) { - var b = a.min + "," + a.max; - if (a.extKey !== b) a.extKey = b, p.push(function() { K(a, "afterSetExtremes", v(a.eventArgs, a.getExtremes())); - delete a.eventArgs }); - (j || g) && a.redraw() })); - j && this.drawChartBox(); - o(c, function(a) { a.isDirty && a.visible && (!a.isCartesian || a.xAxis) && a.redraw() }); - d && d.reset(!0); - m.draw(); - K(this, "redraw"); - n && this.cloneRenderTo(!0); - o(p, function(a) { a.call() }) - }, - get: function(a) { - var b = this.axes, - c = this.series, - d, e; - for (d = 0; d < b.length; d++) - if (b[d].options.id === a) return b[d]; - for (d = 0; d < c.length; d++) - if (c[d].options.id === a) return c[d]; - for (d = 0; d < c.length; d++) { e = c[d].points || []; - for (b = 0; b < e.length; b++) - if (e[b].id === a) return e[b] } - return null - }, - getAxes: function() { - var a = this, - b = this.options, - c = b.xAxis = sa(b.xAxis || {}), - b = b.yAxis = sa(b.yAxis || {}); - o(c, function(a, b) { a.index = b; - a.isX = !0 }); - o(b, function(a, b) { a.index = b }); - c = c.concat(b); - o(c, function(b) { new J(a, b) }) }, - getSelectedPoints: function() { - var a = []; - o(this.series, - function(b) { a = a.concat(Ha(b.points || [], function(a) { - return a.selected })) }); - return a - }, - getSelectedSeries: function() { - return Ha(this.series, function(a) { - return a.selected }) }, - setTitle: function(a, b, c) { - var g; - var d = this, - e = d.options, - f; - f = e.title = D(e.title, a); - g = e.subtitle = D(e.subtitle, b), e = g; - o([ - ["title", a, f], - ["subtitle", b, e] - ], function(a) { - var b = a[0], - c = d[b], - e = a[1], - a = a[2]; - c && e && (d[b] = c = c.destroy()); - a && a.text && !c && (d[b] = d.renderer.text(a.text, 0, 0, a.useHTML).attr({ - align: a.align, - "class": "highcharts-" + b, - zIndex: a.zIndex || - 4 - }).css(a.style).add()) - }); - d.layOutTitles(c) - }, - layOutTitles: function(a) { - var b = 0, - c = this.title, - d = this.subtitle, - e = this.options, - f = e.title, - e = e.subtitle, - g = this.renderer, - h = this.spacingBox; - if (c && (c.css({ width: (f.width || h.width + f.widthAdjust) + "px" }).align(v({ y: g.fontMetrics(f.style.fontSize, c).b - 3 }, f), !1, h), !f.floating && !f.verticalAlign)) b = c.getBBox().height; - d && (d.css({ width: (e.width || h.width + e.widthAdjust) + "px" }).align(v({ y: b + (f.margin - 13) + g.fontMetrics(e.style.fontSize, c).b }, e), !1, h), !e.floating && !e.verticalAlign && - (b = Ga(b + d.getBBox().height))); - c = this.titleOffset !== b; - this.titleOffset = b; - if (!this.isDirtyBox && c) this.isDirtyBox = c, this.hasRendered && q(a, !0) && this.isDirtyBox && this.redraw() - }, - getChartSize: function() { - var a = this.options.chart, - b = a.width, - a = a.height, - c = this.renderToClone || this.renderTo; - if (!t(b)) this.containerWidth = ya(c, "width"); - if (!t(a)) this.containerHeight = ya(c, "height"); - this.chartWidth = y(0, b || this.containerWidth || 600); - this.chartHeight = y(0, q(a, this.containerHeight > 19 ? this.containerHeight : 400)) }, - cloneRenderTo: function(a) { - var b = - this.renderToClone, - c = this.container; - a ? b && (this.renderTo.appendChild(c), Wa(b), delete this.renderToClone) : (c && c.parentNode === this.renderTo && this.renderTo.removeChild(c), this.renderToClone = b = this.renderTo.cloneNode(0), O(b, { position: "absolute", top: "-9999px", display: "block" }), b.style.setProperty && b.style.setProperty("display", "block", "important"), C.body.appendChild(b), c && b.appendChild(c)) - }, - getContainer: function() { - var a, b = this.options, - c = b.chart, - d, e; - a = this.renderTo; - var f = "highcharts-" + Lb++; - if (!a) this.renderTo = - a = c.renderTo; - if (Ea(a)) this.renderTo = a = C.getElementById(a); - a || ja(13, !0); - d = H($(a, "data-highcharts-chart")); - z(d) && ca[d] && ca[d].hasRendered && ca[d].destroy(); - $(a, "data-highcharts-chart", this.index); - a.innerHTML = ""; - !c.skipClone && !a.offsetWidth && this.cloneRenderTo(); - this.getChartSize(); - d = this.chartWidth; - e = this.chartHeight; - this.container = a = ia(Xa, { className: "highcharts-container" + (c.className ? " " + c.className : ""), id: f }, v({ - position: "relative", - overflow: "hidden", - width: d + "px", - height: e + "px", - textAlign: "left", - lineHeight: "normal", - zIndex: 0, - "-webkit-tap-highlight-color": "rgba(0,0,0,0)" - }, c.style), this.renderToClone || a); - this._cursor = a.style.cursor; - this.renderer = new(B[c.renderer] || Za)(a, d, e, c.style, c.forExport, b.exporting && b.exporting.allowHTML); - ua && this.renderer.create(this, a, d, e); - this.renderer.chartIndex = this.index - }, - getMargins: function(a) { - var b = this.spacing, - c = this.margin, - d = this.titleOffset; - this.resetMargins(); - if (d && !t(c[0])) this.plotTop = y(this.plotTop, d + this.options.title.margin + b[0]); - this.legend.display && this.legend.adjustMargins(c, - b); - this.extraBottomMargin && (this.marginBottom += this.extraBottomMargin); - this.extraTopMargin && (this.plotTop += this.extraTopMargin); - a || this.getAxisMargins() - }, - getAxisMargins: function() { - var a = this, - b = a.axisOffset = [0, 0, 0, 0], - c = a.margin; - a.hasCartesianSeries && o(a.axes, function(a) { a.visible && a.getOffset() }); - o(wb, function(d, e) { t(c[e]) || (a[d] += b[e]) }); - a.setChartSize() }, - reflow: function(a) { - var b = this, - c = b.options.chart, - d = b.renderTo, - e = t(c.width), - f = c.width || ya(d, "width"), - c = c.height || ya(d, "height"), - d = a ? a.target : M; - if (!e && - !b.isPrinting && f && c && (d === M || d === C)) { - if (f !== b.containerWidth || c !== b.containerHeight) clearTimeout(b.reflowTimeout), b.reflowTimeout = bb(function() { b.container && b.setSize(void 0, void 0, !1) }, a ? 100 : 0); - b.containerWidth = f; - b.containerHeight = c } - }, - initReflow: function() { - var a = this, - b = function(b) { a.reflow(b) }; - G(M, "resize", b); - G(a, "destroy", function() { U(M, "resize", b) }) }, - setSize: function(a, b, c) { - var d = this, - e = d.renderer; - d.isResizing += 1; - cb(c, d); - d.oldChartHeight = d.chartHeight; - d.oldChartWidth = d.chartWidth; - if (a !== void 0) d.options.chart.width = - a; - if (b !== void 0) d.options.chart.height = b; - d.getChartSize(); - a = e.globalAnimation; - (a ? fb : O)(d.container, { width: d.chartWidth + "px", height: d.chartHeight + "px" }, a); - d.setChartSize(!0); - e.setSize(d.chartWidth, d.chartHeight, c); - d.maxTicks = null; - o(d.axes, function(a) { a.isDirty = !0; - a.setScale() }); - o(d.series, function(a) { a.isDirty = !0 }); - d.isDirtyLegend = !0; - d.isDirtyBox = !0; - d.layOutTitles(); - d.getMargins(); - d.redraw(c); - d.oldChartHeight = null; - K(d, "resize"); - bb(function() { d && K(d, "endResize", null, function() { d.isResizing -= 1 }) }, ib(a).duration) - }, - setChartSize: function(a) { - var b = this.inverted, - c = this.renderer, - d = this.chartWidth, - e = this.chartHeight, - f = this.options.chart, - g = this.spacing, - h = this.clipOffset, - i, j, k, l; - this.plotLeft = i = A(this.plotLeft); - this.plotTop = j = A(this.plotTop); - this.plotWidth = k = y(0, A(d - i - this.marginRight)); - this.plotHeight = l = y(0, A(e - j - this.marginBottom)); - this.plotSizeX = b ? l : k; - this.plotSizeY = b ? k : l; - this.plotBorderWidth = f.plotBorderWidth || 0; - this.spacingBox = c.spacingBox = { x: g[3], y: g[0], width: d - g[3] - g[1], height: e - g[0] - g[2] }; - this.plotBox = c.plotBox = { x: i, y: j, width: k, height: l }; - d = 2 * Y(this.plotBorderWidth / 2); - b = Ga(y(d, h[3]) / 2); - c = Ga(y(d, h[0]) / 2); - this.clipBox = { x: b, y: c, width: Y(this.plotSizeX - y(d, h[1]) / 2 - b), height: y(0, Y(this.plotSizeY - y(d, h[2]) / 2 - c)) }; - a || o(this.axes, function(a) { a.setAxisSize(); - a.setAxisTranslation() }) - }, - resetMargins: function() { - var a = this; - o(wb, function(b, c) { a[b] = q(a.margin[c], a.spacing[c]) }); - a.axisOffset = [0, 0, 0, 0]; - a.clipOffset = [0, 0, 0, 0] }, - drawChartBox: function() { - var a = this.options.chart, - b = this.renderer, - c = this.chartWidth, - d = this.chartHeight, - e = this.chartBackground, - f = this.plotBackground, - g = this.plotBorder, - h = this.plotBGImage, - i = a.borderWidth || 0, - j = a.backgroundColor, - k = a.plotBackgroundColor, - l = a.plotBackgroundImage, - m = a.plotBorderWidth || 0, - n, p = this.plotLeft, - r = this.plotTop, - s = this.plotWidth, - q = this.plotHeight, - o = this.plotBox, - w = this.clipRect, - F = this.clipBox; - n = i + (a.shadow ? 8 : 0); - if (i || j) - if (e) e.animate(e.crisp({ width: c - n, height: d - n })); - else { - e = { fill: j || "none" }; - if (i) e.stroke = a.borderColor, e["stroke-width"] = i; - this.chartBackground = b.rect(n / 2, n / 2, c - n, d - n, a.borderRadius, - i).attr(e).addClass("highcharts-background").add().shadow(a.shadow) - } - if (k) f ? f.animate(o) : this.plotBackground = b.rect(p, r, s, q, 0).attr({ fill: k }).add().shadow(a.plotShadow); - if (l) h ? h.animate(o) : this.plotBGImage = b.image(l, p, r, s, q).add(); - w ? w.animate({ width: F.width, height: F.height }) : this.clipRect = b.clipRect(F); - if (m) g ? (g.strokeWidth = -m, g.animate(g.crisp({ x: p, y: r, width: s, height: q }))) : this.plotBorder = b.rect(p, r, s, q, 0, -m).attr({ stroke: a.plotBorderColor, "stroke-width": m, fill: "none", zIndex: 1 }).add(); - this.isDirtyBox = !1 - }, - propFromSeries: function() { - var a = this, - b = a.options.chart, - c, d = a.options.series, - e, f; - o(["inverted", "angular", "polar"], function(g) { c = I[b.type || b.defaultSeriesType]; - f = a[g] || b[g] || c && c.prototype[g]; - for (e = d && d.length; !f && e--;)(c = I[d[e].type]) && c.prototype[g] && (f = !0); - a[g] = f }) }, - linkSeries: function() { - var a = this, - b = a.series; - o(b, function(a) { a.linkedSeries.length = 0 }); - o(b, function(b) { - var d = b.options.linkedTo; - if (Ea(d) && (d = d === ":previous" ? a.series[b.index - 1] : a.get(d))) d.linkedSeries.push(b), b.linkedParent = d, b.visible = - q(b.options.visible, d.options.visible, b.visible) - }) - }, - renderSeries: function() { o(this.series, function(a) { a.translate(); - a.render() }) }, - renderLabels: function() { - var a = this, - b = a.options.labels; - b.items && o(b.items, function(c) { - var d = v(b.style, c.style), - e = H(d.left) + a.plotLeft, - f = H(d.top) + a.plotTop + 12; - delete d.left; - delete d.top; - a.renderer.text(c.html, e, f).attr({ zIndex: 2 }).css(d).add() }) }, - render: function() { - var a = this.axes, - b = this.renderer, - c = this.options, - d, e, f, g; - this.setTitle(); - this.legend = new xb(this, c.legend); - this.getStacks && - this.getStacks(); - this.getMargins(!0); - this.setChartSize(); - d = this.plotWidth; - e = this.plotHeight -= 21; - o(a, function(a) { a.setScale() }); - this.getAxisMargins(); - f = d / this.plotWidth > 1.1; - g = e / this.plotHeight > 1.05; - if (f || g) this.maxTicks = null, o(a, function(a) { - (a.horiz && f || !a.horiz && g) && a.setTickInterval(!0) }), this.getMargins(); - this.drawChartBox(); - this.hasCartesianSeries && o(a, function(a) { a.visible && a.render() }); - if (!this.seriesGroup) this.seriesGroup = b.g("series-group").attr({ zIndex: 3 }).add(); - this.renderSeries(); - this.renderLabels(); - this.showCredits(c.credits); - this.hasRendered = !0 - }, - showCredits: function(a) { - if (a.enabled && !this.credits) this.credits = this.renderer.text(a.text, 0, 0).on("click", function() { - if (a.href) M.location.href = a.href }).attr({ align: a.position.align, zIndex: 8 }).css(a.style).add().align(a.position) }, - destroy: function() { - var a = this, - b = a.axes, - c = a.series, - d = a.container, - e, f = d && d.parentNode; - K(a, "destroy"); - ca[a.index] = x; - mb--; - a.renderTo.removeAttribute("data-highcharts-chart"); - U(a); - for (e = b.length; e--;) b[e] = b[e].destroy(); - for (e = - c.length; e--;) c[e] = c[e].destroy(); - o("title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer".split(","), function(b) { - var c = a[b]; - c && c.destroy && (a[b] = c.destroy()) }); - if (d) d.innerHTML = "", U(d), f && Wa(d); - for (e in a) delete a[e] - }, - isReadyToRender: function() { - var a = this; - return !ma && M == M.top && C.readyState !== "complete" || ua && !M.canvg ? (ua ? Zb.push(function() { a.firstRender() }, a.options.global.canvasToolsURL) : - C.attachEvent("onreadystatechange", function() { C.detachEvent("onreadystatechange", a.firstRender); - C.readyState === "complete" && a.firstRender() }), !1) : !0 - }, - firstRender: function() { - var a = this, - b = a.options; - if (a.isReadyToRender()) { - a.getContainer(); - K(a, "init"); - a.resetMargins(); - a.setChartSize(); - a.propFromSeries(); - a.getAxes(); - o(b.series || [], function(b) { a.initSeries(b) }); - a.linkSeries(); - K(a, "beforeRender"); - if (B.Pointer) a.pointer = new ab(a, b); - a.render(); - a.renderer.draw(); - if (!a.renderer.imgCount && a.onload) a.onload(); - a.cloneRenderTo(!0) - } - }, - onload: function() { - var a = this; - o([this.callback].concat(this.callbacks), function(b) { b && a.index !== void 0 && b.apply(a, [a]) }); - K(a, "load"); - this.onload = null }, - splashArray: function(a, b) { - var c = b[a], - c = ha(c) ? c : [c, c, c, c]; - return [q(b[a + "Top"], c[0]), q(b[a + "Right"], c[1]), q(b[a + "Bottom"], c[2]), q(b[a + "Left"], c[3])] } - }; - var ec = B.CenteredSeriesMixin = { - getCenter: function() { - var a = this.options, - b = this.chart, - c = 2 * (a.slicedOffset || 0), - d = b.plotWidth - 2 * c, - b = b.plotHeight - 2 * c, - e = a.center, - e = [q(e[0], "50%"), q(e[1], "50%"), - a.size || "100%", a.innerSize || 0 - ], - f = E(d, b), - g, h; - for (g = 0; g < 4; ++g) h = e[g], a = g < 2 || g === 2 && /%$/.test(h), e[g] = (/%$/.test(h) ? [d, b, f, e[2]][g] * parseFloat(h) / 100 : parseFloat(h)) + (a ? c : 0); - e[3] > e[2] && (e[3] = e[2]); - return e - } - }, - Ja = function() {}; - Ja.prototype = { - init: function(a, b, c) { - this.series = a; - this.color = a.color; - this.applyOptions(b, c); - this.pointAttr = {}; - if (a.options.colorByPoint && (b = a.options.colors || a.chart.options.colors, this.color = this.color || b[a.colorCounter++], a.colorCounter === b.length)) a.colorCounter = 0; - a.chart.pointCount++; - return this - }, - applyOptions: function(a, b) { - var c = this.series, - d = c.options.pointValKey || c.pointValKey, - a = Ja.prototype.optionsToObject.call(this, a); - v(this, a); - this.options = this.options ? v(this.options, a) : a; - if (d) this.y = this[d]; - this.isNull = this.x === null || !z(this.y, !0); - if (this.x === void 0 && c) this.x = b === void 0 ? c.autoIncrement(this) : b; - if (c.xAxis && c.xAxis.names) c.xAxis.names[this.x] = this.name; - return this }, - optionsToObject: function(a) { - var b = {}, - c = this.series, - d = c.options.keys, - e = d || c.pointArrayMap || ["y"], - f = e.length, - g = - 0, - h = 0; - if (z(a) || a === null) b[e[0]] = a; - else if (Ra(a)) { - if (!d && a.length > f) { c = typeof a[0]; - if (c === "string") b.name = a[0]; - else if (c === "number") b.x = a[0]; - g++ } - for (; h < f;) { - if (!d || a[g] !== void 0) b[e[h]] = a[g]; - g++; - h++ } } else if (typeof a === "object") { b = a; - if (a.dataLabels) c._hasPointLabels = !0; - if (a.marker) c._hasPointMarkers = !0 } - return b - }, - destroy: function() { - var a = this.series.chart, - b = a.hoverPoints, - c; - a.pointCount--; - if (b && (this.setState(), Ba(b, this), !b.length)) a.hoverPoints = null; - if (this === a.hoverPoint) this.onMouseOut(); - if (this.graphic || - this.dataLabel) U(this), this.destroyElements(); - this.legendItem && a.legend.destroyItem(this); - for (c in this) this[c] = null - }, - destroyElements: function() { - for (var a = ["graphic", "dataLabel", "dataLabelUpper", "connector", "shadowGroup"], b, c = 6; c--;) b = a[c], this[b] && (this[b] = this[b].destroy()) }, - getLabelConfig: function() { - return { x: this.category, y: this.y, color: this.color, key: this.name || this.category, series: this.series, point: this, percentage: this.percentage, total: this.total || this.stackTotal } }, - tooltipFormatter: function(a) { - var b = - this.series, - c = b.tooltipOptions, - d = q(c.valueDecimals, ""), - e = c.valuePrefix || "", - f = c.valueSuffix || ""; - o(b.pointArrayMap || ["y"], function(b) { b = "{point." + b; - if (e || f) a = a.replace(b + "}", e + b + "}" + f); - a = a.replace(b + "}", b + ":,." + d + "f}") }); - return Ma(a, { point: this, series: this.series }) - }, - firePointEvent: function(a, b, c) { - var d = this, - e = this.series.options; - (e.point.events[a] || d.options && d.options.events && d.options.events[a]) && this.importEvents(); - a === "click" && e.allowPointSelect && (c = function(a) { - d.select && d.select(null, a.ctrlKey || - a.metaKey || a.shiftKey) - }); - K(this, a, b, c) - }, - visible: !0 - }; - var P = B.Series = function() {}; - P.prototype = { - isCartesian: !0, - type: "line", - pointClass: Ja, - sorted: !0, - requireSorting: !0, - pointAttrToOptions: { stroke: "lineColor", "stroke-width": "lineWidth", fill: "fillColor", r: "radius" }, - directTouch: !1, - axisTypes: ["xAxis", "yAxis"], - colorCounter: 0, - parallelArrays: ["x", "y"], - init: function(a, b) { - var c = this, - d, e, f = a.series, - g = function(a, b) { - return q(a.options.index, a._i) - q(b.options.index, b._i) }; - c.chart = a; - c.options = b = c.setOptions(b); - c.linkedSeries = []; - c.bindAxes(); - v(c, { name: b.name, state: "", pointAttr: {}, visible: b.visible !== !1, selected: b.selected === !0 }); - if (ua) b.animation = !1; - e = b.events; - for (d in e) G(c, d, e[d]); - if (e && e.click || b.point && b.point.events && b.point.events.click || b.allowPointSelect) a.runTrackerClick = !0; - c.getColor(); - c.getSymbol(); - o(c.parallelArrays, function(a) { c[a + "Data"] = [] }); - c.setData(b.data, !1); - if (c.isCartesian) a.hasCartesianSeries = !0; - f.push(c); - c._i = f.length - 1; - pb(f, g); - this.yAxis && pb(this.yAxis.series, g); - o(f, function(a, b) { - a.index = b; - a.name = - a.name || "Series " + (b + 1) - }) - }, - bindAxes: function() { - var a = this, - b = a.options, - c = a.chart, - d; - o(a.axisTypes || [], function(e) { o(c[e], function(c) { d = c.options; - if (b[e] === d.index || b[e] !== x && b[e] === d.id || b[e] === x && d.index === 0) c.series.push(a), a[e] = c, c.isDirty = !0 });!a[e] && a.optionalAxis !== e && ja(18, !0) }) }, - updateParallelArrays: function(a, b) { - var c = a.series, - d = arguments, - e = z(b) ? function(d) { - var e = d === "y" && c.toYData ? c.toYData(a) : a[d]; - c[d + "Data"][b] = e } : function(a) { - Array.prototype[b].apply(c[a + "Data"], Array.prototype.slice.call(d, - 2)) - }; - o(c.parallelArrays, e) - }, - autoIncrement: function(a) { - var g; - var b = this.options, - c = this.xIncrement, - d = b.pointIntervalUnit, - e = this.xAxis, - f, c = q(c, b.pointStart, 0); - this.pointInterval = b = q(this.pointInterval, b.pointInterval, 1); - if (e && e.categories && a.name) - if (this.requireSorting = !1, g = (f = Ra(e.categories)) ? e.categories : e.names, e = g, a = qa(a.name, e), a === -1) { - if (!f) c = e.length } else c = a; - d && (a = new ea(c), d === "day" ? a = +a[sb](a[db]() + b) : d === "month" ? a = +a[Hb](a[jb]() + b) : d === "year" && (a = +a[Ib](a[kb]() + b)), b = a - c); - this.xIncrement = - c + b; - return c - }, - setOptions: function(a) { - var b = this.chart, - c = b.options.plotOptions, - b = b.userOptions || {}, - d = b.plotOptions || {}, - e = c[this.type]; - this.userOptions = a; - c = D(e, c.series, a); - this.tooltipOptions = D(Q.tooltip, Q.plotOptions[this.type].tooltip, b.tooltip, d.series && d.series.tooltip, d[this.type] && d[this.type].tooltip, a.tooltip); - e.marker === null && delete c.marker; - this.zoneAxis = c.zoneAxis; - a = this.zones = (c.zones || []).slice(); - if ((c.negativeColor || c.negativeFillColor) && !c.zones) a.push({ - value: c[this.zoneAxis + "Threshold"] || - c.threshold || 0, - color: c.negativeColor, - fillColor: c.negativeFillColor - }); - a.length && t(a[a.length - 1].value) && a.push({ color: this.color, fillColor: this.fillColor }); - return c - }, - getCyclic: function(a, b, c) { - var d = this.userOptions, - e = "_" + a + "Index", - f = a + "Counter"; - b || (t(d[e]) ? b = d[e] : (d[e] = b = this.chart[f] % c.length, this.chart[f] += 1), b = c[b]); - this[a] = b }, - getColor: function() { this.options.colorByPoint ? this.options.color = null : this.getCyclic("color", this.options.color || X[this.type].color, this.chart.options.colors) }, - getSymbol: function() { - var a = - this.options.marker; - this.getCyclic("symbol", a.symbol, this.chart.options.symbols); - if (/^url/.test(this.symbol)) a.radius = 0 - }, - drawLegendSymbol: da.drawLineMarker, - setData: function(a, b, c, d) { - var e = this, - f = e.points, - g = f && f.length || 0, - h, i = e.options, - j = e.chart, - k = null, - l = e.xAxis, - m = i.turboThreshold, - n = this.xData, - p = this.yData, - r = (h = e.pointArrayMap) && h.length, - a = a || []; - h = a.length; - b = q(b, !0); - if (d !== !1 && h && g === h && !e.cropped && !e.hasGroupedData && e.visible) o(a, function(a, b) { f[b].update && a !== i.data[b] && f[b].update(a, !1, null, !1) }); - else { - e.xIncrement = null; - e.colorCounter = 0; - o(this.parallelArrays, function(a) { e[a + "Data"].length = 0 }); - if (m && h > m) { - for (c = 0; k === null && c < h;) k = a[c], c++; - if (z(k)) { k = q(i.pointStart, 0); - r = q(i.pointInterval, 1); - for (c = 0; c < h; c++) n[c] = k, p[c] = a[c], k += r; - e.xIncrement = k } else if (Ra(k)) - if (r) - for (c = 0; c < h; c++) k = a[c], n[c] = k[0], p[c] = k.slice(1, r + 1); - else - for (c = 0; c < h; c++) k = a[c], n[c] = k[0], p[c] = k[1]; - else ja(12) } else - for (c = 0; c < h; c++) a[c] !== x && (k = { series: e }, e.pointClass.prototype.applyOptions.apply(k, [a[c]]), e.updateParallelArrays(k, - c)); - Ea(p[0]) && ja(14, !0); - e.data = []; - e.options.data = e.userOptions.data = a; - for (c = g; c--;) f[c] && f[c].destroy && f[c].destroy(); - if (l) l.minRange = l.userMinRange; - e.isDirty = e.isDirtyData = j.isDirtyBox = !0; - c = !1 - } - i.legendType === "point" && (this.processData(), this.generatePoints()); - b && j.redraw(c) - }, - processData: function(a) { - var b = this.xData, - c = this.yData, - d = b.length, - e; - e = 0; - var f, g, h = this.xAxis, - i, j = this.options; - i = j.cropThreshold; - var k = this.getExtremesFromAll || j.getExtremesFromAll, - l = this.isCartesian, - j = h && h.val2lin, - m = h && h.isLog, - n, p; - if (l && !this.isDirty && !h.isDirty && !this.yAxis.isDirty && !a) return !1; - if (h) a = h.getExtremes(), n = a.min, p = a.max; - if (l && this.sorted && !k && (!i || d > i || this.forceCrop)) - if (b[d - 1] < n || b[0] > p) b = [], c = []; - else if (b[0] < n || b[d - 1] > p) e = this.cropData(this.xData, this.yData, n, p), b = e.xData, c = e.yData, e = e.start, f = !0; - for (i = b.length || 1; --i;) d = m ? j(b[i]) - j(b[i - 1]) : b[i] - b[i - 1], d > 0 && (g === x || d < g) ? g = d : d < 0 && this.requireSorting && ja(15); - this.cropped = f; - this.cropStart = e; - this.processedXData = b; - this.processedYData = c; - this.closestPointRange = - g - }, - cropData: function(a, b, c, d) { - var e = a.length, - f = 0, - g = e, - h = q(this.cropShoulder, 1), - i; - for (i = 0; i < e; i++) - if (a[i] >= c) { f = y(0, i - h); - break } - for (c = i; c < e; c++) - if (a[c] > d) { g = c + h; - break } - return { xData: a.slice(f, g), yData: b.slice(f, g), start: f, end: g } }, - generatePoints: function() { - var a = this.options.data, - b = this.data, - c, d = this.processedXData, - e = this.processedYData, - f = this.pointClass, - g = d.length, - h = this.cropStart || 0, - i, j = this.hasGroupedData, - k, l = [], - m; - if (!b && !j) b = [], b.length = a.length, b = this.data = b; - for (m = 0; m < g; m++) i = h + m, j ? (l[m] = (new f).init(this, [d[m]].concat(sa(e[m]))), l[m].dataGroup = this.groupMap[m]) : (b[i] ? k = b[i] : a[i] !== x && (b[i] = k = (new f).init(this, a[i], d[m])), l[m] = k), l[m].index = i; - if (b && (g !== (c = b.length) || j)) - for (m = 0; m < c; m++) - if (m === h && !j && (m += g), b[m]) b[m].destroyElements(), b[m].plotX = x; - this.data = b; - this.points = l - }, - getExtremes: function(a) { - var b = this.yAxis, - c = this.processedXData, - d, e = [], - f = 0; - d = this.xAxis.getExtremes(); - var g = d.min, - h = d.max, - i, j, k, l, a = a || this.stackedYData || this.processedYData || []; - d = a.length; - for (l = 0; l < d; l++) - if (j = c[l], k = a[l], i = k !== null && - k !== x && (!b.isLog || k.length || k > 0), j = this.getExtremesFromAll || this.options.getExtremesFromAll || this.cropped || (c[l + 1] || j) >= g && (c[l - 1] || j) <= h, i && j) - if (i = k.length) - for (; i--;) k[i] !== null && (e[f++] = k[i]); - else e[f++] = k; - this.dataMin = Na(e); - this.dataMax = Fa(e) - }, - translate: function() { - this.processedXData || this.processData(); - this.generatePoints(); - for (var a = this.options, b = a.stacking, c = this.xAxis, d = c.categories, e = this.yAxis, f = this.points, g = f.length, h = !!this.modifyValue, i = a.pointPlacement, j = i === "between" || z(i), k = a.threshold, - l = a.startFromThreshold ? k : 0, m, n, p, r, s = Number.MAX_VALUE, a = 0; a < g; a++) { - var o = f[a], - u = o.x, - w = o.y; - n = o.low; - var F = b && e.stacks[(this.negStacks && w < (l ? 0 : k) ? "-" : "") + this.stackKey], - L; - if (e.isLog && w !== null && w <= 0) o.y = w = null, ja(10); - o.plotX = m = V(E(y(-1E5, c.translate(u, 0, 0, 0, 1, i, this.type === "flags")), 1E5)); - if (b && this.visible && !o.isNull && F && F[u]) r = this.getStackIndicator(r, u, this.index), L = F[u], w = L.points[r.key], n = w[0], w = w[1], n === l && r.key === F[u].base && (n = q(k, e.min)), e.isLog && n <= 0 && (n = null), o.total = o.stackTotal = L.total, o.percentage = - L.total && o.y / L.total * 100, o.stackY = w, L.setOffset(this.pointXOffset || 0, this.barW || 0); - o.yBottom = t(n) ? e.translate(n, 0, 1, 0, 1) : null; - h && (w = this.modifyValue(w, o)); - o.plotY = n = typeof w === "number" && w !== Infinity ? E(y(-1E5, e.translate(w, 0, 1, 0, 1)), 1E5) : x; - o.isInside = n !== x && n >= 0 && n <= e.len && m >= 0 && m <= c.len; - o.clientX = j ? V(c.translate(u, 0, 0, 0, 1)) : m; - o.negative = o.y < (k || 0); - o.category = d && d[o.x] !== x ? d[o.x] : o.x; - o.isNull || (p !== void 0 && (s = E(s, T(m - p))), p = m) - } - this.closestPointRangePx = s - }, - getValidPoints: function(a, b) { - var c = this.chart; - return Ha(a || this.points || [], function(a) { - return b && !c.isInsidePlot(a.plotX, a.plotY, c.inverted) ? !1 : !a.isNull }) - }, - setClip: function(a) { - var b = this.chart, - c = this.options, - d = b.renderer, - e = b.inverted, - f = this.clipBox, - g = f || b.clipBox, - h = this.sharedClipKey || ["_sharedClip", a && a.duration, a && a.easing, g.height, c.xAxis, c.yAxis].join(","), - i = b[h], - j = b[h + "m"]; - if (!i) { - if (a) g.width = 0, b[h + "m"] = j = d.clipRect(-99, e ? -b.plotLeft : -b.plotTop, 99, e ? b.chartWidth : b.chartHeight); - b[h] = i = d.clipRect(g); - i.count = { length: 0 } } - a && !i.count[this.index] && - (i.count[this.index] = !0, i.count.length += 1); - if (c.clip !== !1) this.group.clip(a || f ? i : b.clipRect), this.markerGroup.clip(j), this.sharedClipKey = h; - a || (i.count[this.index] && (delete i.count[this.index], i.count.length -= 1), i.count.length === 0 && h && b[h] && (f || (b[h] = b[h].destroy()), b[h + "m"] && (b[h + "m"] = b[h + "m"].destroy()))) - }, - animate: function(a) { - var b = this.chart, - c = this.options.animation, - d; - if (c && !ha(c)) c = X[this.type].animation; - a ? this.setClip(c) : (d = this.sharedClipKey, (a = b[d]) && a.animate({ width: b.plotSizeX }, c), b[d + "m"] && - b[d + "m"].animate({ width: b.plotSizeX + 99 }, c), this.animate = null) - }, - afterAnimate: function() { this.setClip(); - K(this, "afterAnimate") }, - drawPoints: function() { - var a, b = this.points, - c = this.chart, - d, e, f, g, h, i, j, k, l = this.options.marker, - m = this.pointAttr[""], - n, p, r, s = this.markerGroup, - o = q(l.enabled, this.xAxis.isRadial, this.closestPointRangePx > 2 * l.radius); - if (l.enabled !== !1 || this._hasPointMarkers) - for (f = b.length; f--;) - if (g = b[f], d = Y(g.plotX), e = g.plotY, k = g.graphic, n = g.marker || {}, p = !!g.marker, a = o && n.enabled === x || n.enabled, r = - g.isInside, a && z(e) && g.y !== null) - if (a = g.pointAttr[g.selected ? "select" : ""] || m, h = a.r, i = q(n.symbol, this.symbol), j = i.indexOf("url") === 0, k) k[r ? "show" : "hide"](!0).attr(a).animate(v({ x: d - h, y: e - h }, k.symbolName ? { width: 2 * h, height: 2 * h } : {})); - else { - if (r && (h > 0 || j)) g.graphic = c.renderer.symbol(i, d - h, e - h, 2 * h, 2 * h, p ? n : l).attr(a).add(s) } - else if (k) g.graphic = k.destroy() - }, - convertAttribs: function(a, b, c, d) { - var e = this.pointAttrToOptions, - f, g, h = {}, - a = a || {}, - b = b || {}, - c = c || {}, - d = d || {}; - for (f in e) g = e[f], h[f] = q(a[g], b[f], c[f], d[f]); - return h }, - getAttribs: function() { - var a = this, - b = a.options, - c = X[a.type].marker ? b.marker : b, - d = c.states, - e = d.hover, - f, g = a.color, - h = a.options.negativeColor, - i = { stroke: g, fill: g }, - j = a.points || [], - k, l = [], - m, n = a.pointAttrToOptions; - f = a.hasPointSpecificOptions; - var p = c.lineColor, - r = c.fillColor; - k = b.turboThreshold; - var s = a.zones, - Z = a.zoneAxis || "y", - u, w; - b.marker ? (e.radius = +e.radius || +c.radius + +e.radiusPlus, e.lineWidth = e.lineWidth || c.lineWidth + e.lineWidthPlus) : (e.color = e.color || xa(e.color || g).brighten(e.brightness).get(), e.negativeColor = - e.negativeColor || xa(e.negativeColor || h).brighten(e.brightness).get()); - l[""] = a.convertAttribs(c, i); - o(["hover", "select"], function(b) { l[b] = a.convertAttribs(d[b], l[""]) }); - a.pointAttr = l; - g = j.length; - if (!k || g < k || f) - for (; g--;) { - k = j[g]; - if ((c = k.options && k.options.marker || k.options) && c.enabled === !1) c.radius = 0; - i = null; - if (s.length) { f = 0; - for (i = s[f]; k[Z] >= i.value;) i = s[++f]; - k.color = k.fillColor = i = q(i.color, a.color) } - f = b.colorByPoint || k.color; - if (k.options) - for (w in n) t(c[n[w]]) && (f = !0); - if (f) { - c = c || {}; - m = []; - d = c.states || {}; - f = - d.hover = d.hover || {}; - if (!b.marker || k.negative && !f.fillColor && !e.fillColor) f[a.pointAttrToOptions.fill] = f.color || !k.options.color && e[k.negative && h ? "negativeColor" : "color"] || xa(k.color).brighten(f.brightness || e.brightness).get(); - u = { color: k.color }; - if (!r) u.fillColor = k.color; - if (!p) u.lineColor = k.color; - c.hasOwnProperty("color") && !c.color && delete c.color; - if (i && !e.fillColor) f.fillColor = i; - m[""] = a.convertAttribs(v(u, c), l[""]); - m.hover = a.convertAttribs(d.hover, l.hover, m[""]); - m.select = a.convertAttribs(d.select, - l.select, m[""]) - } else m = l; - k.pointAttr = m - } - }, - destroy: function() { - var a = this, - b = a.chart, - c = /AppleWebKit\/533/.test(Pa), - d, e = a.data || [], - f, g, h; - K(a, "destroy"); - U(a); - o(a.axisTypes || [], function(b) { - if (h = a[b]) Ba(h.series, a), h.isDirty = h.forceRedraw = !0 }); - a.legendItem && a.chart.legend.destroyItem(a); - for (d = e.length; d--;)(f = e[d]) && f.destroy && f.destroy(); - a.points = null; - clearTimeout(a.animationTimeout); - for (g in a) a[g] instanceof ba && !a[g].survive && (d = c && g === "group" ? "hide" : "destroy", a[g][d]()); - if (b.hoverSeries === a) b.hoverSeries = - null; - Ba(b.series, a); - for (g in a) delete a[g] - }, - getGraphPath: function(a, b, c) { - var d = this, - e = d.options, - f = e.step, - g, h = [], - i = [], - j, a = a || d.points; - (g = a.reversed) && a.reverse(); - (f = { right: 1, center: 2 }[f] || f && 3) && g && (f = 4 - f); - e.connectNulls && !b && !c && (a = this.getValidPoints(a)); - o(a, function(g, l) { - var m = g.plotX, - n = g.plotY, - p = a[l - 1]; - if ((g.leftCliff || p && p.rightCliff) && !c) j = !0; - g.isNull && !t(b) && l > 0 ? j = !e.connectNulls : g.isNull && !b ? j = !0 : (l === 0 || j ? p = [W, g.plotX, g.plotY] : d.getPointSpline ? p = d.getPointSpline(a, g, l) : f ? (p = f === 1 ? [R, p.plotX, - n - ] : f === 2 ? [R, (p.plotX + m) / 2, p.plotY, R, (p.plotX + m) / 2, n] : [R, m, p.plotY], p.push(R, m, n)) : p = [R, m, n], i.push(g.x), f && i.push(g.x), h.push.apply(h, p), j = !1) - }); - h.xMap = i; - return d.graphPath = h - }, - drawGraph: function() { - var a = this, - b = this.options, - c = [ - ["graph", b.lineColor || this.color, b.dashStyle] - ], - d = b.lineWidth, - e = b.linecap !== "square", - f = (this.gappedPath || this.getGraphPath).call(this); - o(this.zones, function(d, e) { c.push(["zoneGraph" + e, d.color || a.color, d.dashStyle || b.dashStyle]) }); - o(c, function(c, h) { - var i = c[0], - j = a[i]; - if (j) j.endX = - f.xMap, j.animate({ d: f }); - else if (d && f.length) j = { stroke: c[1], "stroke-width": d, fill: "none", zIndex: 1 }, c[2] ? j.dashstyle = c[2] : e && (j["stroke-linecap"] = j["stroke-linejoin"] = "round"), j = a[i] = a.chart.renderer.path(f).attr(j).add(a.group).shadow(h < 2 && b.shadow); - if (j) j.startX = f.xMap, j.isArea = f.isArea - }) - }, - applyZones: function() { - var a = this, - b = this.chart, - c = b.renderer, - d = this.zones, - e, f, g = this.clips || [], - h, i = this.graph, - j = this.area, - k = y(b.chartWidth, b.chartHeight), - l = this[(this.zoneAxis || "y") + "Axis"], - m, n = l.reversed, - p = b.inverted, - r = l.horiz, - s, Z, u, w = !1; - if (d.length && (i || j) && l.min !== x) i && i.hide(), j && j.hide(), m = l.getExtremes(), o(d, function(d, o) { - e = n ? r ? b.plotWidth : 0 : r ? 0 : l.toPixels(m.min); - e = E(y(q(f, e), 0), k); - f = E(y(A(l.toPixels(q(d.value, m.max), !0)), 0), k); - w && (e = f = l.toPixels(m.max)); - s = Math.abs(e - f); - Z = E(e, f); - u = y(e, f); - if (l.isXAxis) { - if (h = { x: p ? u : Z, y: 0, width: s, height: k }, !r) h.x = b.plotHeight - h.x } else if (h = { x: 0, y: p ? u : Z, width: k, height: s }, r) h.y = b.plotWidth - h.y; - b.inverted && c.isVML && (h = l.isXAxis ? { x: 0, y: n ? Z : u, height: h.width, width: b.chartWidth } : { - x: h.y - - b.plotLeft - b.spacingBox.x, - y: 0, - width: h.height, - height: b.chartHeight - }); - g[o] ? g[o].animate(h) : (g[o] = c.clipRect(h), i && a["zoneGraph" + o].clip(g[o]), j && a["zoneArea" + o].clip(g[o])); - w = d.value > m.max - }), this.clips = g - }, - invertGroups: function() { - function a() { - var a = { width: b.yAxis.len, height: b.xAxis.len }; - o(["group", "markerGroup"], function(c) { b[c] && b[c].attr(a).invert() }) } - var b = this, - c = b.chart; - if (b.xAxis) G(c, "resize", a), G(b, "destroy", function() { U(c, "resize", a) }), a(), b.invertGroups = a }, - plotGroup: function(a, b, c, d, e) { - var f = - this[a], - g = !f; - g && (this[a] = f = this.chart.renderer.g(b).attr({ zIndex: d || 0.1 }).add(e), f.addClass("highcharts-series-" + this.index)); - f.attr({ visibility: c })[g ? "attr" : "animate"](this.getPlotBox()); - return f - }, - getPlotBox: function() { - var a = this.chart, - b = this.xAxis, - c = this.yAxis; - if (a.inverted) b = c, c = this.xAxis; - return { translateX: b ? b.left : a.plotLeft, translateY: c ? c.top : a.plotTop, scaleX: 1, scaleY: 1 } }, - render: function() { - var a = this, - b = a.chart, - c, d = a.options, - e = !!a.animate && b.renderer.isSVG && ib(d.animation).duration, - f = a.visible ? - "inherit" : "hidden", - g = d.zIndex, - h = a.hasRendered, - i = b.seriesGroup; - c = a.plotGroup("group", "series", f, g, i); - a.markerGroup = a.plotGroup("markerGroup", "markers", f, g, i); - e && a.animate(!0); - a.getAttribs(); - c.inverted = a.isCartesian ? b.inverted : !1; - a.drawGraph && (a.drawGraph(), a.applyZones()); - o(a.points, function(a) { a.redraw && a.redraw() }); - a.drawDataLabels && a.drawDataLabels(); - a.visible && a.drawPoints(); - a.drawTracker && a.options.enableMouseTracking !== !1 && a.drawTracker(); - b.inverted && a.invertGroups(); - d.clip !== !1 && !a.sharedClipKey && - !h && c.clip(b.clipRect); - e && a.animate(); - if (!h) a.animationTimeout = bb(function() { a.afterAnimate() }, e); - a.isDirty = a.isDirtyData = !1; - a.hasRendered = !0 - }, - redraw: function() { - var a = this.chart, - b = this.isDirty || this.isDirtyData, - c = this.group, - d = this.xAxis, - e = this.yAxis; - c && (a.inverted && c.attr({ width: a.plotWidth, height: a.plotHeight }), c.animate({ translateX: q(d && d.left, a.plotLeft), translateY: q(e && e.top, a.plotTop) })); - this.translate(); - this.render(); - b && delete this.kdTree }, - kdDimensions: 1, - kdAxisArray: ["clientX", "plotY"], - searchPoint: function(a, - b) { - var c = this.xAxis, - d = this.yAxis, - e = this.chart.inverted; - return this.searchKDTree({ clientX: e ? c.len - a.chartY + c.pos : a.chartX - c.pos, plotY: e ? d.len - a.chartX + d.pos : a.chartY - d.pos }, b) }, - buildKDTree: function() { - function a(c, e, f) { - var g, h; - if (h = c && c.length) return g = b.kdAxisArray[e % f], c.sort(function(a, b) { - return a[g] - b[g] }), h = Math.floor(h / 2), { point: c[h], left: a(c.slice(0, h), e + 1, f), right: a(c.slice(h + 1), e + 1, f) } } - var b = this, - c = b.kdDimensions; - delete b.kdTree; - bb(function() { - b.kdTree = a(b.getValidPoints(null, !b.directTouch), - c, c) - }, b.options.kdNow ? 0 : 1) - }, - searchKDTree: function(a, b) { - function c(a, b, j, k) { - var l = b.point, - m = d.kdAxisArray[j % k], - n, p, r = l; - p = t(a[e]) && t(l[e]) ? Math.pow(a[e] - l[e], 2) : null; - n = t(a[f]) && t(l[f]) ? Math.pow(a[f] - l[f], 2) : null; - n = (p || 0) + (n || 0); - l.dist = t(n) ? Math.sqrt(n) : Number.MAX_VALUE; - l.distX = t(p) ? Math.sqrt(p) : Number.MAX_VALUE; - m = a[m] - l[m]; - n = m < 0 ? "left" : "right"; - p = m < 0 ? "right" : "left"; - b[n] && (n = c(a, b[n], j + 1, k), r = n[g] < r[g] ? n : l); - b[p] && Math.sqrt(m * m) < r[g] && (a = c(a, b[p], j + 1, k), r = a[g] < r[g] ? a : r); - return r } - var d = this, - e = this.kdAxisArray[0], - f = this.kdAxisArray[1], - g = b ? "distX" : "dist"; - this.kdTree || this.buildKDTree(); - if (this.kdTree) return c(a, this.kdTree, this.kdDimensions, this.kdDimensions) - } - }; - Vb.prototype = { - destroy: function() { Oa(this, this.axis) }, - render: function(a) { - var b = this.options, - c = b.format, - c = c ? Ma(c, this) : b.formatter.call(this); - this.label ? this.label.attr({ text: c, visibility: "hidden" }) : this.label = this.axis.chart.renderer.text(c, null, null, b.useHTML).css(b.style).attr({ align: this.textAlign, rotation: b.rotation, visibility: "hidden" }).add(a) }, - setOffset: function(a, b) { - var c = this.axis, - d = c.chart, - e = d.inverted, - f = c.reversed, - f = this.isNegative && !f || !this.isNegative && f, - g = c.translate(c.usePercentage ? 100 : this.total, 0, 0, 0, 1), - c = c.translate(0), - c = T(g - c), - h = d.xAxis[0].translate(this.x) + a, - i = d.plotHeight, - f = { x: e ? f ? g : g - c : h, y: e ? i - h - b : f ? i - g - c : i - g, width: e ? c : b, height: e ? b : c }; - if (e = this.label) e.align(this.alignOptions, null, f), f = e.alignAttr, e[this.options.crop === !1 || d.isInsidePlot(f.x, f.y) ? "show" : "hide"](!0) } - }; - Da.prototype.getStacks = function() { - var a = this; - o(a.yAxis, - function(a) { - if (a.stacks && a.hasVisibleSeries) a.oldStacks = a.stacks }); - o(a.series, function(b) { - if (b.options.stacking && (b.visible === !0 || a.options.chart.ignoreHiddenSeries === !1)) b.stackKey = b.type + q(b.options.stack, "") }) - }; - J.prototype.buildStacks = function() { - var a = this.series, - b, c = q(this.options.reversedStacks, !0), - d = a.length, - e; - if (!this.isXAxis) { this.usePercentage = !1; - for (e = d; e--;) a[c ? e : d - e - 1].setStackedPoints(); - for (e = d; e--;) b = a[c ? e : d - e - 1], b.setStackCliffs && b.setStackCliffs(); - if (this.usePercentage) - for (e = 0; e < d; e++) a[e].setPercentStacks() } }; - J.prototype.renderStackTotals = function() { - var a = this.chart, - b = a.renderer, - c = this.stacks, - d, e, f = this.stackTotalGroup; - if (!f) this.stackTotalGroup = f = b.g("stack-labels").attr({ visibility: "visible", zIndex: 6 }).add(); - f.translate(a.plotLeft, a.plotTop); - for (d in c) - for (e in a = c[d], a) a[e].render(f) }; - J.prototype.resetStacks = function() { - var a = this.stacks, - b, c; - if (!this.isXAxis) - for (b in a) - for (c in a[b]) a[b][c].touched < this.stacksTouched ? (a[b][c].destroy(), delete a[b][c]) : (a[b][c].total = null, a[b][c].cum = 0) }; - J.prototype.cleanStacks = - function() { - var a, b, c; - if (!this.isXAxis) { - if (this.oldStacks) a = this.stacks = this.oldStacks; - for (b in a) - for (c in a[b]) a[b][c].cum = a[b][c].total } }; - P.prototype.setStackedPoints = function() { - if (this.options.stacking && !(this.visible !== !0 && this.chart.options.chart.ignoreHiddenSeries !== !1)) { - var a = this.processedXData, - b = this.processedYData, - c = [], - d = b.length, - e = this.options, - f = e.threshold, - g = e.startFromThreshold ? f : 0, - h = e.stack, - e = e.stacking, - i = this.stackKey, - j = "-" + i, - k = this.negStacks, - l = this.yAxis, - m = l.stacks, - n = l.oldStacks, - p, - r, s, o, u, w, F; - l.stacksTouched += 1; - for (u = 0; u < d; u++) { - w = a[u]; - F = b[u]; - p = this.getStackIndicator(p, w, this.index); - o = p.key; - s = (r = k && F < (g ? 0 : f)) ? j : i; - m[s] || (m[s] = {}); - if (!m[s][w]) n[s] && n[s][w] ? (m[s][w] = n[s][w], m[s][w].total = null) : m[s][w] = new Vb(l, l.options.stackLabels, r, w, h); - s = m[s][w]; - if (F !== null) { s.points[o] = s.points[this.index] = [q(s.cum, g)]; - if (!t(s.cum)) s.base = o; - s.touched = l.stacksTouched; - p.index > 0 && this.singleStacks === !1 && (s.points[o][0] = s.points[this.index + "," + w + ",0"][0]) } - e === "percent" ? (r = r ? i : j, k && m[r] && m[r][w] ? - (r = m[r][w], s.total = r.total = y(r.total, s.total) + T(F) || 0) : s.total = V(s.total + (T(F) || 0))) : s.total = V(s.total + (F || 0)); - s.cum = q(s.cum, g) + (F || 0); - if (F !== null) s.points[o].push(s.cum), c[u] = s.cum - } - if (e === "percent") l.usePercentage = !0; - this.stackedYData = c; - l.oldStacks = {} - } - }; - P.prototype.setPercentStacks = function() { - var a = this, - b = a.stackKey, - c = a.yAxis.stacks, - d = a.processedXData, - e; - o([b, "-" + b], function(b) { - var f; - for (var g = d.length, h, i; g--;) - if (h = d[g], e = a.getStackIndicator(e, h, a.index), f = (i = c[b] && c[b][h]) && i.points[e.key], h = f) i = - i.total ? 100 / i.total : 0, h[0] = V(h[0] * i), h[1] = V(h[1] * i), a.stackedYData[g] = h[1] - }) - }; - P.prototype.getStackIndicator = function(a, b, c) {!t(a) || a.x !== b ? a = { x: b, index: 0 } : a.index++; - a.key = [c, b, a.index].join(","); - return a }; - v(Da.prototype, { - addSeries: function(a, b, c) { - var d, e = this; - a && (b = q(b, !0), K(e, "addSeries", { options: a }, function() { d = e.initSeries(a); - e.isDirtyLegend = !0; - e.linkSeries(); - b && e.redraw(c) })); - return d }, - addAxis: function(a, b, c, d) { - var e = b ? "xAxis" : "yAxis", - f = this.options, - a = D(a, { index: this[e].length, isX: b }); - new J(this, - a); - f[e] = sa(f[e] || {}); - f[e].push(a); - q(c, !0) && this.redraw(d) - }, - showLoading: function(a) { - var b = this, - c = b.options, - d = b.loadingDiv, - e = c.loading, - f = function() { d && O(d, { left: b.plotLeft + "px", top: b.plotTop + "px", width: b.plotWidth + "px", height: b.plotHeight + "px" }) }; - if (!d) b.loadingDiv = d = ia(Xa, { className: "highcharts-loading" }, v(e.style, { zIndex: 10, display: "none" }), b.container), b.loadingSpan = ia("span", null, e.labelStyle, d), G(b, "redraw", f); - b.loadingSpan.innerHTML = a || c.lang.loading; - if (!b.loadingShown) O(d, { opacity: 0, display: "" }), - fb(d, { opacity: e.style.opacity }, { duration: e.showDuration || 0 }), b.loadingShown = !0; - f() - }, - hideLoading: function() { - var a = this.options, - b = this.loadingDiv; - b && fb(b, { opacity: 0 }, { duration: a.loading.hideDuration || 100, complete: function() { O(b, { display: "none" }) } }); - this.loadingShown = !1 } - }); - v(Ja.prototype, { - update: function(a, b, c, d) { - function e() { - f.applyOptions(a); - if (f.y === null && h) f.graphic = h.destroy(); - if (ha(a, !0)) f.redraw = function() { - if (h && h.element && a && a.marker && a.marker.symbol) f.graphic = h.destroy(); - if (a && a.dataLabels && - f.dataLabel) f.dataLabel = f.dataLabel.destroy(); - f.redraw = null - }; - i = f.index; - g.updateParallelArrays(f, i); - if (l && f.name) l[f.x] = f.name; - k.data[i] = ha(k.data[i], !0) ? f.options : a; - g.isDirty = g.isDirtyData = !0; - if (!g.fixedBox && g.hasCartesianSeries) j.isDirtyBox = !0; - if (k.legendType === "point") j.isDirtyLegend = !0; - b && j.redraw(c) - } - var f = this, - g = f.series, - h = f.graphic, - i, j = g.chart, - k = g.options, - l = g.xAxis && g.xAxis.names, - b = q(b, !0); - d === !1 ? e() : f.firePointEvent("update", { options: a }, e) - }, - remove: function(a, b) { - this.series.removePoint(qa(this, - this.series.data), a, b) - } - }); - v(P.prototype, { - addPoint: function(a, b, c, d) { - var e = this.options, - f = this.data, - g = this.chart, - h = this.xAxis && this.xAxis.names, - i = e.data, - j, k = this.xData, - l, m; - cb(d, g); - b = q(b, !0); - d = { series: this }; - this.pointClass.prototype.applyOptions.apply(d, [a]); - m = d.x; - l = k.length; - if (this.requireSorting && m < k[l - 1]) - for (j = !0; l && k[l - 1] > m;) l--; - this.updateParallelArrays(d, "splice", l, 0, 0); - this.updateParallelArrays(d, l); - if (h && d.name) h[m] = d.name; - i.splice(l, 0, a); - j && (this.data.splice(l, 0, null), this.processData()); - e.legendType === - "point" && this.generatePoints(); - c && (f[0] && f[0].remove ? f[0].remove(!1) : (f.shift(), this.updateParallelArrays(d, "shift"), i.shift())); - this.isDirtyData = this.isDirty = !0; - b && (this.getAttribs(), g.redraw()) - }, - removePoint: function(a, b, c) { - var d = this, - e = d.data, - f = e[a], - g = d.points, - h = d.chart, - i = function() { g && g.length === e.length && g.splice(a, 1); - e.splice(a, 1); - d.options.data.splice(a, 1); - d.updateParallelArrays(f || { series: d }, "splice", a, 1); - f && f.destroy(); - d.isDirty = !0; - d.isDirtyData = !0; - b && h.redraw() }; - cb(c, h); - b = q(b, !0); - f ? f.firePointEvent("remove", - null, i) : i() - }, - remove: function(a, b) { - var c = this, - d = c.chart; - K(c, "remove", null, function() { c.destroy(); - d.isDirtyLegend = d.isDirtyBox = !0; - d.linkSeries(); - q(a, !0) && d.redraw(b) }) }, - update: function(a, b) { - var c = this, - d = this.chart, - e = this.userOptions, - f = this.type, - g = I[f].prototype, - h = ["group", "markerGroup", "dataLabelsGroup"], - i; - if (a.type && a.type !== f || a.zIndex !== void 0) h.length = 0; - o(h, function(a) { h[a] = c[a]; - delete c[a] }); - a = D(e, { animation: !1, index: this.index, pointStart: this.xData[0] }, { data: this.options.data }, a); - this.remove(!1); - for (i in g) this[i] = x; - v(this, I[a.type || f].prototype); - o(h, function(a) { c[a] = h[a] }); - this.init(d, a); - d.linkSeries(); - q(b, !0) && d.redraw(!1) - } - }); - v(J.prototype, { - update: function(a, b) { - var c = this.chart, - a = c.options[this.coll][this.options.index] = D(this.userOptions, a); - this.destroy(!0); - this.init(c, v(a, { events: x })); - c.isDirtyBox = !0; - q(b, !0) && c.redraw() }, - remove: function(a) { - for (var b = this.chart, c = this.coll, d = this.series, e = d.length; e--;) d[e] && d[e].remove(!1); - Ba(b.axes, this); - Ba(b[c], this); - b.options[c].splice(this.options.index, - 1); - o(b[c], function(a, b) { a.options.index = b }); - this.destroy(); - b.isDirtyBox = !0; - q(a, !0) && b.redraw() - }, - setTitle: function(a, b) { this.update({ title: a }, b) }, - setCategories: function(a, b) { this.update({ categories: a }, b) } - }); - var Ka = oa(P); - I.line = Ka; - X.area = D(ga, { softThreshold: !1, threshold: 0 }); - var Aa = oa(P, { - type: "area", - singleStacks: !1, - getStackPoints: function() { - var a = [], - b = [], - c = this.xAxis, - d = this.yAxis, - e = d.stacks[this.stackKey], - f = {}, - g = this.points, - h = this.index, - i = d.series, - j = i.length, - k, l = q(d.options.reversedStacks, !0) ? 1 : -1, - m, - n; - if (this.options.stacking) { - for (m = 0; m < g.length; m++) f[g[m].x] = g[m]; - for (n in e) e[n].total !== null && b.push(n); - b.sort(function(a, b) { - return a - b }); - k = wa(i, function() { - return this.visible }); - o(b, function(g, i) { - var n = 0, - q, u; - if (f[g] && !f[g].isNull) a.push(f[g]), o([-1, 1], function(a) { - var c = a === 1 ? "rightNull" : "leftNull", - d = 0, - n = e[b[i + a]]; - if (n) - for (m = h; m >= 0 && m < j;) q = n.points[m], q || (m === h ? f[g][c] = !0 : k[m] && (u = e[g].points[m]) && (d -= u[1] - u[0])), m += l; - f[g][a === 1 ? "rightCliff" : "leftCliff"] = d }); - else { - for (m = h; m >= 0 && m < j;) { - if (q = e[g].points[m]) { - n = - q[1]; - break - } - m += l - } - n = d.toPixels(n, !0); - a.push({ isNull: !0, plotX: c.toPixels(g, !0), plotY: n, yBottom: n }) - } - }) - } - return a - }, - getGraphPath: function(a) { - var b = P.prototype.getGraphPath, - c = this.options, - d = c.stacking, - e = this.yAxis, - f, g, h = [], - i = [], - j = this.index, - k, l = e.stacks[this.stackKey], - m = c.threshold, - n = e.getThreshold(c.threshold), - p, c = c.connectNulls || d === "percent", - r = function(b, c, f) { - var g = a[b], - b = d && l[g.x].points[j], - p = g[f + "Null"] || 0, - f = g[f + "Cliff"] || 0, - r, o, g = !0; - f || p ? (r = (p ? b[0] : b[1]) + f, o = b[0] + f, g = !!p) : !d && a[c] && a[c].isNull && (r = o = - m); - r !== void 0 && (i.push({ plotX: k, plotY: r === null ? n : e.getThreshold(r), isNull: g }), h.push({ plotX: k, plotY: o === null ? n : e.getThreshold(o) })) - }, - a = a || this.points; - d && (a = this.getStackPoints()); - for (f = 0; f < a.length; f++) - if (g = a[f].isNull, k = q(a[f].rectPlotX, a[f].plotX), p = q(a[f].yBottom, n), !g || c) { c || r(f, f - 1, "left"); - if (!g || d || !c) i.push(a[f]), h.push({ x: f, plotX: k, plotY: p }); - c || r(f, f + 1, "right") } - f = b.call(this, i, !0, !0); - h.reversed = !0; - g = b.call(this, h, !0, !0); - g.length && (g[0] = R); - g = f.concat(g); - b = b.call(this, i, !1, c); - g.xMap = f.xMap; - this.areaPath = g; - return b - }, - drawGraph: function() { - this.areaPath = []; - P.prototype.drawGraph.apply(this); - var a = this, - b = this.areaPath, - c = this.options, - d = [ - ["area", this.color, c.fillColor] - ]; - o(this.zones, function(b, f) { d.push(["zoneArea" + f, b.color || a.color, b.fillColor || c.fillColor]) }); - o(d, function(d) { - var f = d[0], - g = a[f]; - g ? (g.endX = b.xMap, g.animate({ d: b })) : (g = { fill: d[2] || d[1], zIndex: 0 }, d[2] || (g["fill-opacity"] = q(c.fillOpacity, 0.75)), g = a[f] = a.chart.renderer.path(b).attr(g).add(a.group), g.isArea = !0); - g.startX = b.xMap; - g.shiftUnit = - c.step ? 2 : 1 - }) - }, - drawLegendSymbol: da.drawRectangle - }); - I.area = Aa; - X.spline = D(ga); - Ka = oa(P, { - type: "spline", - getPointSpline: function(a, b, c) { - var d = b.plotX, - e = b.plotY, - f = a[c - 1], - c = a[c + 1], - g, h, i, j; - if (f && !f.isNull && c && !c.isNull) { - a = f.plotY; - i = c.plotX; - var c = c.plotY, - k = 0; - g = (1.5 * d + f.plotX) / 2.5; - h = (1.5 * e + a) / 2.5; - i = (1.5 * d + i) / 2.5; - j = (1.5 * e + c) / 2.5; - i !== g && (k = (j - h) * (i - d) / (i - g) + e - j); - h += k; - j += k; - h > a && h > e ? (h = y(a, e), j = 2 * e - h) : h < a && h < e && (h = E(a, e), j = 2 * e - h); - j > c && j > e ? (j = y(c, e), h = 2 * e - j) : j < c && j < e && (j = E(c, e), h = 2 * e - j); - b.rightContX = i; - b.rightContY = - j - } - b = ["C", q(f.rightContX, f.plotX), q(f.rightContY, f.plotY), q(g, d), q(h, e), d, e]; - f.rightContX = f.rightContY = null; - return b - } - }); - I.spline = Ka; - X.areaspline = D(X.area); - Aa = Aa.prototype; - Ka = oa(Ka, { type: "areaspline", getStackPoints: Aa.getStackPoints, getGraphPath: Aa.getGraphPath, setStackCliffs: Aa.setStackCliffs, drawGraph: Aa.drawGraph, drawLegendSymbol: da.drawRectangle }); - I.areaspline = Ka; - X.column = D(ga, { - borderColor: "#FFFFFF", - borderRadius: 0, - groupPadding: 0.2, - marker: null, - pointPadding: 0.1, - minPointLength: 0, - cropThreshold: 50, - pointRange: null, - states: { hover: { brightness: 0.1, shadow: !1, halo: !1 }, select: { color: "#C0C0C0", borderColor: "#000000", shadow: !1 } }, - dataLabels: { align: null, verticalAlign: null, y: null }, - softThreshold: !1, - startFromThreshold: !0, - stickyTracking: !1, - tooltip: { distance: 6 }, - threshold: 0 - }); - Ka = oa(P, { - type: "column", - pointAttrToOptions: { stroke: "borderColor", fill: "color", r: "borderRadius" }, - cropShoulder: 0, - directTouch: !0, - trackerGroups: ["group", "dataLabelsGroup"], - negStacks: !0, - init: function() { - P.prototype.init.apply(this, arguments); - var a = this, - b = a.chart; - b.hasRendered && o(b.series, function(b) { - if (b.type === a.type) b.isDirty = !0 }) - }, - getColumnMetrics: function() { - var a = this, - b = a.options, - c = a.xAxis, - d = a.yAxis, - e = c.reversed, - f, g = {}, - h = 0; - b.grouping === !1 ? h = 1 : o(a.chart.series, function(b) { - var c = b.options, - e = b.yAxis, - i; - if (b.type === a.type && b.visible && d.len === e.len && d.pos === e.pos) c.stacking ? (f = b.stackKey, g[f] === x && (g[f] = h++), i = g[f]) : c.grouping !== !1 && (i = h++), b.columnIndex = i }); - var i = E(T(c.transA) * (c.ordinalSlope || b.pointRange || c.closestPointRange || c.tickInterval || 1), c.len), - j = - i * b.groupPadding, - k = (i - 2 * j) / h, - b = E(b.maxPointWidth || c.len, q(b.pointWidth, k * (1 - 2 * b.pointPadding))); - a.columnMetrics = { width: b, offset: (k - b) / 2 + (j + ((a.columnIndex || 0) + (e ? 1 : 0)) * k - i / 2) * (e ? -1 : 1) }; - return a.columnMetrics - }, - crispCol: function(a, b, c, d) { - var e = this.chart, - f = this.borderWidth, - g = -(f % 2 ? 0.5 : 0), - f = f % 2 ? 0.5 : 1; - e.inverted && e.renderer.isVML && (f += 1); - c = Math.round(a + c) + g; - a = Math.round(a) + g; - c -= a; - d = Math.round(b + d) + f; - g = T(b) <= 0.5 && d > 0.5; - b = Math.round(b) + f; - d -= b; - g && d && (b -= 1, d += 1); - return { x: a, y: b, width: c, height: d } }, - translate: function() { - var a = - this, - b = a.chart, - c = a.options, - d = a.borderWidth = q(c.borderWidth, a.closestPointRange * a.xAxis.transA < 2 ? 0 : 1), - e = a.yAxis, - f = a.translatedThreshold = e.getThreshold(c.threshold), - g = q(c.minPointLength, 5), - h = a.getColumnMetrics(), - i = h.width, - j = a.barW = y(i, 1 + 2 * d), - k = a.pointXOffset = h.offset; - b.inverted && (f -= 0.5); - c.pointPadding && (j = Ga(j)); - P.prototype.translate.apply(a); - o(a.points, function(c) { - var d = E(q(c.yBottom, f), 9E4), - h = 999 + T(d), - h = E(y(-h, c.plotY), e.len + h), - p = c.plotX + k, - r = j, - o = E(h, d), - t, u = y(h, d) - o; - T(u) < g && g && (u = g, t = !e.reversed && - !c.negative || e.reversed && c.negative, o = T(o - f) > g ? d - g : f - (t ? g : 0)); - c.barX = p; - c.pointWidth = i; - c.tooltipPos = b.inverted ? [e.len + e.pos - b.plotLeft - h, a.xAxis.len - p - r / 2, u] : [p + r / 2, h + e.pos - b.plotTop, u]; - c.shapeType = "rect"; - c.shapeArgs = a.crispCol(p, o, r, u) - }) - }, - getSymbol: va, - drawLegendSymbol: da.drawRectangle, - drawGraph: va, - drawPoints: function() { - var a = this, - b = this.chart, - c = a.options, - d = b.renderer, - e = c.animationLimit || 250, - f, g; - o(a.points, function(h) { - var i = h.graphic, - j; - if (z(h.plotY) && h.y !== null) f = h.shapeArgs, j = t(a.borderWidth) ? { "stroke-width": a.borderWidth } : {}, g = h.pointAttr[h.selected ? "select" : ""] || a.pointAttr[""], i ? (Qa(i), i.attr(j).attr(g)[b.pointCount < e ? "animate" : "attr"](D(f))) : h.graphic = d[h.shapeType](f).attr(j).attr(g).add(h.group || a.group).shadow(c.shadow, null, c.stacking && !c.borderRadius); - else if (i) h.graphic = i.destroy() - }) - }, - animate: function(a) { - var b = this, - c = this.yAxis, - d = b.options, - e = this.chart.inverted, - f = {}; - if (ma) a ? (f.scaleY = 0.001, a = E(c.pos + c.len, y(c.pos, c.toPixels(d.threshold))), e ? f.translateX = a - c.len : f.translateY = a, b.group.attr(f)) : (f[e ? "translateX" : - "translateY"] = c.pos, b.group.animate(f, v(ib(b.options.animation), { step: function(a, c) { b.group.attr({ scaleY: y(0.001, c.pos) }) } })), b.animate = null) - }, - remove: function() { - var a = this, - b = a.chart; - b.hasRendered && o(b.series, function(b) { - if (b.type === a.type) b.isDirty = !0 }); - P.prototype.remove.apply(a, arguments) } - }); - I.column = Ka; - X.bar = D(X.column); - Aa = oa(Ka, { type: "bar", inverted: !0 }); - I.bar = Aa; - X.scatter = D(ga, { - lineWidth: 0, - marker: { enabled: !0 }, - tooltip: { - headerFormat: '\u25cf {series.name}
', - pointFormat: "x: {point.x}
y: {point.y}
" - } - }); - Aa = oa(P, { type: "scatter", sorted: !1, requireSorting: !1, noSharedTooltip: !0, trackerGroups: ["group", "markerGroup", "dataLabelsGroup"], takeOrdinalPosition: !1, kdDimensions: 2, drawGraph: function() { this.options.lineWidth && P.prototype.drawGraph.call(this) } }); - I.scatter = Aa; - X.pie = D(ga, { - borderColor: "#FFFFFF", - borderWidth: 1, - center: [null, null], - clip: !1, - colorByPoint: !0, - dataLabels: { - distance: 30, - enabled: !0, - formatter: function() { - return this.y === null ? void 0 : this.point.name }, - x: 0 - }, - ignoreHiddenPoint: !0, - legendType: "point", - marker: null, - size: null, - showInLegend: !1, - slicedOffset: 10, - states: { hover: { brightness: 0.1, shadow: !1 } }, - stickyTracking: !1, - tooltip: { followPointer: !0 } - }); - ga = { - type: "pie", - isCartesian: !1, - pointClass: oa(Ja, { - init: function() { Ja.prototype.init.apply(this, arguments); - var a = this, - b; - a.name = q(a.name, "Slice"); - b = function(b) { a.slice(b.type === "select") }; - G(a, "select", b); - G(a, "unselect", b); - return a }, - setVisible: function(a, b) { - var c = this, - d = c.series, - e = d.chart, - f = d.options.ignoreHiddenPoint, - b = q(b, f); - if (a !== c.visible) { c.visible = c.options.visible = a = a === x ? !c.visible : a; - d.options.data[qa(c, d.data)] = c.options; - o(["graphic", "dataLabel", "connector", "shadowGroup"], function(b) { - if (c[b]) c[b][a ? "show" : "hide"](!0) }); - c.legendItem && e.legend.colorizeItem(c, a);!a && c.state === "hover" && c.setState(""); - if (f) d.isDirty = !0; - b && e.redraw() } - }, - slice: function(a, b, c) { - var d = this.series; - cb(c, d.chart); - q(b, !0); - this.sliced = this.options.sliced = a = t(a) ? a : !this.sliced; - d.options.data[qa(this, d.data)] = this.options; - a = a ? this.slicedTranslation : { translateX: 0, translateY: 0 }; - this.graphic.animate(a); - this.shadowGroup && this.shadowGroup.animate(a) - }, - haloPath: function(a) { - var b = this.shapeArgs, - c = this.series.chart; - return this.sliced || !this.visible ? [] : this.series.chart.renderer.symbols.arc(c.plotLeft + b.x, c.plotTop + b.y, b.r + a, b.r + a, { innerR: this.shapeArgs.r, start: b.start, end: b.end }) } - }), - requireSorting: !1, - directTouch: !0, - noSharedTooltip: !0, - trackerGroups: ["group", "dataLabelsGroup"], - axisTypes: [], - pointAttrToOptions: { - stroke: "borderColor", - "stroke-width": "borderWidth", - fill: "color" - }, - animate: function(a) { - var b = this, - c = b.points, - d = b.startAngleRad; - if (!a) o(c, function(a) { - var c = a.graphic, - g = a.shapeArgs; - c && (c.attr({ r: a.startR || b.center[3] / 2, start: d, end: d }), c.animate({ r: g.r, start: g.start, end: g.end }, b.options.animation)) }), b.animate = null }, - updateTotals: function() { - var a, b = 0, - c = this.points, - d = c.length, - e, f = this.options.ignoreHiddenPoint; - for (a = 0; a < d; a++) { e = c[a]; - if (e.y < 0) e.y = null; - b += f && !e.visible ? 0 : e.y } - this.total = b; - for (a = 0; a < d; a++) e = c[a], e.percentage = b > 0 && (e.visible || !f) ? e.y / b * 100 : - 0, e.total = b - }, - generatePoints: function() { P.prototype.generatePoints.call(this); - this.updateTotals() }, - translate: function(a) { - this.generatePoints(); - var b = 0, - c = this.options, - d = c.slicedOffset, - e = d + c.borderWidth, - f, g, h, i = c.startAngle || 0, - j = this.startAngleRad = Ca / 180 * (i - 90), - i = (this.endAngleRad = Ca / 180 * (q(c.endAngle, i + 360) - 90)) - j, - k = this.points, - l = c.dataLabels.distance, - c = c.ignoreHiddenPoint, - m, n = k.length, - p; - if (!a) this.center = a = this.getCenter(); - this.getX = function(b, c) { - h = aa.asin(E((b - a[1]) / (a[2] / 2 + l), 1)); - return a[0] + (c ? - -1 : 1) * fa(h) * (a[2] / 2 + l) - }; - for (m = 0; m < n; m++) { - p = k[m]; - f = j + b * i; - if (!c || p.visible) b += p.percentage / 100; - g = j + b * i; - p.shapeType = "arc"; - p.shapeArgs = { x: a[0], y: a[1], r: a[2] / 2, innerR: a[3] / 2, start: A(f * 1E3) / 1E3, end: A(g * 1E3) / 1E3 }; - h = (g + f) / 2; - h > 1.5 * Ca ? h -= 2 * Ca : h < -Ca / 2 && (h += 2 * Ca); - p.slicedTranslation = { translateX: A(fa(h) * d), translateY: A(na(h) * d) }; - f = fa(h) * a[2] / 2; - g = na(h) * a[2] / 2; - p.tooltipPos = [a[0] + f * 0.7, a[1] + g * 0.7]; - p.half = h < -Ca / 2 || h > Ca / 2 ? 1 : 0; - p.angle = h; - e = E(e, l / 2); - p.labelPos = [a[0] + f + fa(h) * l, a[1] + g + na(h) * l, a[0] + f + fa(h) * e, a[1] + g + na(h) * - e, a[0] + f, a[1] + g, l < 0 ? "center" : p.half ? "right" : "left", h - ] - } - }, - drawGraph: null, - drawPoints: function() { - var a = this, - b = a.chart.renderer, - c, d, e = a.options.shadow, - f, g, h, i; - if (e && !a.shadowGroup) a.shadowGroup = b.g("shadow").add(a.group); - o(a.points, function(j) { - if (j.y !== null) { - d = j.graphic; - h = j.shapeArgs; - f = j.shadowGroup; - g = j.pointAttr[j.selected ? "select" : ""]; - if (!g.stroke) g.stroke = g.fill; - if (e && !f) f = j.shadowGroup = b.g("shadow").add(a.shadowGroup); - c = j.sliced ? j.slicedTranslation : { translateX: 0, translateY: 0 }; - f && f.attr(c); - if (d) d.setRadialReference(a.center).attr(g).animate(v(h, - c)); - else { i = { "stroke-linejoin": "round" }; - if (!j.visible) i.visibility = "hidden"; - j.graphic = d = b[j.shapeType](h).setRadialReference(a.center).attr(g).attr(i).attr(c).add(a.group).shadow(e, f) } - } - }) - }, - searchPoint: va, - sortByAngle: function(a, b) { a.sort(function(a, d) { - return a.angle !== void 0 && (d.angle - a.angle) * b }) }, - drawLegendSymbol: da.drawRectangle, - getCenter: ec.getCenter, - getSymbol: va - }; - ga = oa(P, ga); - I.pie = ga; - P.prototype.drawDataLabels = function() { - var a = this, - b = a.options, - c = b.cursor, - d = b.dataLabels, - e = a.points, - f, g, h = a.hasRendered || - 0, - i, j, k = q(d.defer, !0), - l = a.chart.renderer; - if (d.enabled || a._hasPointLabels) a.dlProcessOptions && a.dlProcessOptions(d), j = a.plotGroup("dataLabelsGroup", "data-labels", k && !h ? "hidden" : "visible", d.zIndex || 6), k && (j.attr({ opacity: +h }), h || G(a, "afterAnimate", function() { a.visible && j.show(!0); - j[b.animation ? "animate" : "attr"]({ opacity: 1 }, { duration: 200 }) })), g = d, o(e, function(e) { - var h, k = e.dataLabel, - r, o, y = e.connector, - u = !0, - w, F = {}; - f = e.dlOptions || e.options && e.options.dataLabels; - h = q(f && f.enabled, g.enabled) && e.y !== null; - if (k && - !h) e.dataLabel = k.destroy(); - else if (h) { - d = D(g, f); - w = d.style; - h = d.rotation; - r = e.getLabelConfig(); - i = d.format ? Ma(d.format, r) : d.formatter.call(r, d); - w.color = q(d.color, w.color, a.color, "black"); - if (k) - if (t(i)) k.attr({ text: i }), u = !1; - else { - if (e.dataLabel = k = k.destroy(), y) e.connector = y.destroy() } - else if (t(i)) { - k = { fill: d.backgroundColor, stroke: d.borderColor, "stroke-width": d.borderWidth, r: d.borderRadius || 0, rotation: h, padding: d.padding, zIndex: 1 }; - if (w.color === "contrast") F.color = d.inside || d.distance < 0 || b.stacking ? l.getContrast(e.color || - a.color) : "#000000"; - if (c) F.cursor = c; - for (o in k) k[o] === x && delete k[o]; - k = e.dataLabel = l[h ? "text" : "label"](i, 0, -9999, d.shape, null, null, d.useHTML).attr(k).css(v(w, F)).add(j).shadow(d.shadow) - } - k && a.alignDataLabel(e, k, d, null, u) - } - }) - }; - P.prototype.alignDataLabel = function(a, b, c, d, e) { - var f = this.chart, - g = f.inverted, - h = q(a.plotX, -9999), - i = q(a.plotY, -9999), - j = b.getBBox(), - k = f.renderer.fontMetrics(c.style.fontSize).b, - l = c.rotation, - m = c.align, - n = this.visible && (a.series.forceDL || f.isInsidePlot(h, A(i), g) || d && f.isInsidePlot(h, - g ? d.x + 1 : d.y + d.height - 1, g)), - p = q(c.overflow, "justify") === "justify"; - if (n) d = v({ x: g ? f.plotWidth - i : h, y: A(g ? f.plotHeight - h : i), width: 0, height: 0 }, d), v(c, { width: j.width, height: j.height }), l ? (p = !1, g = f.renderer.rotCorr(k, l), g = { x: d.x + c.x + d.width / 2 + g.x, y: d.y + c.y + { top: 0, middle: 0.5, bottom: 1 }[c.verticalAlign] * d.height }, b[e ? "attr" : "animate"](g).attr({ align: m }), h = (l + 720) % 360, h = h > 180 && h < 360, m === "left" ? g.y -= h ? j.height : 0 : m === "center" ? (g.x -= j.width / 2, g.y -= j.height / 2) : m === "right" && (g.x -= j.width, g.y -= h ? 0 : j.height)) : (b.align(c, - null, d), g = b.alignAttr), p ? this.justifyDataLabel(b, c, g, j, d, e) : q(c.crop, !0) && (n = f.isInsidePlot(g.x, g.y) && f.isInsidePlot(g.x + j.width, g.y + j.height)), c.shape && !l && b.attr({ anchorX: a.plotX, anchorY: a.plotY }); - if (!n) Qa(b), b.attr({ y: -9999 }), b.placed = !1 - }; - P.prototype.justifyDataLabel = function(a, b, c, d, e, f) { - var g = this.chart, - h = b.align, - i = b.verticalAlign, - j, k, l = a.box ? 0 : a.padding || 0; - j = c.x + l; - if (j < 0) h === "right" ? b.align = "left" : b.x = -j, k = !0; - j = c.x + d.width - l; - if (j > g.plotWidth) h === "left" ? b.align = "right" : b.x = g.plotWidth - j, k = !0; - j = c.y + l; - if (j < 0) i === "bottom" ? b.verticalAlign = "top" : b.y = -j, k = !0; - j = c.y + d.height - l; - if (j > g.plotHeight) i === "top" ? b.verticalAlign = "bottom" : b.y = g.plotHeight - j, k = !0; - if (k) a.placed = !f, a.align(b, null, e) - }; - if (I.pie) I.pie.prototype.drawDataLabels = function() { - var a = this, - b = a.data, - c, d = a.chart, - e = a.options.dataLabels, - f = q(e.connectorPadding, 10), - g = q(e.connectorWidth, 1), - h = d.plotWidth, - i = d.plotHeight, - j, k, l = q(e.softConnector, !0), - m = e.distance, - n = a.center, - p = n[2] / 2, - r = n[1], - s = m > 0, - t, u, w, F = [ - [], - [] - ], - x, v, B, D, z, C = [0, 0, 0, 0], - G = function(a, - b) { - return b.y - a.y }; - if (a.visible && (e.enabled || a._hasPointLabels)) { - P.prototype.drawDataLabels.apply(a); - o(b, function(a) { - if (a.dataLabel && a.visible) F[a.half].push(a), a.dataLabel._pos = null }); - for (D = 2; D--;) { - var J = [], - M = [], - H = F[D], - K = H.length, - I; - if (K) { - a.sortByAngle(H, D - 0.5); - for (z = b = 0; !b && H[z];) b = H[z] && H[z].dataLabel && (H[z].dataLabel.getBBox().height || 21), z++; - if (m > 0) { - u = E(r + p + m, d.plotHeight); - for (z = y(0, r - p - m); z <= u; z += b) J.push(z); - u = J.length; - if (K > u) { - c = [].concat(H); - c.sort(G); - for (z = K; z--;) c[z].rank = z; - for (z = K; z--;) H[z].rank >= - u && H.splice(z, 1); - K = H.length - } - for (z = 0; z < K; z++) { c = H[z]; - w = c.labelPos; - c = 9999; - var O, N; - for (N = 0; N < u; N++) O = T(J[N] - w[1]), O < c && (c = O, I = N); - if (I < z && J[z] !== null) I = z; - else - for (u < K - z + I && J[z] !== null && (I = u - K + z); J[I] === null;) I++; - M.push({ i: I, y: J[I] }); - J[I] = null } - M.sort(G) - } - for (z = 0; z < K; z++) { - c = H[z]; - w = c.labelPos; - t = c.dataLabel; - B = c.visible === !1 ? "hidden" : "inherit"; - c = w[1]; - if (m > 0) { - if (u = M.pop(), I = u.i, v = u.y, c > v && J[I + 1] !== null || c < v && J[I - 1] !== null) v = E(y(0, c), d.plotHeight) } else v = c; - x = e.justify ? n[0] + (D ? -1 : 1) * (p + m) : a.getX(v === r - p - m || v === - r + p + m ? c : v, D); - t._attr = { visibility: B, align: w[6] }; - t._pos = { x: x + e.x + ({ left: f, right: -f }[w[6]] || 0), y: v + e.y - 10 }; - t.connX = x; - t.connY = v; - if (this.options.size === null) u = t.width, x - u < f ? C[3] = y(A(u - x + f), C[3]) : x + u > h - f && (C[1] = y(A(x + u - h + f), C[1])), v - b / 2 < 0 ? C[0] = y(A(-v + b / 2), C[0]) : v + b / 2 > i && (C[2] = y(A(v + b / 2 - i), C[2])) - } - } - } - if (Fa(C) === 0 || this.verifyDataLabelOverflow(C)) this.placeDataLabels(), s && g && o(this.points, function(b) { - j = b.connector; - w = b.labelPos; - if ((t = b.dataLabel) && t._pos && b.visible) B = t._attr.visibility, x = t.connX, v = t.connY, k = - l ? [W, x + (w[6] === "left" ? 5 : -5), v, "C", x, v, 2 * w[2] - w[4], 2 * w[3] - w[5], w[2], w[3], R, w[4], w[5]] : [W, x + (w[6] === "left" ? 5 : -5), v, R, w[2], w[3], R, w[4], w[5]], j ? (j.animate({ d: k }), j.attr("visibility", B)) : b.connector = j = a.chart.renderer.path(k).attr({ "stroke-width": g, stroke: e.connectorColor || b.color || "#606060", visibility: B }).add(a.dataLabelsGroup); - else if (j) b.connector = j.destroy() - }) - } - }, I.pie.prototype.placeDataLabels = function() { - o(this.points, function(a) { - var b = a.dataLabel; - if (b && a.visible)(a = b._pos) ? (b.attr(b._attr), b[b.moved ? - "animate" : "attr"](a), b.moved = !0) : b && b.attr({ y: -9999 }) - }) - }, I.pie.prototype.alignDataLabel = va, I.pie.prototype.verifyDataLabelOverflow = function(a) { - var b = this.center, - c = this.options, - d = c.center, - e = c.minSize || 80, - f = e, - g; - d[0] !== null ? f = y(b[2] - y(a[1], a[3]), e) : (f = y(b[2] - a[1] - a[3], e), b[0] += (a[3] - a[1]) / 2); - d[1] !== null ? f = y(E(f, b[2] - y(a[0], a[2])), e) : (f = y(E(f, b[2] - a[0] - a[2]), e), b[1] += (a[0] - a[2]) / 2); - f < b[2] ? (b[2] = f, b[3] = Math.min(/%$/.test(c.innerSize || 0) ? f * parseFloat(c.innerSize || 0) / 100 : parseFloat(c.innerSize || 0), f), this.translate(b), - this.drawDataLabels && this.drawDataLabels()) : g = !0; - return g - }; - if (I.column) I.column.prototype.alignDataLabel = function(a, b, c, d, e) { - var f = this.chart.inverted, - g = a.series, - h = a.dlBox || a.shapeArgs, - i = q(a.below, a.plotY > q(this.translatedThreshold, g.yAxis.len)), - j = q(c.inside, !!this.options.stacking); - if (h) { - d = D(h); - if (d.y < 0) d.height += d.y, d.y = 0; - h = d.y + d.height - g.yAxis.len; - h > 0 && (d.height -= h); - f && (d = { x: g.yAxis.len - d.y - d.height, y: g.xAxis.len - d.x - d.width, width: d.height, height: d.width }); - if (!j) f ? (d.x += i ? 0 : d.width, d.width = 0) : - (d.y += i ? d.height : 0, d.height = 0) - } - c.align = q(c.align, !f || j ? "center" : i ? "right" : "left"); - c.verticalAlign = q(c.verticalAlign, f || j ? "middle" : i ? "top" : "bottom"); - P.prototype.alignDataLabel.call(this, a, b, c, d, e) - }; - (function(a) { - var b = a.Chart, - c = a.each, - d = a.pick, - e = a.addEvent; - b.prototype.callbacks.push(function(a) { - function b() { - var e = []; - c(a.series, function(a) { - var b = a.options.dataLabels, - f = a.dataLabelCollections || ["dataLabel"]; - (b.enabled || a._hasPointLabels) && !b.allowOverlap && a.visible && c(f, function(b) { - c(a.points, function(a) { - if (a[b]) a[b].labelrank = - d(a.labelrank, a.shapeArgs && a.shapeArgs.height), e.push(a[b]) - }) - }) - }); - a.hideOverlappingLabels(e) - } - b(); - e(a, "redraw", b) - }); - b.prototype.hideOverlappingLabels = function(a) { - var b = a.length, - d, e, j, k, l, m, n, p, r; - for (e = 0; e < b; e++) - if (d = a[e]) d.oldOpacity = d.opacity, d.newOpacity = 1; - a.sort(function(a, b) { - return (b.labelrank || 0) - (a.labelrank || 0) }); - for (e = 0; e < b; e++) { - j = a[e]; - for (d = e + 1; d < b; ++d) - if (k = a[d], j && k && j.placed && k.placed && j.newOpacity !== 0 && k.newOpacity !== 0 && (l = j.alignAttr, m = k.alignAttr, n = j.parentGroup, p = k.parentGroup, r = 2 * (j.box ? - 0 : j.padding), l = !(m.x + p.translateX > l.x + n.translateX + (j.width - r) || m.x + p.translateX + (k.width - r) < l.x + n.translateX || m.y + p.translateY > l.y + n.translateY + (j.height - r) || m.y + p.translateY + (k.height - r) < l.y + n.translateY)))(j.labelrank < k.labelrank ? j : k).newOpacity = 0 - } - c(a, function(a) { - var b, c; - if (a) { c = a.newOpacity; - if (a.oldOpacity !== c && a.placed) c ? a.show(!0) : b = function() { a.hide() }, a.alignAttr.opacity = c, a[a.isOld ? "animate" : "attr"](a.alignAttr, null, b); - a.isOld = !0 } }) - } - })(B); - var ob = B.TrackerMixin = { - drawTrackerPoint: function() { - var a = - this, - b = a.chart, - c = b.pointer, - d = a.options.cursor, - e = d && { cursor: d }, - f = function(a) { - for (var c = a.target, d; c && !d;) d = c.point, c = c.parentNode; - if (d !== x && d !== b.hoverPoint) d.onMouseOver(a) }; - o(a.points, function(a) { - if (a.graphic) a.graphic.element.point = a; - if (a.dataLabel) a.dataLabel.element.point = a }); - if (!a._hasTracking) o(a.trackerGroups, function(b) { - if (a[b] && (a[b].addClass("highcharts-tracker").on("mouseover", f).on("mouseout", function(a) { c.onTrackerMouseOut(a) }).css(e), $a)) a[b].on("touchstart", f) }), a._hasTracking = !0 - }, - drawTrackerGraph: function() { - var a = this, - b = a.options, - c = b.trackByArea, - d = [].concat(c ? a.areaPath : a.graphPath), - e = d.length, - f = a.chart, - g = f.pointer, - h = f.renderer, - i = f.options.tooltip.snap, - j = a.tracker, - k = b.cursor, - l = k && { cursor: k }, - m = function() { - if (f.hoverSeries !== a) a.onMouseOver() }, - n = "rgba(192,192,192," + (ma ? 1.0E-4 : 0.002) + ")"; - if (e && !c) - for (k = e + 1; k--;) d[k] === W && d.splice(k + 1, 0, d[k + 1] - i, d[k + 2], R), (k && d[k] === W || k === e) && d.splice(k, 0, R, d[k - 2] + i, d[k - 1]); - j ? j.attr({ d: d }) : (a.tracker = h.path(d).attr({ - "stroke-linejoin": "round", - visibility: a.visible ? "visible" : "hidden", - stroke: n, - fill: c ? n : "none", - "stroke-width": b.lineWidth + (c ? 0 : 2 * i), - zIndex: 2 - }).add(a.group), o([a.tracker, a.markerGroup], function(a) { a.addClass("highcharts-tracker").on("mouseover", m).on("mouseout", function(a) { g.onTrackerMouseOut(a) }).css(l); - if ($a) a.on("touchstart", m) })) - } - }; - if (I.column) Ka.prototype.drawTracker = ob.drawTrackerPoint; - if (I.pie) I.pie.prototype.drawTracker = ob.drawTrackerPoint; - if (I.scatter) Aa.prototype.drawTracker = ob.drawTrackerPoint; - v(xb.prototype, { - setItemEvents: function(a, - b, c, d, e) { - var f = this; - (c ? b : a.legendGroup).on("mouseover", function() { a.setState("hover"); - b.css(f.options.itemHoverStyle) }).on("mouseout", function() { b.css(a.visible ? d : e); - a.setState() }).on("click", function(b) { - var c = function() { a.setVisible && a.setVisible() }, - b = { browserEvent: b }; - a.firePointEvent ? a.firePointEvent("legendItemClick", b, c) : K(a, "legendItemClick", b, c) }) }, - createCheckboxForItem: function(a) { - a.checkbox = ia("input", { type: "checkbox", checked: a.selected, defaultChecked: a.selected }, this.options.itemCheckboxStyle, - this.chart.container); - G(a.checkbox, "click", function(b) { K(a.series || a, "checkboxClick", { checked: b.target.checked, item: a }, function() { a.select() }) }) - } - }); - Q.legend.itemStyle.cursor = "pointer"; - v(Da.prototype, { - showResetZoom: function() { - var a = this, - b = Q.lang, - c = a.options.chart.resetZoomButton, - d = c.theme, - e = d.states, - f = c.relativeTo === "chart" ? null : "plotBox"; - this.resetZoomButton = a.renderer.button(b.resetZoom, null, null, function() { a.zoomOut() }, d, e && e.hover).attr({ align: c.position.align, title: b.resetZoomTitle }).add().align(c.position, !1, f) - }, - zoomOut: function() { - var a = this; - K(a, "selection", { resetSelection: !0 }, function() { a.zoom() }) }, - zoom: function(a) { - var b, c = this.pointer, - d = !1, - e; - !a || a.resetSelection ? o(this.axes, function(a) { b = a.zoom() }) : o(a.xAxis.concat(a.yAxis), function(a) { - var e = a.axis, - h = e.isXAxis; - if (c[h ? "zoomX" : "zoomY"] || c[h ? "pinchX" : "pinchY"]) b = e.zoom(a.min, a.max), e.displayBtn && (d = !0) }); - e = this.resetZoomButton; - if (d && !e) this.showResetZoom(); - else if (!d && ha(e)) this.resetZoomButton = e.destroy(); - b && this.redraw(q(this.options.chart.animation, - a && a.animation, this.pointCount < 100)) - }, - pan: function(a, b) { - var c = this, - d = c.hoverPoints, - e; - d && o(d, function(a) { a.setState() }); - o(b === "xy" ? [1, 0] : [1], function(b) { - var b = c[b ? "xAxis" : "yAxis"][0], - d = b.horiz, - h = a[d ? "chartX" : "chartY"], - d = d ? "mouseDownX" : "mouseDownY", - i = c[d], - j = (b.pointRange || 0) / 2, - k = b.getExtremes(), - l = b.toValue(i - h, !0) + j, - j = b.toValue(i + b.len - h, !0) - j, - i = i > h; - if (b.series.length && (i || l > E(k.dataMin, k.min)) && (!i || j < y(k.dataMax, k.max))) b.setExtremes(l, j, !1, !1, { trigger: "pan" }), e = !0; - c[d] = h }); - e && c.redraw(!1); - O(c.container, { cursor: "move" }) - } - }); - v(Ja.prototype, { - select: function(a, b) { - var c = this, - d = c.series, - e = d.chart, - a = q(a, !c.selected); - c.firePointEvent(a ? "select" : "unselect", { accumulate: b }, function() { c.selected = c.options.selected = a; - d.options.data[qa(c, d.data)] = c.options; - c.setState(a && "select"); - b || o(e.getSelectedPoints(), function(a) { - if (a.selected && a !== c) a.selected = a.options.selected = !1, d.options.data[qa(a, d.data)] = a.options, a.setState(""), a.firePointEvent("unselect") }) }) }, - onMouseOver: function(a, b) { - var c = this.series, - d = c.chart, - e = d.tooltip, - f = d.hoverPoint; - if (d.hoverSeries !== c) c.onMouseOver(); - if (f && f !== this) f.onMouseOut(); - if (this.series && (this.firePointEvent("mouseOver"), e && (!e.shared || c.noSharedTooltip) && e.refresh(this, a), this.setState("hover"), !b)) d.hoverPoint = this - }, - onMouseOut: function() { - var a = this.series.chart, - b = a.hoverPoints; - this.firePointEvent("mouseOut"); - if (!b || qa(this, b) === -1) this.setState(), a.hoverPoint = null }, - importEvents: function() { - if (!this.hasImportedEvents) { - var a = D(this.series.options.point, this.options).events, - b; - this.events = a; - for (b in a) G(this, b, a[b]); - this.hasImportedEvents = !0 - } - }, - setState: function(a, b) { - var c = Y(this.plotX), - d = this.plotY, - e = this.series, - f = e.options.states, - g = X[e.type].marker && e.options.marker, - h = g && !g.enabled, - i = g && g.states[a], - j = i && i.enabled === !1, - k = e.stateMarkerGraphic, - l = this.marker || {}, - m = e.chart, - n = e.halo, - p, a = a || ""; - p = this.pointAttr[a] || e.pointAttr[a]; - if (!(a === this.state && !b || this.selected && a !== "select" || f[a] && f[a].enabled === !1 || a && (j || h && i.enabled === !1) || a && l.states && l.states[a] && l.states[a].enabled === - !1)) { - if (this.graphic) g = g && this.graphic.symbolName && p.r, this.graphic.attr(D(p, g ? { x: c - g, y: d - g, width: 2 * g, height: 2 * g } : {})), k && k.hide(); - else { - if (a && i) - if (g = i.radius, l = l.symbol || e.symbol, k && k.currentSymbol !== l && (k = k.destroy()), k) k[b ? "animate" : "attr"]({ x: c - g, y: d - g }); - else if (l) e.stateMarkerGraphic = k = m.renderer.symbol(l, c - g, d - g, 2 * g, 2 * g).attr(p).add(e.markerGroup), k.currentSymbol = l; - if (k) k[a && m.isInsidePlot(c, d, m.inverted) ? "show" : "hide"](), k.element.point = this } - if ((c = f[a] && f[a].halo) && c.size) { - if (!n) e.halo = n = m.renderer.path().add(m.seriesGroup); - n.attr(v({ fill: this.color || e.color, "fill-opacity": c.opacity, zIndex: -1 }, c.attributes))[b ? "animate" : "attr"]({ d: this.haloPath(c.size) }) - } else n && n.attr({ d: [] }); - this.state = a - } - }, - haloPath: function(a) { - var b = this.series, - c = b.chart, - d = b.getPlotBox(), - e = c.inverted, - f = Math.floor(this.plotX); - return c.renderer.symbols.circle(d.translateX + (e ? b.yAxis.len - this.plotY : f) - a, d.translateY + (e ? b.xAxis.len - f : this.plotY) - a, a * 2, a * 2) } - }); - v(P.prototype, { - onMouseOver: function() { - var a = this.chart, - b = a.hoverSeries; - if (b && b !== this) b.onMouseOut(); - this.options.events.mouseOver && K(this, "mouseOver"); - this.setState("hover"); - a.hoverSeries = this - }, - onMouseOut: function() { - var a = this.options, - b = this.chart, - c = b.tooltip, - d = b.hoverPoint; - b.hoverSeries = null; - if (d) d.onMouseOut(); - this && a.events.mouseOut && K(this, "mouseOut"); - c && !a.stickyTracking && (!c.shared || this.noSharedTooltip) && c.hide(); - this.setState() }, - setState: function(a) { - var b = this.options, - c = this.graph, - d = b.states, - e = b.lineWidth, - b = 0, - a = a || ""; - if (this.state !== a && (this.state = a, !(d[a] && d[a].enabled === !1) && (a && (e = d[a].lineWidth || - e + (d[a].lineWidthPlus || 0)), c && !c.dashstyle))) { a = { "stroke-width": e }; - for (c.attr(a); this["zoneGraph" + b];) this["zoneGraph" + b].attr(a), b += 1 } - }, - setVisible: function(a, b) { - var c = this, - d = c.chart, - e = c.legendItem, - f, g = d.options.chart.ignoreHiddenSeries, - h = c.visible; - f = (c.visible = a = c.userOptions.visible = a === x ? !h : a) ? "show" : "hide"; - o(["group", "dataLabelsGroup", "markerGroup", "tracker"], function(a) { - if (c[a]) c[a][f]() }); - if (d.hoverSeries === c || (d.hoverPoint && d.hoverPoint.series) === c) c.onMouseOut(); - e && d.legend.colorizeItem(c, - a); - c.isDirty = !0; - c.options.stacking && o(d.series, function(a) { - if (a.options.stacking && a.visible) a.isDirty = !0 }); - o(c.linkedSeries, function(b) { b.setVisible(a, !1) }); - if (g) d.isDirtyBox = !0; - b !== !1 && d.redraw(); - K(c, f) - }, - show: function() { this.setVisible(!0) }, - hide: function() { this.setVisible(!1) }, - select: function(a) { this.selected = a = a === x ? !this.selected : a; - if (this.checkbox) this.checkbox.checked = a; - K(this, a ? "select" : "unselect") }, - drawTracker: ob.drawTrackerGraph - }); - S(P.prototype, "init", function(a) { - var b; - a.apply(this, Array.prototype.slice.call(arguments, - 1)); - (b = this.xAxis) && b.options.ordinal && G(this, "updatedData", function() { delete b.ordinalIndex }) - }); - S(J.prototype, "getTimeTicks", function(a, b, c, d, e, f, g, h) { - var i = 0, - j, k, l = {}, - m, n, p, o = [], - q = -Number.MAX_VALUE, - v = this.options.tickPixelInterval; - if (!this.options.ordinal && !this.options.breaks || !f || f.length < 3 || c === x) return a.call(this, b, c, d, e); - n = f.length; - for (j = 0; j < n; j++) { - p = j && f[j - 1] > d; - f[j] < c && (i = j); - if (j === n - 1 || f[j + 1] - f[j] > g * 5 || p) { - if (f[j] > q) { - for (k = a.call(this, b, f[i], f[j], e); k.length && k[0] <= q;) k.shift(); - k.length && - (q = k[k.length - 1]); - o = o.concat(k) - } - i = j + 1 - } - if (p) break - } - a = k.info; - if (h && a.unitRange <= N.hour) { j = o.length - 1; - for (i = 1; i < j; i++) pa("%d", o[i]) !== pa("%d", o[i - 1]) && (l[o[i]] = "day", m = !0); - m && (l[o[0]] = "day"); - a.higherRanks = l } - o.info = a; - if (h && t(v)) { h = a = o.length; - j = []; - var u; - for (m = []; h--;) i = this.translate(o[h]), u && (m[h] = u - i), j[h] = u = i; - m.sort(); - m = m[Y(m.length / 2)]; - m < v * 0.6 && (m = null); - h = o[a - 1] > d ? a - 1 : a; - for (u = void 0; h--;) i = j[h], d = u - i, u && d < v * 0.8 && (m === null || d < m * 0.8) ? (l[o[h]] && !l[o[h + 1]] ? (d = h + 1, u = i) : d = h, o.splice(d, 1)) : u = i } - return o - }); - v(J.prototype, { - beforeSetTickPositions: function() { - var a, b = [], - c = !1, - d, e = this.getExtremes(), - f = e.min, - g = e.max, - h, i = this.isXAxis && !!this.options.breaks; - if ((e = this.options.ordinal) || i) { - o(this.series, function(c, d) { - if (c.visible !== !1 && (c.takeOrdinalPosition !== !1 || i)) - if (b = b.concat(c.processedXData), a = b.length, b.sort(function(a, b) { - return a - b }), a) - for (d = a - 1; d--;) b[d] === b[d + 1] && b.splice(d, 1) }); - a = b.length; - if (a > 2) { - d = b[1] - b[0]; - for (h = a - 1; h-- && !c;) b[h + 1] - b[h] !== d && (c = !0); - if (!this.options.keepOrdinalPadding && (b[0] - f > d || - g - b[b.length - 1] > d)) c = !0 - } - c ? (this.ordinalPositions = b, d = this.val2lin(y(f, b[0]), !0), h = y(this.val2lin(E(g, b[b.length - 1]), !0), 1), this.ordinalSlope = g = (g - f) / (h - d), this.ordinalOffset = f - d * g) : this.ordinalPositions = this.ordinalSlope = this.ordinalOffset = x - } - this.isOrdinal = e && c; - this.groupIntervalFactor = null - }, - val2lin: function(a, b) { - var c = this.ordinalPositions, - d; - if (c) { - var e = c.length, - f; - for (d = e; d--;) - if (c[d] === a) { f = d; - break } - for (d = e - 1; d--;) - if (a > c[d] || d === 0) { c = (a - c[d]) / (c[d + 1] - c[d]); - f = d + c; - break } - d = b ? f : this.ordinalSlope * (f || - 0) + this.ordinalOffset - } else d = a; - return d - }, - lin2val: function(a, b) { - var c = this.ordinalPositions; - if (c) { - var d = this.ordinalSlope, - e = this.ordinalOffset, - f = c.length - 1, - g, h; - if (b) a < 0 ? a = c[0] : a > f ? a = c[f] : (f = Y(a), h = a - f); - else - for (; f--;) - if (g = d * f + e, a >= g) { d = d * (f + 1) + e; - h = (a - g) / (d - g); - break } - c = h !== x && c[f] !== x ? c[f] + (h ? h * (c[f + 1] - c[f]) : 0) : a } else c = a; - return c }, - getExtendedPositions: function() { - var a = this.chart, - b = this.series[0].currentDataGrouping, - c = this.ordinalIndex, - d = b ? b.count + b.unitName : "raw", - e = this.getExtremes(), - f, g; - if (!c) c = this.ordinalIndex = {}; - if (!c[d]) f = { series: [], getExtremes: function() { - return { min: e.dataMin, max: e.dataMax } }, options: { ordinal: !0 }, val2lin: J.prototype.val2lin }, o(this.series, function(c) { g = { xAxis: f, xData: c.xData, chart: a, destroyGroupedData: va }; - g.options = { dataGrouping: b ? { enabled: !0, forced: !0, approximation: "open", units: [ - [b.unitName, [b.count]] - ] } : { enabled: !1 } }; - c.processData.apply(g); - f.series.push(g) }), this.beforeSetTickPositions.apply(f), c[d] = f.ordinalPositions; - return c[d] - }, - getGroupIntervalFactor: function(a, b, c) { - var d, c = c.processedXData, - e = c.length, - f = []; - d = this.groupIntervalFactor; - if (!d) { - for (d = 0; d < e - 1; d++) f[d] = c[d + 1] - c[d]; - f.sort(function(a, b) { - return a - b }); - f = f[Y(e / 2)]; - a = y(a, c[0]); - b = E(b, c[e - 1]); - this.groupIntervalFactor = d = e * f / (b - a) } - return d - }, - postProcessTickInterval: function(a) { - var b = this.ordinalSlope; - return b ? this.options.breaks ? this.closestPointRange : a / (b / this.closestPointRange) : a } - }); - S(Da.prototype, "pan", function(a, b) { - var c = this.xAxis[0], - d = b.chartX, - e = !1; - if (c.options.ordinal && c.series.length) { - var f = this.mouseDownX, - g = c.getExtremes(), - h = - g.dataMax, - i = g.min, - j = g.max, - k = this.hoverPoints, - l = c.closestPointRange, - f = (f - d) / (c.translationSlope * (c.ordinalSlope || l)), - m = { ordinalPositions: c.getExtendedPositions() }, - l = c.lin2val, - n = c.val2lin, - p; - if (m.ordinalPositions) { - if (T(f) > 1) k && o(k, function(a) { a.setState() }), f < 0 ? (k = m, p = c.ordinalPositions ? c : m) : (k = c.ordinalPositions ? c : m, p = m), m = p.ordinalPositions, h > m[m.length - 1] && m.push(h), this.fixedRange = j - i, f = c.toFixedRange(null, null, l.apply(k, [n.apply(k, [i, !0]) + f, !0]), l.apply(p, [n.apply(p, [j, !0]) + f, !0])), f.min >= E(g.dataMin, - i) && f.max <= y(h, j) && c.setExtremes(f.min, f.max, !0, !1, { trigger: "pan" }), this.mouseDownX = d, O(this.container, { cursor: "move" }) - } else e = !0 - } else e = !0; - e && a.apply(this, Array.prototype.slice.call(arguments, 1)) - }); - P.prototype.gappedPath = function() { - var a = this.options.gapSize, - b = this.points.slice(), - c = b.length - 1; - if (a && c > 0) - for (; c--;) b[c + 1].x - b[c].x > this.closestPointRange * a && b.splice(c + 1, 0, { isNull: !0 }); - return this.getGraphPath(b) }; - (function(a) { a(B) })(function(a) { - function b() { - return Array.prototype.slice.call(arguments, - 1) - } - - function c(a) { a.apply(this); - this.drawBreaks(this.xAxis, ["x"]); - this.drawBreaks(this.yAxis, d(this.pointArrayMap, ["y"])) } - var d = a.pick, - e = a.wrap, - f = a.each, - g = a.extend, - h = a.fireEvent, - i = a.Axis, - j = a.Series; - g(i.prototype, { - isInBreak: function(a, b) { - var c = a.repeat || Infinity, - d = a.from, - e = a.to - a.from, - c = b >= d ? (b - d) % c : c - (d - b) % c; - return a.inclusive ? c <= e : c < e && c !== 0 }, - isInAnyBreak: function(a, b) { - var c = this.options.breaks, - e = c && c.length, - f, g, h; - if (e) { - for (; e--;) this.isInBreak(c[e], a) && (f = !0, g || (g = d(c[e].showPoints, this.isXAxis ? - !1 : !0))); - h = f && b ? f && !g : f - } - return h - } - }); - e(i.prototype, "setTickPositions", function(a) { a.apply(this, Array.prototype.slice.call(arguments, 1)); - if (this.options.breaks) { - var b = this.tickPositions, - c = this.tickPositions.info, - d = [], - e; - for (e = 0; e < b.length; e++) this.isInAnyBreak(b[e]) || d.push(b[e]); - this.tickPositions = d; - this.tickPositions.info = c } }); - e(i.prototype, "init", function(a, b, c) { - if (c.breaks && c.breaks.length) c.ordinal = !1; - a.call(this, b, c); - if (this.options.breaks) { - var d = this; - d.isBroken = !0; - this.val2lin = function(a) { - var b = - a, - c, e; - for (e = 0; e < d.breakArray.length; e++) - if (c = d.breakArray[e], c.to <= a) b -= c.len; - else if (c.from >= a) break; - else if (d.isInBreak(c, a)) { b -= a - c.from; - break } - return b - }; - this.lin2val = function(a) { - var b, c; - for (c = 0; c < d.breakArray.length; c++) - if (b = d.breakArray[c], b.from >= a) break; - else b.to < a ? a += b.len : d.isInBreak(b, a) && (a += b.len); - return a }; - this.setExtremes = function(a, b, c, d, e) { - for (; this.isInAnyBreak(a);) a -= this.closestPointRange; - for (; this.isInAnyBreak(b);) b -= this.closestPointRange; - i.prototype.setExtremes.call(this, a, b, - c, d, e) - }; - this.setAxisTranslation = function(a) { - i.prototype.setAxisTranslation.call(this, a); - var b = d.options.breaks, - a = [], - c = [], - e = 0, - f, g, j = d.userMin || d.min, - k = d.userMax || d.max, - l, m; - for (m in b) g = b[m], f = g.repeat || Infinity, d.isInBreak(g, j) && (j += g.to % f - j % f), d.isInBreak(g, k) && (k -= k % f - g.from % f); - for (m in b) { g = b[m]; - l = g.from; - for (f = g.repeat || Infinity; l - f > j;) l -= f; - for (; l < j;) l += f; - for (; l < k; l += f) a.push({ value: l, move: "in" }), a.push({ value: l + (g.to - g.from), move: "out", size: g.breakSize }) } - a.sort(function(a, b) { - return a.value === b.value ? - (a.move === "in" ? 0 : 1) - (b.move === "in" ? 0 : 1) : a.value - b.value - }); - b = 0; - l = j; - for (m in a) { g = a[m]; - b += g.move === "in" ? 1 : -1; - if (b === 1 && g.move === "in") l = g.value; - b === 0 && (c.push({ from: l, to: g.value, len: g.value - l - (g.size || 0) }), e += g.value - l - (g.size || 0)) } - d.breakArray = c; - h(d, "afterBreaks"); - d.transA *= (k - d.min) / (k - j - e); - d.min = j; - d.max = k - } - } - }); - e(j.prototype, "generatePoints", function(a) { - a.apply(this, b(arguments)); - var c = this.xAxis, - d = this.yAxis, - e = this.points, - f, g = e.length, - h = this.options.connectNulls, - i; - if (c && d && (c.options.breaks || d.options.breaks)) - for (; g--;) - if (f = - e[g], i = f.y === null && h === !1, !i && (c.isInAnyBreak(f.x, !0) || d.isInAnyBreak(f.y, !0))) e.splice(g, 1), this.data[g] && this.data[g].destroyElements() - }); - a.Series.prototype.drawBreaks = function(a, b) { - var c = this, - e = c.points, - g, i, j, o; - f(b, function(b) { - g = a.breakArray || []; - i = a.isXAxis ? a.min : d(c.options.threshold, a.min); - f(e, function(c) { - o = d(c["stack" + b.toUpperCase()], c[b]); - f(g, function(b) { - j = !1; - if (i < b.from && o > b.to || i > b.from && o < b.from) j = "pointBreak"; - else if (i < b.from && o > b.from && o < b.to || i > b.from && o > b.to && o < b.from) j = "pointInBreak"; - j && h(a, j, { point: c, brk: b }) - }) - }) - }) - }; - e(a.seriesTypes.column.prototype, "drawPoints", c); - e(a.Series.prototype, "drawPoints", c) - }); - var la = P.prototype, - fc = la.processData, - gc = la.generatePoints, - hc = la.destroy, - ic = { - approximation: "average", - groupPixelWidth: 2, - dateTimeLabelFormats: { - millisecond: ["%A, %b %e, %H:%M:%S.%L", "%A, %b %e, %H:%M:%S.%L", "-%H:%M:%S.%L"], - second: ["%A, %b %e, %H:%M:%S", "%A, %b %e, %H:%M:%S", "-%H:%M:%S"], - minute: ["%A, %b %e, %H:%M", "%A, %b %e, %H:%M", "-%H:%M"], - hour: ["%A, %b %e, %H:%M", "%A, %b %e, %H:%M", - "-%H:%M" - ], - day: ["%A, %b %e, %Y", "%A, %b %e", "-%A, %b %e, %Y"], - week: ["Week from %A, %b %e, %Y", "%A, %b %e", "-%A, %b %e, %Y"], - month: ["%B %Y", "%B", "-%B %Y"], - year: ["%Y", "%Y", "-%Y"] - } - }, - $b = { line: {}, spline: {}, area: {}, areaspline: {}, column: { approximation: "sum", groupPixelWidth: 10 }, arearange: { approximation: "range" }, areasplinerange: { approximation: "range" }, columnrange: { approximation: "range", groupPixelWidth: 10 }, candlestick: { approximation: "ohlc", groupPixelWidth: 10 }, ohlc: { approximation: "ohlc", groupPixelWidth: 5 } }, - ac = [ - ["millisecond", [1, 2, 5, 10, 20, 25, 50, 100, 200, 500]], - ["second", [1, 2, 5, 10, 15, 30]], - ["minute", [1, 2, 5, 10, 15, 30]], - ["hour", [1, 2, 3, 4, 6, 8, 12]], - ["day", [1]], - ["week", [1]], - ["month", [1, 3, 6]], - ["year", null] - ], - Va = { - sum: function(a) { - var b = a.length, - c; - if (!b && a.hasNulls) c = null; - else if (b) - for (c = 0; b--;) c += a[b]; - return c }, - average: function(a) { - var b = a.length, - a = Va.sum(a); - z(a) && b && (a /= b); - return a }, - open: function(a) { - return a.length ? a[0] : a.hasNulls ? null : x }, - high: function(a) { - return a.length ? Fa(a) : a.hasNulls ? null : x }, - low: function(a) { - return a.length ? - Na(a) : a.hasNulls ? null : x - }, - close: function(a) { - return a.length ? a[a.length - 1] : a.hasNulls ? null : x }, - ohlc: function(a, b, c, d) { a = Va.open(a); - b = Va.high(b); - c = Va.low(c); - d = Va.close(d); - if (z(a) || z(b) || z(c) || z(d)) return [a, b, c, d] }, - range: function(a, b) { a = Va.low(a); - b = Va.high(b); - if (z(a) || z(b)) return [a, b] } - }; - la.groupData = function(a, b, c, d) { - var e = this.data, - f = this.options.data, - g = [], - h = [], - i = [], - j = a.length, - k, l, m = !!b, - n = [ - [], - [], - [], - [] - ], - d = typeof d === "function" ? d : Va[d], - p = this.pointArrayMap, - o = p && p.length, - q, t = 0, - u = 0; - for (q = 0; q <= j; q++) - if (a[q] >= - c[0]) break; - for (; q <= j; q++) { - for (; c[t + 1] !== void 0 && a[q] >= c[t + 1] || q === j;) - if (k = c[t], l = d.apply(0, n), l !== x && (g.push(k), h.push(l), i.push({ start: u, length: n[0].length })), u = q, n[0] = [], n[1] = [], n[2] = [], n[3] = [], t += 1, q === j) break; - if (q === j) break; - if (p) { k = this.cropStart + q; - k = e && e[k] || this.pointClass.prototype.applyOptions.apply({ series: this }, [f[k]]); - var w; - for (l = 0; l < o; l++) - if (w = k[p[l]], z(w)) n[l].push(w); - else if (w === null) n[l].hasNulls = !0 } else if (k = m ? b[q] : null, z(k)) n[0].push(k); - else if (k === null) n[0].hasNulls = !0 } - return [g, - h, i - ] - }; - la.processData = function() { - var a = this.chart, - b = this.options.dataGrouping, - c = this.allowDG !== !1 && b && q(b.enabled, a.options._stock), - d; - this.forceCrop = c; - this.groupPixelWidth = null; - this.hasProcessed = !0; - if (fc.apply(this, arguments) !== !1 && c) { - this.destroyGroupedData(); - var e = this.processedXData, - f = this.processedYData, - g = a.plotSizeX, - a = this.xAxis, - h = a.options.ordinal, - i = this.groupPixelWidth = a.getGroupPixelWidth && a.getGroupPixelWidth(); - if (i) { - d = !0; - this.points = null; - var j = a.getExtremes(), - c = j.min, - j = j.max, - h = h && a.getGroupIntervalFactor(c, - j, this) || 1, - g = i * (j - c) / g * h, - i = a.getTimeTicks(a.normalizeTimeTickInterval(g, b.units || ac), Math.min(c, e[0]), Math.max(j, e[e.length - 1]), a.options.startOfWeek, e, this.closestPointRange), - e = la.groupData.apply(this, [e, f, i, b.approximation]), - f = e[0], - h = e[1]; - if (b.smoothed) { b = f.length - 1; - for (f[b] = Math.min(f[b], j); b-- && b > 0;) f[b] += g / 2; - f[0] = Math.max(f[0], c) } - this.currentDataGrouping = i.info; - this.closestPointRange = i.info.totalRange; - this.groupMap = e[2]; - if (t(f[0]) && f[0] < a.dataMin) { - if (a.min === a.dataMin) a.min = f[0]; - a.dataMin = f[0] } - this.processedXData = - f; - this.processedYData = h - } else this.currentDataGrouping = this.groupMap = null; - this.hasGroupedData = d - } - }; - la.destroyGroupedData = function() { - var a = this.groupedData; - o(a || [], function(b, c) { b && (a[c] = b.destroy ? b.destroy() : null) }); - this.groupedData = null }; - la.generatePoints = function() { gc.apply(this); - this.destroyGroupedData(); - this.groupedData = this.hasGroupedData ? this.points : null }; - S(Nb.prototype, "tooltipFooterHeaderFormatter", function(a, b, c) { - var d = b.series, - e = d.tooltipOptions, - f = d.options.dataGrouping, - g = e.xDateFormat, - h, - i = d.xAxis; - return i && i.options.type === "datetime" && f && z(b.key) ? (a = d.currentDataGrouping, f = f.dateTimeLabelFormats, a ? (i = f[a.unitName], a.count === 1 ? g = i[0] : (g = i[1], h = i[2])) : !g && f && (g = this.getXDateFormat(b, e, i)), g = pa(g, b.key), h && (g += pa(h, b.key + a.totalRange - 1)), Ma(e[(c ? "footer" : "header") + "Format"], { point: v(b.point, { key: g }), series: d })) : a.call(this, b, c) - }); - la.destroy = function() { - for (var a = this.groupedData || [], b = a.length; b--;) a[b] && a[b].destroy(); - hc.apply(this) }; - S(la, "setOptions", function(a, b) { - var c = a.call(this, - b), - d = this.type, - e = this.chart.options.plotOptions, - f = X[d].dataGrouping; - if ($b[d]) f || (f = D(ic, $b[d])), c.dataGrouping = D(f, e.series && e.series.dataGrouping, e[d].dataGrouping, b.dataGrouping); - if (this.chart.options._stock) this.requireSorting = !0; - return c - }); - S(J.prototype, "setScale", function(a) { a.call(this); - o(this.series, function(a) { a.hasProcessed = !1 }) }); - J.prototype.getGroupPixelWidth = function() { - var a = this.series, - b = a.length, - c, d = 0, - e = !1, - f; - for (c = b; c--;)(f = a[c].options.dataGrouping) && (d = y(d, f.groupPixelWidth)); - for (c = - b; c--;) - if ((f = a[c].options.dataGrouping) && a[c].hasProcessed) - if (b = (a[c].processedXData || a[c].data).length, a[c].groupPixelWidth || b > this.chart.plotSizeX / d || b && f.forced) e = !0; - return e ? d : 0 - }; - J.prototype.setDataGrouping = function(a, b) { - var c, b = q(b, !0); - a || (a = { forced: !1, units: null }); - if (this instanceof J) - for (c = this.series.length; c--;) this.series[c].update({ dataGrouping: a }, !1); - else o(this.chart.options.series, function(b) { b.dataGrouping = a }, !1); - b && this.chart.redraw() }; - X.ohlc = D(X.column, { - lineWidth: 1, - tooltip: { pointFormat: '\u25cf {series.name}
Open: {point.open}
High: {point.high}
Low: {point.low}
Close: {point.close}
' }, - states: { hover: { lineWidth: 3 } }, - threshold: null - }); - ga = oa(I.column, { - type: "ohlc", - pointArrayMap: ["open", "high", "low", "close"], - toYData: function(a) { - return [a.open, a.high, a.low, a.close] }, - pointValKey: "high", - pointAttrToOptions: { stroke: "color", "stroke-width": "lineWidth" }, - upColorProp: "stroke", - getAttribs: function() { - I.column.prototype.getAttribs.apply(this, arguments); - var a = this.options, - b = a.states, - a = a.upColor || this.color, - c = D(this.pointAttr), - d = this.upColorProp; - c[""][d] = a; - c.hover[d] = b.hover.upColor || a; - c.select[d] = b.select.upColor || - a; - o(this.points, function(a) { - if (a.open < a.close && !a.options.color) a.pointAttr = c }) - }, - translate: function() { - var a = this.yAxis; - I.column.prototype.translate.apply(this); - o(this.points, function(b) { - if (b.open !== null) b.plotOpen = a.translate(b.open, 0, 1, 0, 1); - if (b.close !== null) b.plotClose = a.translate(b.close, 0, 1, 0, 1) }) }, - drawPoints: function() { - var a = this, - b = a.chart, - c, d, e, f, g, h, i, j; - o(a.points, function(k) { - if (k.plotY !== x) i = k.graphic, c = k.pointAttr[k.selected ? "selected" : ""] || a.pointAttr[""], f = c["stroke-width"] % 2 / 2, j = A(k.plotX) - - f, g = A(k.shapeArgs.width / 2), h = ["M", j, A(k.yBottom), "L", j, A(k.plotY)], k.open !== null && (d = A(k.plotOpen) + f, h.push("M", j, d, "L", j - g, d)), k.close !== null && (e = A(k.plotClose) + f, h.push("M", j, e, "L", j + g, e)), i ? i.attr(c).animate({ d: h }) : k.graphic = b.renderer.path(h).attr(c).add(a.group) - }) - }, - animate: null - }); - I.ohlc = ga; - X.candlestick = D(X.column, { lineColor: "black", lineWidth: 1, states: { hover: { lineWidth: 2 } }, tooltip: X.ohlc.tooltip, threshold: null, upColor: "white" }); - ga = oa(ga, { - type: "candlestick", - pointAttrToOptions: { - fill: "color", - stroke: "lineColor", - "stroke-width": "lineWidth" - }, - upColorProp: "fill", - getAttribs: function() { I.ohlc.prototype.getAttribs.apply(this, arguments); - var a = this.options, - b = a.states, - c = a.upLineColor || a.lineColor, - d = b.hover.upLineColor || c, - e = b.select.upLineColor || c; - o(this.points, function(a) { - if (a.open < a.close) { - if (a.lineColor) a.pointAttr = D(a.pointAttr), c = a.lineColor; - a.pointAttr[""].stroke = c; - a.pointAttr.hover.stroke = d; - a.pointAttr.select.stroke = e } }) }, - drawPoints: function() { - var a = this, - b = a.chart, - c, d = a.pointAttr[""], - e, f, g, h, i, j, k, l, m, n, p; - o(a.points, - function(o) { m = o.graphic; - if (o.plotY !== x) c = o.pointAttr[o.selected ? "selected" : ""] || d, k = c["stroke-width"] % 2 / 2, l = A(o.plotX) - k, e = o.plotOpen, f = o.plotClose, g = aa.min(e, f), h = aa.max(e, f), p = A(o.shapeArgs.width / 2), i = A(g) !== A(o.plotY), j = h !== o.yBottom, g = A(g) + k, h = A(h) + k, n = [], n.push("M", l - p, h, "L", l - p, g, "L", l + p, g, "L", l + p, h, "Z", "M", l, g, "L", l, i ? A(o.plotY) : g, "M", l, h, "L", l, j ? A(o.yBottom) : h), m ? m.attr(c).animate({ d: n }) : o.graphic = b.renderer.path(n).attr(c).add(a.group).shadow(a.options.shadow) }) - } - }); - I.candlestick = ga; - var yb = - za.prototype.symbols; - X.flags = D(X.column, { fillColor: "white", lineWidth: 1, pointRange: 0, shape: "flag", stackDistance: 12, states: { hover: { lineColor: "black", fillColor: "#FCFFC5" } }, style: { fontSize: "11px", fontWeight: "bold", textAlign: "center" }, tooltip: { pointFormat: "{point.text}
" }, threshold: null, y: -30 }); - I.flags = oa(I.column, { - type: "flags", - sorted: !1, - noSharedTooltip: !0, - allowDG: !1, - takeOrdinalPosition: !1, - trackerGroups: ["markerGroup"], - forceCrop: !0, - init: P.prototype.init, - pointAttrToOptions: { - fill: "fillColor", - stroke: "color", - "stroke-width": "lineWidth", - r: "radius" - }, - translate: function() { - I.column.prototype.translate.apply(this); - var a = this.options, - b = this.chart, - c = this.points, - d = c.length - 1, - e, f, g = a.onSeries; - e = g && b.get(g); - var a = a.onKey || "y", - g = e && e.options.step, - h = e && e.points, - i = h && h.length, - j = this.xAxis, - k = j.getExtremes(), - l, m, n; - if (e && e.visible && i) { - e = e.currentDataGrouping; - m = h[i - 1].x + (e ? e.totalRange : 0); - c.sort(function(a, b) { - return a.x - b.x }); - for (a = "plot" + a[0].toUpperCase() + a.substr(1); i-- && c[d];) - if (e = c[d], l = h[i], l.x <= e.x && l[a] !== void 0) { - if (e.x <= - m) e.plotY = l[a], l.x < e.x && !g && (n = h[i + 1]) && n[a] !== x && (e.plotY += (e.x - l.x) / (n.x - l.x) * (n[a] - l[a])); - d--; - i++; - if (d < 0) break - } - } - o(c, function(a, d) { - var e; - if (a.plotY === x) a.x >= k.min && a.x <= k.max ? a.plotY = b.chartHeight - j.bottom - (j.opposite ? j.height : 0) + j.offset - b.plotTop : a.shapeArgs = {}; - if ((f = c[d - 1]) && f.plotX === a.plotX) { - if (f.stackIndex === x) f.stackIndex = 0; - e = f.stackIndex + 1 } - a.stackIndex = e }) - }, - drawPoints: function() { - var a, b = this.pointAttr[""], - c = this.points, - d = this.chart, - e = d.renderer, - f, g, h = this.options, - i = h.y, - j, k, l, m, n, p, o = this.yAxis, - s; - for (k = c.length; k--;) - if (l = c[k], a = l.plotX > this.xAxis.len, f = l.plotX, f > 0 && (f -= q(l.lineWidth, h.lineWidth) % 2), m = l.stackIndex, j = l.options.shape || h.shape, g = l.plotY, g !== x && (g = l.plotY + i - (m !== x && m * h.stackDistance)), n = m ? x : l.plotX, p = m ? x : l.plotY, m = l.graphic, g !== x && f >= 0 && !a) a = l.pointAttr[l.selected ? "select" : ""] || b, s = q(l.options.title, h.title, "A"), m ? m.attr({ text: s }).attr({ x: f, y: g, r: a.r, anchorX: n, anchorY: p }) : l.graphic = e.label(s, f, g, j, n, p, h.useHTML).css(D(h.style, l.style)).attr(a).attr({ - align: j === "flag" ? "left" : "center", - width: h.width, - height: h.height - }).add(this.markerGroup).shadow(h.shadow), l.tooltipPos = d.inverted ? [o.len + o.pos - d.plotLeft - g, this.xAxis.len - f] : [f, g]; - else if (m) l.graphic = m.destroy() - }, - drawTracker: function() { - var a = this.points; - ob.drawTrackerPoint.apply(this); - o(a, function(b) { - var c = b.graphic; - c && G(c.element, "mouseover", function() { - if (b.stackIndex > 0 && !b.raised) b._y = c.y, c.attr({ y: b._y - 8 }), b.raised = !0; - o(a, function(a) { - if (a !== b && a.raised && a.graphic) a.graphic.attr({ y: a._y }), a.raised = !1 }) }) }) }, - animate: va, - buildKDTree: va, - setClip: va - }); - yb.flag = function(a, b, c, d, e) { - return ["M", e && e.anchorX || a, e && e.anchorY || b, "L", a, b + d, a, b, a + c, b, a + c, b + d, a, b + d, "Z"] }; - o(["circle", "square"], function(a) { yb[a + "pin"] = function(b, c, d, e, f) { - var g = f && f.anchorX, - f = f && f.anchorY; - a === "circle" && e > d && (b -= A((e - d) / 2), d = e); - b = yb[a](b, c, d, e); - g && f && b.push("M", g, c > f ? c : c + e, "L", g, f); - return b } }); - Za === B.VMLRenderer && o(["flag", "circlepin", "squarepin"], function(a) { nb.prototype.symbols[a] = yb[a] }); - var Wb = { - height: lb ? 20 : 14, - barBackgroundColor: "#bfc8d1", - barBorderRadius: 0, - barBorderWidth: 1, - barBorderColor: "#bfc8d1", - buttonArrowColor: "#666", - buttonBackgroundColor: "#ebe7e8", - buttonBorderColor: "#bbb", - buttonBorderRadius: 0, - buttonBorderWidth: 1, - margin: 10, - minWidth: 6, - rifleColor: "#666", - zIndex: 3, - step: 0.2, - trackBackgroundColor: "#eeeeee", - trackBorderColor: "#eeeeee", - trackBorderWidth: 1, - liveRedraw: ma && !lb - }; - Q.scrollbar = D(!0, Wb, Q.scrollbar); - tb.prototype = { - render: function() { - var a = this.renderer, - b = this.options, - c = b.trackBorderWidth, - d = b.barBorderWidth, - e = this.size, - f; - this.group = f = a.g("highcharts-scrollbar").attr({ - zIndex: b.zIndex, - translateY: -99999 - }).add(); - this.track = a.rect().attr({ height: e, width: e, y: -c % 2 / 2, x: -c % 2 / 2, "stroke-width": c, fill: b.trackBackgroundColor, stroke: b.trackBorderColor, r: b.trackBorderRadius || 0 }).add(f); - this.scrollbarGroup = a.g().add(f); - this.scrollbar = a.rect().attr({ height: e, width: e, y: -d % 2 / 2, x: -d % 2 / 2, "stroke-width": d, fill: b.barBackgroundColor, stroke: b.barBorderColor, r: b.barBorderRadius || 0 }).add(this.scrollbarGroup); - this.scrollbarRifles = a.path(this.swapXY([W, -3, e / 4, R, -3, 2 * e / 3, W, 0, e / 4, R, 0, 2 * e / 3, W, 3, e / 4, R, 3, 2 * e / - 3 - ], b.vertical)).attr({ stroke: b.rifleColor, "stroke-width": 1 }).add(this.scrollbarGroup); - this.drawScrollbarButton(0); - this.drawScrollbarButton(1) - }, - position: function(a, b, c, d) { - var e = this.options, - f = e.vertical, - g = 0, - h = this.rendered ? "animate" : "attr"; - this.x = a; - this.y = b + e.trackBorderWidth; - this.width = c; - this.xOffset = this.height = d; - this.yOffset = g; - f ? (this.width = this.yOffset = c = g = this.size, this.xOffset = b = 0, this.barWidth = d - c * 2, this.x = a += this.options.margin) : (this.height = this.xOffset = d = b = this.size, this.barWidth = c - d * 2, this.y += - this.options.margin); - this.group[h]({ translateX: a, translateY: this.y }); - this.track[h]({ width: c, height: d }); - this.scrollbarButtons[1].attr({ translateX: f ? 0 : c - b, translateY: f ? d - g : 0 }) - }, - drawScrollbarButton: function(a) { - var b = this.renderer, - c = this.scrollbarButtons, - d = this.options, - e = this.size, - f; - f = b.g().add(this.group); - c.push(f); - b.rect(-0.5, -0.5, e + 1, e + 1, d.buttonBorderRadius, d.buttonBorderWidth).attr({ stroke: d.buttonBorderColor, "stroke-width": d.buttonBorderWidth, fill: d.buttonBackgroundColor }).add(f); - b.path(this.swapXY(["M", - e / 2 + (a ? -1 : 1), e / 2 - 3, "L", e / 2 + (a ? -1 : 1), e / 2 + 3, "L", e / 2 + (a ? 2 : -2), e / 2 - ], d.vertical)).attr({ fill: d.buttonArrowColor }).add(f) - }, - swapXY: function(a, b) { - var c, d = a.length, - e; - if (b) - for (c = 0; c < d; c += 3) e = a[c + 1], a[c + 1] = a[c + 2], a[c + 2] = e; - return a }, - setRange: function(a, b) { - var c = this.options, - d = c.vertical, - e, f, g, h = this.rendered && !this.hasDragged ? "animate" : "attr"; - if (t(this.barWidth)) e = this.barWidth * Math.max(a, 0), f = this.barWidth * Math.min(b, 1), f = Math.max(V(f - e), c.minWidth), e = Math.floor(e + this.xOffset + this.yOffset), g = f / 2 - 0.5, this.from = - a, this.to = b, d ? (this.scrollbarGroup[h]({ translateY: e }), this.scrollbar[h]({ height: f }), this.scrollbarRifles[h]({ translateY: g }), this.scrollbarTop = e, this.scrollbarLeft = 0) : (this.scrollbarGroup[h]({ translateX: e }), this.scrollbar[h]({ width: f }), this.scrollbarRifles[h]({ translateX: g }), this.scrollbarLeft = e, this.scrollbarTop = 0), f <= 12 ? this.scrollbarRifles.hide() : this.scrollbarRifles.show(!0), c.showFull === !1 && (a <= 0 && b >= 1 ? this.group.hide() : this.group.show()), this.rendered = !0 - }, - initEvents: function() { - var a = this; - a.mouseMoveHandler = - function(b) { - var c = a.chart.pointer.normalize(b), - d = a.options.vertical ? "chartY" : "chartX", - e = a.initPositions; - if (a.grabbedCenter && (!b.touches || b.touches[0][d] !== 0)) c = { chartX: (c.chartX - a.x - a.xOffset) / a.barWidth, chartY: (c.chartY - a.y - a.yOffset) / a.barWidth }[d], d = a[d], d = c - d, a.hasDragged = !0, a.updatePosition(e[0] + d, e[1] + d), a.hasDragged && K(a, "changed", { from: a.from, to: a.to, trigger: "scrollbar", DOMType: b.type, DOMEvent: b }) }; - a.mouseUpHandler = function(b) { - a.hasDragged && K(a, "changed", { - from: a.from, - to: a.to, - trigger: "scrollbar", - DOMType: b.type, - DOMEvent: b - }); - a.grabbedCenter = a.hasDragged = a.chartX = a.chartY = null - }; - a.mouseDownHandler = function(b) { b = a.chart.pointer.normalize(b); - a.chartX = (b.chartX - a.x - a.xOffset) / a.barWidth; - a.chartY = (b.chartY - a.y - a.yOffset) / a.barWidth; - a.initPositions = [a.from, a.to]; - a.grabbedCenter = !0 }; - a.buttonToMinClick = function(b) { - var c = V(a.to - a.from) * a.options.step; - a.updatePosition(V(a.from - c), V(a.to - c)); - K(a, "changed", { from: a.from, to: a.to, trigger: "scrollbar", DOMEvent: b }) }; - a.buttonToMaxClick = function(b) { - var c = (a.to - - a.from) * a.options.step; - a.updatePosition(a.from + c, a.to + c); - K(a, "changed", { from: a.from, to: a.to, trigger: "scrollbar", DOMEvent: b }) - }; - a.trackClick = function(b) { - var c = a.chart.pointer.normalize(b), - d = a.to - a.from, - e = a.y + a.scrollbarTop, - f = a.x + a.scrollbarLeft; - a.options.vertical && c.chartY > e || !a.options.vertical && c.chartX > f ? a.updatePosition(a.from + d, a.to + d) : a.updatePosition(a.from - d, a.to - d); - K(a, "changed", { from: a.from, to: a.to, trigger: "scrollbar", DOMEvent: b }) } - }, - updatePosition: function(a, b) { - b > 1 && (a = V(1 - V(b - a)), b = 1); - a < - 0 && (b = V(b - a), a = 0); - this.from = a; - this.to = b - }, - addEvents: function() { - var a = this.options.inverted ? [1, 0] : [0, 1], - b = this.scrollbarButtons, - c = this.scrollbarGroup.element, - d = this.mouseDownHandler, - e = this.mouseMoveHandler, - f = this.mouseUpHandler, - a = [ - [b[a[0]].element, "click", this.buttonToMinClick], - [b[a[1]].element, "click", this.buttonToMaxClick], - [this.track.element, "click", this.trackClick], - [c, "mousedown", d], - [C, "mousemove", e], - [C, "mouseup", f] - ]; - $a && a.push([c, "touchstart", d], [C, "touchmove", e], [C, "touchend", f]); - o(a, function(a) { - G.apply(null, - a) - }); - this._events = a - }, - removeEvents: function() { o(this._events, function(a) { U.apply(null, a) }); - this._events = x }, - destroy: function() { this.removeEvents(); - o([this.track, this.scrollbarRifles, this.scrollbar, this.scrollbarGroup, this.group], function(a) { a && a.destroy && a.destroy() }); - Oa(this.scrollbarButtons) } - }; - S(J.prototype, "init", function(a) { - var b = this; - a.apply(b, [].slice.call(arguments, 1)); - if (b.options.scrollbar && b.options.scrollbar.enabled) b.options.scrollbar.vertical = !b.horiz, b.options.startOnTick = b.options.endOnTick = !1, b.scrollbar = new tb(b.chart.renderer, b.options.scrollbar, b.chart), G(b.scrollbar, "changed", function(a) { - var d = Math.min(q(b.options.min, b.min), b.min, b.dataMin), - e = Math.max(q(b.options.max, b.max), b.max, b.dataMax) - d, - f; - b.horiz && !b.reversed || !b.horiz && b.reversed ? (f = d + e * this.to, d += e * this.from) : (f = d + e * (1 - this.from), d += e * (1 - this.to)); - b.setExtremes(d, f, !0, !1, a) }) - }); - S(J.prototype, "render", function(a) { - var b = Math.min(q(this.options.min, this.min), this.min, this.dataMin), - c = Math.max(q(this.options.max, this.max), this.max, - this.dataMax), - d = this.scrollbar, - e; - a.apply(this, [].slice.call(arguments, 1)); - d && (this.horiz ? d.position(this.left, this.top + this.height + this.offset + 2 + (this.opposite ? 0 : this.axisTitleMargin), this.width, this.height) : d.position(this.left + this.width + 2 + this.offset + (this.opposite ? this.axisTitleMargin : 0), this.top, this.width, this.height), isNaN(b) || isNaN(c) || !t(this.min) || !t(this.max) ? d.setRange(0, 0) : (e = (this.min - b) / (c - b), b = (this.max - b) / (c - b), this.horiz && !this.reversed || !this.horiz && this.reversed ? d.setRange(e, b) : - d.setRange(1 - b, 1 - e))) - }); - S(J.prototype, "getOffset", function(a) { - var b = this.horiz ? 2 : 1, - c = this.scrollbar; - a.apply(this, [].slice.call(arguments, 1)); - c && (this.chart.axisOffset[b] += c.size + c.options.margin) }); - S(J.prototype, "destroy", function(a) { - if (this.scrollbar) this.scrollbar = this.scrollbar.destroy(); - a.apply(this, [].slice.call(arguments, 1)) }); - B.Scrollbar = tb; - var ga = [].concat(ac), - zb = function(a) { - var b = Ha(arguments, z); - if (b.length) return Math[a].apply(0, b) }; - ga[4] = ["day", [1, 2, 3, 4]]; - ga[5] = ["week", [1, 2, 3]]; - v(Q, { - navigator: { - handles: { - backgroundColor: "#ebe7e8", - borderColor: "#b2b1b6" - }, - height: 40, - margin: 25, - maskFill: "rgba(128,179,236,0.3)", - maskInside: !0, - outlineColor: "#b2b1b6", - outlineWidth: 1, - series: { type: I.areaspline === x ? "line" : "areaspline", color: "#4572A7", compare: null, fillOpacity: 0.05, dataGrouping: { approximation: "average", enabled: !0, groupPixelWidth: 2, smoothed: !0, units: ga }, dataLabels: { enabled: !1, zIndex: 2 }, id: "highcharts-navigator-series", lineColor: null, lineWidth: 1, marker: { enabled: !1 }, pointRange: 0, shadow: !1, threshold: null }, - xAxis: { - tickWidth: 0, - lineWidth: 0, - gridLineColor: "#EEE", - gridLineWidth: 1, - tickPixelInterval: 200, - labels: { align: "left", style: { color: "#888" }, x: 3, y: -4 }, - crosshair: !1 - }, - yAxis: { gridLineWidth: 0, startOnTick: !1, endOnTick: !1, minPadding: 0.1, maxPadding: 0.1, labels: { enabled: !1 }, crosshair: !1, title: { text: null }, tickWidth: 0 } - } - }); - Jb.prototype = { - drawHandle: function(a, b) { - var c = this.chart.renderer, - d = this.elementsToDestroy, - e = this.handles, - f = this.navigatorOptions.handles, - f = { fill: f.backgroundColor, stroke: f.borderColor, "stroke-width": 1 }, - g; - this.rendered || (e[b] = c.g("navigator-handle-" + ["left", "right"][b]).css({ cursor: "ew-resize" }).attr({ zIndex: 10 - b }).add(), g = c.rect(-4.5, 0, 9, 16, 0, 1).attr(f).add(e[b]), d.push(g), g = c.path(["M", -1.5, 4, "L", -1.5, 12, "M", 0.5, 4, "L", 0.5, 12]).attr(f).add(e[b]), d.push(g)); - e[b][this.rendered && !this.hasDragged ? "animate" : "attr"]({ translateX: this.scrollerLeft + this.scrollbarHeight + parseInt(a, 10), translateY: this.top + this.height / 2 - 8 }) - }, - render: function(a, b, c, d) { - var e = this.chart, - f = e.renderer, - g, h, i, j, k = this.navigatorGroup; - j = this.scrollbarHeight; - var k = this.xAxis, - l = this.navigatorOptions, - m = this.height, - n = this.top, - p = this.navigatorEnabled, - o = l.outlineWidth, - s = o / 2, - v = this.outlineHeight, - u = n + s, - w = this.rendered; - if (z(a) && z(b) && (!this.hasDragged || t(c))) { - this.navigatorLeft = g = q(k.left, e.plotLeft + j); - this.navigatorWidth = h = q(k.len, e.plotWidth - 2 * j); - this.scrollerLeft = i = g - j; - this.scrollerWidth = j = j = h + 2 * j; - c = q(c, k.translate(a)); - d = q(d, k.translate(b)); - if (!z(c) || T(c) === Infinity) c = 0, d = j; - if (!(k.translate(d, !0) - k.translate(c, !0) < e.xAxis[0].minRange)) { - this.zoomedMax = E(y(c, d, 0), h); - this.zoomedMin = E(y(this.fixedWidth ? - this.zoomedMax - this.fixedWidth : E(c, d), 0), h); - this.range = this.zoomedMax - this.zoomedMin; - b = A(this.zoomedMax); - a = A(this.zoomedMin); - if (!w && p) this.navigatorGroup = k = f.g("navigator").attr({ zIndex: 3 }).add(), this.leftShade = f.rect().attr({ fill: l.maskFill }).add(k), l.maskInside ? this.leftShade.css({ cursor: "ew-resize" }) : this.rightShade = f.rect().attr({ fill: l.maskFill }).add(k), this.outline = f.path().attr({ "stroke-width": o, stroke: l.outlineColor }).add(k); - f = w && !this.hasDragged ? "animate" : "attr"; - if (p) { - this.leftShade[f](l.maskInside ? { x: g + a, y: n, width: b - a, height: m } : { x: g, y: n, width: a, height: m }); - if (this.rightShade) this.rightShade[f]({ x: g + b, y: n, width: h - b, height: m }); - this.outline[f]({ d: [W, i, u, R, g + a - s, u, g + a - s, u + v, R, g + b - s, u + v, R, g + b - s, u, i + j, u].concat(l.maskInside ? [W, g + a + s, u, R, g + b - s, u] : []) }); - this.drawHandle(a + s, 0); - this.drawHandle(b + s, 1) - } - if (this.scrollbar) this.scrollbar.hasDragged = this.hasDragged, this.scrollbar.position(this.scrollerLeft, this.top + (p ? this.height : -this.scrollbarHeight), this.scrollerWidth, this.scrollbarHeight), this.scrollbar.setRange(a / - h, b / h); - this.rendered = !0 - } - } - }, - addEvents: function() { - var a = this.chart, - b = a.container, - c = this.mouseDownHandler, - d = this.mouseMoveHandler, - e = this.mouseUpHandler, - f; - f = [ - [b, "mousedown", c], - [b, "mousemove", d], - [C, "mouseup", e] - ]; - $a && f.push([b, "touchstart", c], [b, "touchmove", d], [C, "touchend", e]); - o(f, function(a) { G.apply(null, a) }); - this._events = f; - this.series && G(this.series.xAxis, "foundExtremes", function() { a.scroller.modifyNavigatorAxisExtremes() }); - G(a, "redraw", function() { - var a = this.scroller, - b = a && a.baseSeries && a.baseSeries.xAxis; - b && a.render(b.min, b.max) - }) - }, - removeEvents: function() { o(this._events, function(a) { U.apply(null, a) }); - this._events = x; - this.removeBaseSeriesEvents() }, - removeBaseSeriesEvents: function() { this.navigatorEnabled && this.baseSeries && this.baseSeries.xAxis && this.navigatorOptions.adaptToUpdatedData !== !1 && (U(this.baseSeries, "updatedData", this.updatedDataHandler), U(this.baseSeries.xAxis, "foundExtremes", this.modifyBaseAxisExtremes)) }, - init: function() { - var a = this, - b = a.chart, - c, d, e = a.scrollbarHeight, - f = a.navigatorOptions, - g = a.height, - h = a.top, - i, j = a.baseSeries; - a.mouseDownHandler = function(d) { - var d = b.pointer.normalize(d), - e = a.zoomedMin, - f = a.zoomedMax, - h = a.top, - j = a.scrollerLeft, - k = a.scrollerWidth, - l = a.navigatorLeft, - o = a.navigatorWidth, - q = a.scrollbarPad || 0, - t = a.range, - v = d.chartX, - x = d.chartY, - d = b.xAxis[0], - y, z = lb ? 10 : 7; - if (x > h && x < h + g) - if (aa.abs(v - e - l) < z) a.grabbedLeft = !0, a.otherHandlePos = f, a.fixedExtreme = d.max, b.fixedRange = null; - else if (aa.abs(v - f - l) < z) a.grabbedRight = !0, a.otherHandlePos = e, a.fixedExtreme = d.min, b.fixedRange = null; - else if (v > l + e - q && v < l + f + - q) a.grabbedCenter = v, a.fixedWidth = t, i = v - e; - else if (v > j && v < j + k) { f = v - l - t / 2; - if (f < 0) f = 0; - else if (f + t >= o) f = o - t, y = a.getUnionExtremes().dataMax; - if (f !== e) a.fixedWidth = t, e = c.toFixedRange(f, f + t, null, y), d.setExtremes(e.min, e.max, !0, null, { trigger: "navigator" }) } - }; - a.mouseMoveHandler = function(c) { - var d = a.scrollbarHeight, - e = a.navigatorLeft, - f = a.navigatorWidth, - g = a.scrollerLeft, - h = a.scrollerWidth, - j = a.range, - k; - if (!c.touches || c.touches[0].pageX !== 0) { - c = b.pointer.normalize(c); - k = c.chartX; - k < e ? k = e : k > g + h - d && (k = g + h - d); - if (a.grabbedLeft) a.hasDragged = !0, a.render(0, 0, k - e, a.otherHandlePos); - else if (a.grabbedRight) a.hasDragged = !0, a.render(0, 0, a.otherHandlePos, k - e); - else if (a.grabbedCenter) a.hasDragged = !0, k < i ? k = i : k > f + i - j && (k = f + i - j), a.render(0, 0, k - i, k - i + j); - if (a.hasDragged && a.scrollbar && a.scrollbar.options.liveRedraw) c.DOMType = c.type, setTimeout(function() { a.mouseUpHandler(c) }, 0) - } - }; - a.mouseUpHandler = function(d) { - var e, f, g = d.DOMEvent || d; - if (a.hasDragged || d.trigger === "scrollbar") { - if (a.zoomedMin === a.otherHandlePos) e = a.fixedExtreme; - else if (a.zoomedMax === a.otherHandlePos) f = - a.fixedExtreme; - if (a.zoomedMax === a.navigatorWidth) f = a.getUnionExtremes().dataMax; - e = c.toFixedRange(a.zoomedMin, a.zoomedMax, e, f); - t(e.min) && b.xAxis[0].setExtremes(e.min, e.max, !0, a.hasDragged ? !1 : null, { trigger: "navigator", triggerOp: "navigator-drag", DOMEvent: g }) - } - if (d.DOMType !== "mousemove") a.grabbedLeft = a.grabbedRight = a.grabbedCenter = a.fixedWidth = a.fixedExtreme = a.otherHandlePos = a.hasDragged = i = null - }; - var k = b.xAxis.length, - l = b.yAxis.length; - b.extraBottomMargin = a.outlineHeight + f.margin; - a.navigatorEnabled ? (a.xAxis = - c = new J(b, D({ breaks: j && j.xAxis.options.breaks, ordinal: j && j.xAxis.options.ordinal }, f.xAxis, { id: "navigator-x-axis", isX: !0, type: "datetime", index: k, height: g, offset: 0, offsetLeft: e, offsetRight: -e, keepOrdinalPadding: !0, startOnTick: !1, endOnTick: !1, minPadding: 0, maxPadding: 0, zoomEnabled: !1 })), a.yAxis = d = new J(b, D(f.yAxis, { id: "navigator-y-axis", alignTicks: !1, height: g, offset: 0, index: l, zoomEnabled: !1 })), j || f.series.data ? a.addBaseSeries() : b.series.length === 0 && S(b, "redraw", function(c, d) { - if (b.series.length > 0 && !a.series) a.setBaseSeries(), - b.redraw = c; - c.call(b, d) - })) : a.xAxis = c = { translate: function(a, c) { - var d = b.xAxis[0], - f = d.getExtremes(), - g = b.plotWidth - 2 * e, - h = zb("min", d.options.min, f.dataMin), - d = zb("max", d.options.max, f.dataMax) - h; - return c ? a * d / g + h : g * (a - h) / d }, toFixedRange: J.prototype.toFixedRange }; - if (b.options.scrollbar.enabled) a.scrollbar = new tb(b.renderer, D(b.options.scrollbar, { margin: a.navigatorEnabled ? 0 : 10 }), b), G(a.scrollbar, "changed", function(c) { - var d = a.navigatorWidth, - e = d * this.to; - d *= this.from; - a.hasDragged = a.scrollbar.hasDragged; - a.render(0, - 0, d, e); - (b.options.scrollbar.liveRedraw || c.DOMType !== "mousemove") && setTimeout(function() { a.mouseUpHandler(c) }) - }); - a.addBaseSeriesEvents(); - S(b, "getMargins", function(b) { - var e = this.legend, - f = e.options; - b.apply(this, [].slice.call(arguments, 1)); - a.top = h = a.navigatorOptions.top || this.chartHeight - a.height - a.scrollbarHeight - this.spacing[2] - (f.verticalAlign === "bottom" && f.enabled && !f.floating ? e.legendHeight + q(f.margin, 10) : 0); - if (c && d) c.options.top = d.options.top = h, c.setAxisSize(), d.setAxisSize() }); - a.addEvents() - }, - getUnionExtremes: function(a) { - var b = - this.chart.xAxis[0], - c = this.xAxis, - d = c.options, - e = b.options, - f; - if (!a || b.dataMin !== null) f = { dataMin: q(d && d.min, zb("min", e.min, b.dataMin, c.dataMin, c.min)), dataMax: q(d && d.max, zb("max", e.max, b.dataMax, c.dataMax, c.max)) }; - return f - }, - setBaseSeries: function(a) { - var b = this.chart, - a = a || b.options.navigator.baseSeries; - this.series && (this.removeBaseSeriesEvents(), this.series.remove()); - this.baseSeries = b.series[a] || typeof a === "string" && b.get(a) || b.series[0]; - this.xAxis && this.addBaseSeries() }, - addBaseSeries: function() { - var a = - this.baseSeries, - b = a ? a.options : {}, - a = b.data, - c = this.navigatorOptions.series, - d; - d = c.data; - this.hasNavigatorData = !!d; - b = D(b, c, { enableMouseTracking: !1, group: "nav", padXAxis: !1, xAxis: "navigator-x-axis", yAxis: "navigator-y-axis", name: "Navigator", showInLegend: !1, stacking: !1, isInternal: !0, visible: !0 }); - b.data = d || a.slice(0); - this.series = this.chart.initSeries(b); - this.addBaseSeriesEvents() - }, - addBaseSeriesEvents: function() { - var a = this.baseSeries; - if (a && a.xAxis && this.navigatorOptions.adaptToUpdatedData !== !1) G(a, "updatedData", - this.updatedDataHandler), G(a.xAxis, "foundExtremes", this.modifyBaseAxisExtremes), a.userOptions.events = v(a.userOptions.event, { updatedData: this.updatedDataHandler }) - }, - modifyNavigatorAxisExtremes: function() { - var a = this.xAxis, - b; - if (a.getExtremes && (b = this.getUnionExtremes(!0)) && (b.dataMin !== a.min || b.dataMax !== a.max)) a.min = b.dataMin, a.max = b.dataMax }, - modifyBaseAxisExtremes: function() { - if (this.chart.scroller.baseSeries && this.chart.scroller.baseSeries.xAxis) { - var a = this.chart.scroller, - b = this.getExtremes(), - c = b.dataMin, - d = b.dataMax, - b = b.max - b.min, - e = a.stickToMin, - f = a.stickToMax, - g, h, i = a.series, - j = !!this.setExtremes; - if (!(this.eventArgs && this.eventArgs.trigger === "rangeSelectorButton") && (e && (h = c, g = h + b), f && (g = d, e || (h = y(g - b, i && i.xData ? i.xData[0] : -Number.MAX_VALUE))), j && (e || f) && z(h))) this.min = this.userMin = h, this.max = this.userMax = g; - a.stickToMin = a.stickToMax = null - } - }, - updatedDataHandler: function() { - var a = this.chart.scroller, - b = a.baseSeries, - c = a.series; - a.stickToMin = z(b.xAxis.min) && b.xAxis.min <= b.xData[0]; - a.stickToMax = Math.round(a.zoomedMax) >= - Math.round(a.navigatorWidth); - if (c && !a.hasNavigatorData) c.options.pointStart = b.xData[0], c.setData(b.options.data, !1, null, !1) - }, - destroy: function() { this.removeEvents(); - o([this.scrollbar, this.xAxis, this.yAxis, this.leftShade, this.rightShade, this.outline], function(a) { a && a.destroy && a.destroy() }); - this.xAxis = this.yAxis = this.leftShade = this.rightShade = this.outline = null; - o([this.handles, this.elementsToDestroy], function(a) { Oa(a) }) } - }; - B.Navigator = Jb; - S(J.prototype, "zoom", function(a, b, c) { - var d = this.chart, - e = d.options, - f = e.chart.zoomType, - g = e.navigator, - e = e.rangeSelector, - h; - if (this.isXAxis && (g && g.enabled || e && e.enabled)) - if (f === "x") d.resetZoomButton = "blocked"; - else if (f === "y") h = !1; - else if (f === "xy") d = this.previousZoom, t(b) ? this.previousZoom = [this.min, this.max] : d && (b = d[0], c = d[1], delete this.previousZoom); - return h !== x ? h : a.call(this, b, c) - }); - S(Da.prototype, "init", function(a, b, c) { G(this, "beforeRender", function() { - var a = this.options; - if (a.navigator.enabled || a.scrollbar.enabled) this.scroller = new Jb(this) }); - a.call(this, b, c) }); - S(P.prototype, - "addPoint", - function(a, b, c, d, e) { - var f = this.options.turboThreshold; - f && this.xData.length > f && ha(b, !0) && this.chart.scroller && ja(20, !0); - a.call(this, b, c, d, e) }); - v(Q, { rangeSelector: { buttonTheme: { width: 28, height: 18, fill: "#f7f7f7", padding: 2, r: 0, "stroke-width": 0, style: { color: "#444", cursor: "pointer", fontWeight: "normal" }, zIndex: 7, states: { hover: { fill: "#e7e7e7" }, select: { fill: "#e7f0f9", style: { color: "black", fontWeight: "bold" } } } }, height: 35, inputPosition: { align: "right" }, labelStyle: { color: "#666" } } }); - Q.lang = D(Q.lang, { - rangeSelectorZoom: "Zoom", - rangeSelectorFrom: "From", - rangeSelectorTo: "To" - }); - Kb.prototype = { - clickButton: function(a, b) { - var c = this, - d = c.selected, - e = c.chart, - f = c.buttons, - g = c.buttonOptions[a], - h = e.xAxis[0], - i = e.scroller && e.scroller.getUnionExtremes() || h || {}, - j = i.dataMin, - k = i.dataMax, - l, m = h && A(E(h.max, q(k, h.max))), - n = g.type, - p, i = g._range, - r, s, t, u = g.dataGrouping; - if (!(j === null || k === null || a === c.selected)) { - e.fixedRange = i; - if (u) this.forcedDataGrouping = !0, J.prototype.setDataGrouping.call(h || { chart: this.chart }, u, !1); - if (n === "month" || n === "year") - if (h) { - if (n = { range: g, max: m, dataMin: j, dataMax: k }, l = h.minFromRange.call(n), z(n.newMax)) m = n.newMax - } else i = g; - else if (i) l = y(m - i, j), m = E(l + i, k); - else if (n === "ytd") - if (h) { - if (k === x) j = Number.MAX_VALUE, k = Number.MIN_VALUE, o(e.series, function(a) { a = a.xData; - j = E(a[0], j); - k = y(a[a.length - 1], k) }), b = !1; - m = new ea(k); - l = m.getFullYear(); - l = r = y(j || 0, ea.UTC(l, 0, 1)); - m = m.getTime(); - m = E(k || m, m) } else { G(e, "beforeRender", function() { c.clickButton(a) }); - return } - else n === "all" && h && (l = j, m = k); - f[d] && f[d].setState(0); - if (f[a]) f[a].setState(2), c.lastSelected = - a; - h ? (h.setExtremes(l, m, q(b, 1), null, { trigger: "rangeSelectorButton", rangeSelectorButton: g }), c.setSelected(a)) : (p = sa(e.options.xAxis)[0], t = p.range, p.range = i, s = p.min, p.min = r, c.setSelected(a), G(e, "load", function() { p.range = t; - p.min = s })) - } - }, - setSelected: function(a) { this.selected = this.options.selected = a }, - defaultButtons: [{ type: "month", count: 1, text: "1m" }, { type: "month", count: 3, text: "3m" }, { type: "month", count: 6, text: "6m" }, { type: "ytd", text: "YTD" }, { type: "year", count: 1, text: "1y" }, { type: "all", text: "All" }], - init: function(a) { - var b = - this, - c = a.options.rangeSelector, - d = c.buttons || [].concat(b.defaultButtons), - e = c.selected, - f = b.blurInputs = function() { - var a = b.minInput, - c = b.maxInput; - a && a.blur && K(a, "blur"); - c && c.blur && K(c, "blur") }; - b.chart = a; - b.options = c; - b.buttons = []; - a.extraTopMargin = c.height; - b.buttonOptions = d; - G(a.container, "mousedown", f); - G(a, "resize", f); - o(d, b.computeButtonRange); - e !== x && d[e] && this.clickButton(e, !1); - G(a, "load", function() { - G(a.xAxis[0], "setExtremes", function(c) { - this.max - this.min !== a.fixedRange && c.trigger !== "rangeSelectorButton" && - c.trigger !== "updatedData" && b.forcedDataGrouping && this.setDataGrouping(!1, !1) - }); - G(a.xAxis[0], "afterSetExtremes", function() { b.updateButtonStates(!0) }) - }) - }, - updateButtonStates: function(a) { - var b = this, - c = this.chart, - d = c.xAxis[0], - e = c.scroller && c.scroller.getUnionExtremes() || d, - f = e.dataMin, - g = e.dataMax, - h = b.selected, - i = b.options.allButtonsEnabled, - j = b.buttons; - a && c.fixedRange !== A(d.max - d.min) && (j[h] && j[h].setState(0), b.setSelected(null)); - o(b.buttonOptions, function(a, e) { - var m = A(d.max - d.min), - n = a._range, - o = a.type, - q = a.count || - 1, - s = n > g - f, - t = n < d.minRange, - u = a.type === "all" && d.max - d.min >= g - f && j[e].state !== 2, - w = a.type === "ytd" && pa("%Y", f) === pa("%Y", g), - v = c.renderer.forExport && e === h, - n = n === m, - x = !d.hasVisibleSeries; - if ((o === "month" || o === "year") && m >= { month: 28, year: 365 }[o] * 864E5 * q && m <= { month: 31, year: 366 }[o] * 864E5 * q) n = !0; - v || n && e !== h && e === b.lastSelected ? (b.setSelected(e), j[e].setState(2)) : !i && (s || t || u || w || x) ? j[e].setState(3) : j[e].state === 3 && j[e].setState(0) - }) - }, - computeButtonRange: function(a) { - var b = a.type, - c = a.count || 1, - d = { - millisecond: 1, - second: 1E3, - minute: 6E4, - hour: 36E5, - day: 864E5, - week: 6048E5 - }; - if (d[b]) a._range = d[b] * c; - else if (b === "month" || b === "year") a._range = { month: 30, year: 365 }[b] * 864E5 * c - }, - setInputValue: function(a, b) { - var c = this.chart.options.rangeSelector; - if (t(b)) this[a + "Input"].HCTime = b; - this[a + "Input"].value = pa(c.inputEditDateFormat || "%Y-%m-%d", this[a + "Input"].HCTime); - this[a + "DateBox"].attr({ text: pa(c.inputDateFormat || "%b %e, %Y", this[a + "Input"].HCTime) }) }, - showInput: function(a) { - var b = this.inputGroup, - c = this[a + "DateBox"]; - O(this[a + "Input"], { - left: b.translateX + - c.x + "px", - top: b.translateY + "px", - width: c.width - 2 + "px", - height: c.height - 2 + "px", - border: "2px solid silver" - }) - }, - hideInput: function(a) { O(this[a + "Input"], { border: 0, width: "1px", height: "1px" }); - this.setInputValue(a) }, - drawInput: function(a) { - function b() { - var a = j.value, - b = (g.inputDateParser || ea.parse)(a), - e = d.xAxis[0], - f = e.dataMin, - h = e.dataMax; - if (b !== j.previousValue) j.previousValue = b, z(b) || (b = a.split("-"), b = ea.UTC(H(b[0]), H(b[1]) - 1, H(b[2]))), z(b) && (Q.global.useUTC || (b += (new ea).getTimezoneOffset() * 6E4), i ? b > c.maxInput.HCTime ? - b = x : b < f && (b = f) : b < c.minInput.HCTime ? b = x : b > h && (b = h), b !== x && d.xAxis[0].setExtremes(i ? b : e.min, i ? e.max : b, x, x, { trigger: "rangeSelectorInput" })) - } - var c = this, - d = c.chart, - e = d.renderer.style, - f = d.renderer, - g = d.options.rangeSelector, - h = c.div, - i = a === "min", - j, k, l = this.inputGroup; - this[a + "Label"] = k = f.label(Q.lang[i ? "rangeSelectorFrom" : "rangeSelectorTo"], this.inputGroup.offset).attr({ padding: 2 }).css(D(e, g.labelStyle)).add(l); - l.offset += k.width + 5; - this[a + "DateBox"] = f = f.label("", l.offset).attr({ - padding: 2, - width: g.inputBoxWidth || - 90, - height: g.inputBoxHeight || 17, - stroke: g.inputBoxBorderColor || "silver", - "stroke-width": 1 - }).css(D({ textAlign: "center", color: "#444" }, e, g.inputStyle)).on("click", function() { c.showInput(a); - c[a + "Input"].focus() }).add(l); - l.offset += f.width + (i ? 10 : 0); - this[a + "Input"] = j = ia("input", { name: a, className: "highcharts-range-selector", type: "text" }, v({ position: "absolute", border: 0, width: "1px", height: "1px", padding: 0, textAlign: "center", fontSize: e.fontSize, fontFamily: e.fontFamily, left: "-9em", top: d.plotTop + "px" }, g.inputStyle), - h); - j.onfocus = function() { c.showInput(a) }; - j.onblur = function() { c.hideInput(a) }; - j.onchange = b; - j.onkeypress = function(a) { a.keyCode === 13 && b() } - }, - getPosition: function() { - var a = this.chart, - b = a.options.rangeSelector, - a = q((b.buttonPosition || {}).y, a.plotTop - a.axisOffset[0] - b.height); - return { buttonTop: a, inputTop: a - 10 } }, - render: function(a, b) { - var c = this, - d = c.chart, - e = d.renderer, - f = d.container, - g = d.options, - h = g.exporting && g.exporting.enabled !== !1 && g.navigation && g.navigation.buttonOptions, - i = g.rangeSelector, - j = c.buttons, - g = Q.lang, - k = c.div, - k = c.inputGroup, - l = i.buttonTheme, - m = i.buttonPosition || {}, - n = i.inputEnabled, - p = l && l.states, - r = d.plotLeft, - s, x = this.getPosition(), - u = c.group, - w = c.rendered; - if (!w && (c.group = u = e.g("range-selector-buttons").add(), c.zoomText = e.text(g.rangeSelectorZoom, q(m.x, r), 15).css(i.labelStyle).add(u), s = q(m.x, r) + c.zoomText.getBBox().width + 5, o(c.buttonOptions, function(a, b) { - j[b] = e.button(a.text, s, 0, function() { c.clickButton(b); - c.isActive = !0 }, l, p && p.hover, p && p.select, p && p.disabled).css({ textAlign: "center" }).add(u); - s += j[b].width + - q(i.buttonSpacing, 5); - c.selected === b && j[b].setState(2) - }), c.updateButtonStates(), n !== !1)) c.div = k = ia("div", null, { position: "relative", height: 0, zIndex: 1 }), f.parentNode.insertBefore(k, f), c.inputGroup = k = e.g("input-group").add(), k.offset = 0, c.drawInput("min"), c.drawInput("max"); - u[w ? "animate" : "attr"]({ translateY: x.buttonTop }); - n !== !1 && (k.align(v({ y: x.inputTop, width: k.offset, x: h && x.inputTop < (h.y || 0) + h.height - d.spacing[0] ? -40 : 0 }, i.inputPosition), !0, d.spacingBox), t(n) || (d = u.getBBox(), k[k.translateX < d.x + d.width + - 10 ? "hide" : "show"]()), c.setInputValue("min", a), c.setInputValue("max", b)); - c.rendered = !0 - }, - destroy: function() { - var a = this.minInput, - b = this.maxInput, - c = this.chart, - d = this.blurInputs, - e; - U(c.container, "mousedown", d); - U(c, "resize", d); - Oa(this.buttons); - if (a) a.onfocus = a.onblur = a.onchange = null; - if (b) b.onfocus = b.onblur = b.onchange = null; - for (e in this) this[e] && e !== "chart" && (this[e].destroy ? this[e].destroy() : this[e].nodeType && Wa(this[e])), this[e] = null } - }; - J.prototype.toFixedRange = function(a, b, c, d) { - var e = this.chart && this.chart.fixedRange, - a = q(c, this.translate(a, !0)), - b = q(d, this.translate(b, !0)), - c = e && (b - a) / e; - c > 0.7 && c < 1.3 && (d ? a = b - e : b = a + e); - z(a) || (a = b = void 0); - return { min: a, max: b } - }; - J.prototype.minFromRange = function() { - var a = this.range, - b = { month: "Month", year: "FullYear" }[a.type], - c, d = this.max, - e, f, g = function(a, c) { - var d = new ea(a); - d["set" + b](d["get" + b]() + c); - return d.getTime() - a }; - z(a) ? (c = this.max - a, f = a) : c = d + g(d, -a.count); - e = q(this.dataMin, Number.MIN_VALUE); - z(c) || (c = e); - if (c <= e) c = e, f === void 0 && (f = g(c, a.count)), this.newMax = E(c + f, this.dataMax); - z(d) || (c = - void 0); - return c - }; - S(Da.prototype, "init", function(a, b, c) { G(this, "init", function() { - if (this.options.rangeSelector.enabled) this.rangeSelector = new Kb(this) }); - a.call(this, b, c) }); - B.RangeSelector = Kb; - Da.prototype.callbacks.push(function(a) { - function b() { d = a.xAxis[0].getExtremes(); - z(d.min) && f.render(d.min, d.max) } - - function c(a) { f.render(a.min, a.max) } - var d, e = a.scroller, - f = a.rangeSelector; - e && (d = a.xAxis[0].getExtremes(), e.render(d.min, d.max)); - f && (G(a.xAxis[0], "afterSetExtremes", c), G(a, "resize", b), b()); - G(a, "destroy", - function() { f && (U(a, "resize", b), U(a.xAxis[0], "afterSetExtremes", c)) }) - }); - B.StockChart = B.stockChart = function(a, b, c) { - var d = Ea(a) || a.nodeName, - e = arguments[d ? 1 : 0], - f = e.series, - g, h = q(e.navigator && e.navigator.enabled, !0) ? { startOnTick: !1, endOnTick: !1 } : null, - i = { marker: { enabled: !1, radius: 2 } }, - j = { shadow: !1, borderWidth: 0 }; - e.xAxis = wa(sa(e.xAxis || {}), function(a) { - return D({ minPadding: 0, maxPadding: 0, ordinal: !0, title: { text: null }, labels: { overflow: "justify" }, showLastLabel: !0 }, a, { type: "datetime", categories: null }, h) }); - e.yAxis = - wa(sa(e.yAxis || {}), function(a) { g = q(a.opposite, !0); - return D({ labels: { y: -2 }, opposite: g, showLastLabel: !1, title: { text: null } }, a) }); - e.series = null; - e = D({ chart: { panning: !0, pinchType: "x" }, navigator: { enabled: !0 }, scrollbar: { enabled: !0 }, rangeSelector: { enabled: !0 }, title: { text: null, style: { fontSize: "16px" } }, tooltip: { shared: !0, crosshairs: !0 }, legend: { enabled: !1 }, plotOptions: { line: i, spline: i, area: i, areaspline: i, arearange: i, areasplinerange: i, column: j, columnrange: j, candlestick: j, ohlc: j } }, e, { _stock: !0, chart: { inverted: !1 } }); - e.series = f; - return d ? new Da(a, e, c) : new Da(e, b) - }; - S(ab.prototype, "init", function(a, b, c) { - var d = c.chart.pinchType || ""; - a.call(this, b, c); - this.pinchX = this.pinchHor = d.indexOf("x") !== -1; - this.pinchY = this.pinchVert = d.indexOf("y") !== -1; - this.hasZoom = this.hasZoom || this.pinchHor || this.pinchVert }); - S(J.prototype, "autoLabelAlign", function(a) { - var b = this.chart, - c = this.options, - b = b._labelPanes = b._labelPanes || {}, - d = this.options.labels; - if (this.chart.options._stock && this.coll === "yAxis" && (c = c.top + "," + c.height, !b[c] && d.enabled)) { - if (d.x === - 15) d.x = 0; - if (d.align === void 0) d.align = "right"; - b[c] = 1; - return "right" - } - return a.call(this, [].slice.call(arguments, 1)) - }); - S(J.prototype, "getPlotLinePath", function(a, b, c, d, e, f) { - var g = this, - h = this.isLinked && !this.series ? this.linkedParent.series : this.series, - i = g.chart, - j = i.renderer, - k = g.left, - l = g.top, - m, n, p, r, s = [], - v = [], - u, w; - if (g.coll === "colorAxis") return a.apply(this, [].slice.call(arguments, 1)); - v = g.isXAxis ? t(g.options.yAxis) ? [i.yAxis[g.options.yAxis]] : wa(h, function(a) { - return a.yAxis }) : t(g.options.xAxis) ? [i.xAxis[g.options.xAxis]] : - wa(h, function(a) { - return a.xAxis }); - o(g.isXAxis ? i.yAxis : i.xAxis, function(a) { - if (t(a.options.id) ? a.options.id.indexOf("navigator") === -1 : 1) { - var b = a.isXAxis ? "yAxis" : "xAxis", - b = t(a.options[b]) ? i[b][a.options[b]] : i[b][0]; - g === b && v.push(a) } }); - u = v.length ? [] : [g.isXAxis ? i.yAxis[0] : i.xAxis[0]]; - o(v, function(a) { qa(a, u) === -1 && u.push(a) }); - w = q(f, g.translate(b, null, null, d)); - z(w) && (g.horiz ? o(u, function(a) { - var b; - n = a.pos; - r = n + a.len; - m = p = A(w + g.transB); - if (m < k || m > k + g.width) e ? m = p = E(y(k, m), k + g.width) : b = !0; - b || s.push("M", m, n, "L", - p, r) - }) : o(u, function(a) { - var b; - m = a.pos; - p = m + a.len; - n = r = A(l + g.height - w); - if (n < l || n > l + g.height) e ? n = r = E(y(l, n), g.top + g.height) : b = !0; - b || s.push("M", m, n, "L", p, r) })); - return s.length > 0 ? j.crispPolyLine(s, c || 1) : null - }); - J.prototype.getPlotBandPath = function(a, b) { - var c = this.getPlotLinePath(b, null, null, !0), - d = this.getPlotLinePath(a, null, null, !0), - e = [], - f; - if (d && c && d.toString() !== c.toString()) - for (f = 0; f < d.length; f += 6) e.push("M", d[f + 1], d[f + 2], "L", d[f + 4], d[f + 5], c[f + 4], c[f + 5], c[f + 1], c[f + 2]); - else e = null; - return e }; - za.prototype.crispPolyLine = - function(a, b) { - var c; - for (c = 0; c < a.length; c += 6) a[c + 1] === a[c + 4] && (a[c + 1] = a[c + 4] = A(a[c + 1]) - b % 2 / 2), a[c + 2] === a[c + 5] && (a[c + 2] = a[c + 5] = A(a[c + 2]) + b % 2 / 2); - return a }; - if (Za === B.VMLRenderer) nb.prototype.crispPolyLine = za.prototype.crispPolyLine; - S(J.prototype, "hideCrosshair", function(a, b) { a.call(this, b); - if (this.crossLabel) this.crossLabel = this.crossLabel.hide() }); - S(J.prototype, "drawCrosshair", function(a, b, c) { - var d, e; - a.call(this, b, c); - if (t(this.crosshair.label) && this.crosshair.label.enabled && this.cross) { - var a = this.chart, - f = this.options.crosshair.label, - g = this.horiz, - h = this.opposite, - i = this.left, - j = this.top, - k = this.crossLabel, - l, m = f.format, - n = "", - o = this.options.tickPosition === "inside", - r = this.crosshair.snap !== !1; - b || (b = this.cross && this.cross.e); - l = g ? "center" : h ? this.labelAlign === "right" ? "right" : "left" : this.labelAlign === "left" ? "left" : "center"; - if (!k) k = this.crossLabel = a.renderer.label(null, null, null, f.shape || "callout").attr({ - align: f.align || l, - zIndex: 12, - fill: f.backgroundColor || this.series[0] && this.series[0].color || "gray", - padding: q(f.padding, - 8), - stroke: f.borderColor || "", - "stroke-width": f.borderWidth || 0, - r: q(f.borderRadius, 3) - }).css(v({ color: "white", fontWeight: "normal", fontSize: "11px", textAlign: "center" }, f.style)).add(); - g ? (l = r ? c.plotX + i : b.chartX, j += h ? 0 : this.height) : (l = h ? this.width + i : 0, j = r ? c.plotY + j : b.chartY); - !m && !f.formatter && (this.isDatetimeAxis && (n = "%b %d, %Y"), m = "{value" + (n ? ":" + n : "") + "}"); - b = r ? c[this.isXAxis ? "x" : "y"] : this.toValue(g ? b.chartX : b.chartY); - k.attr({ - text: m ? Ma(m, { value: b }) : f.formatter.call(this, b), - anchorX: g ? l : this.opposite ? 0 : a.chartWidth, - anchorY: g ? this.opposite ? a.chartHeight : 0 : j, - x: l, - y: j, - visibility: "visible" - }); - b = k.getBBox(); - if (g) { - if (o && !h || !o && h) j = k.y - b.height } else j = k.y - b.height / 2; - g ? (d = i - b.x, e = i + this.width - b.x) : (d = this.labelAlign === "left" ? i : 0, e = this.labelAlign === "right" ? i + this.width : a.chartWidth); - k.translateX < d && (l += d - k.translateX); - k.translateX + b.width >= e && (l -= k.translateX + b.width - e); - k.attr({ x: l, y: j, visibility: "visible" }) - } - }); - var jc = la.init, - kc = la.processData, - lc = Ja.prototype.tooltipFormatter; - la.init = function() { - jc.apply(this, arguments); - this.setCompare(this.options.compare) - }; - la.setCompare = function(a) { this.modifyValue = a === "value" || a === "percent" ? function(b, c) { - var d = this.compareValue; - if (b !== x && (b = a === "value" ? b - d : b = 100 * (b / d) - 100, c)) c.change = b; - return b } : null; - this.userOptions.compare = a; - if (this.chart.hasRendered) this.isDirty = !0 }; - la.processData = function() { - var a, b = -1, - c, d, e, f; - kc.apply(this, arguments); - if (this.xAxis && this.processedYData) { - c = this.processedXData; - d = this.processedYData; - e = d.length; - this.pointArrayMap && (b = qa(this.pointValKey || "y", this.pointArrayMap)); - for (a = 0; a < e - 1; a++) - if (f = b > -1 ? d[a][b] : d[a], z(f) && c[a + 1] >= this.xAxis.min && f !== 0) { this.compareValue = f; - break } - } - }; - S(la, "getExtremes", function(a) { - var b; - a.apply(this, [].slice.call(arguments, 1)); - if (this.modifyValue) b = [this.modifyValue(this.dataMin), this.modifyValue(this.dataMax)], this.dataMin = Na(b), this.dataMax = Fa(b) }); - J.prototype.setCompare = function(a, b) { this.isXAxis || (o(this.series, function(b) { b.setCompare(a) }), q(b, !0) && this.chart.redraw()) }; - Ja.prototype.tooltipFormatter = function(a) { - a = a.replace("{point.change}", - (this.change > 0 ? "+" : "") + B.numberFormat(this.change, q(this.series.tooltipOptions.changeDecimals, 2))); - return lc.apply(this, [a]) - }; - S(P.prototype, "render", function(a) { - if (this.chart.options._stock && this.xAxis) !this.clipBox && this.animate ? (this.clipBox = D(this.chart.clipBox), this.clipBox.width = this.xAxis.len, this.clipBox.height = this.yAxis.len) : this.chart[this.sharedClipKey] && (Qa(this.chart[this.sharedClipKey]), this.chart[this.sharedClipKey].attr({ width: this.xAxis.len, height: this.yAxis.len })); - a.call(this) }); - v(B, { Color: xa, Point: Ja, Tick: eb, Renderer: Za, SVGElement: ba, SVGRenderer: za, arrayMin: Na, arrayMax: Fa, charts: ca, correctFloat: V, dateFormat: pa, error: ja, format: Ma, pathAnim: void 0, getOptions: function() { - return Q }, hasBidiBug: bc, isTouchDevice: lb, setOptions: function(a) { Q = D(!0, Q, a); - Qb(); - return Q }, addEvent: G, removeEvent: U, createElement: ia, discardElement: Wa, css: O, each: o, map: wa, merge: D, splat: sa, stableSort: pb, extendClass: oa, pInt: H, svg: ma, canvas: ua, vml: !ma && !ua, product: "Highstock", version: "4.2.6" }); - return B -}); diff --git a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/jquery.min.js b/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/jquery.min.js deleted file mode 100644 index e9439454da..0000000000 --- a/samples/simm-valuation-demo/src/main/resources/simmvaluationweb/libs/jquery.min.js +++ /dev/null @@ -1,1636 +0,0 @@ -/*! jQuery v3.1.0 | (c) jQuery Foundation | jquery.org/license */ ! function(a, b) { "use strict"; "object" == typeof module && "object" == typeof module.exports ? module.exports = a.document ? b(a, !0) : function(a) { - if (!a.document) throw new Error("jQuery requires a window with a document"); - return b(a) } : b(a) }("undefined" != typeof window ? window : this, function(a, b) { - "use strict"; - var c = [], - d = a.document, - e = Object.getPrototypeOf, - f = c.slice, - g = c.concat, - h = c.push, - i = c.indexOf, - j = {}, - k = j.toString, - l = j.hasOwnProperty, - m = l.toString, - n = m.call(Object), - o = {}; - - function p(a, b) { b = b || d; - var c = b.createElement("script"); - c.text = a, b.head.appendChild(c).parentNode.removeChild(c) } - var q = "3.1.0", - r = function(a, b) { - return new r.fn.init(a, b) }, - s = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - t = /^-ms-/, - u = /-([a-z])/g, - v = function(a, b) { - return b.toUpperCase() }; - r.fn = r.prototype = { jquery: q, constructor: r, length: 0, toArray: function() { - return f.call(this) }, get: function(a) { - return null != a ? a < 0 ? this[a + this.length] : this[a] : f.call(this) }, pushStack: function(a) { - var b = r.merge(this.constructor(), a); - return b.prevObject = this, b }, each: function(a) { - return r.each(this, a) }, map: function(a) { - return this.pushStack(r.map(this, function(b, c) { - return a.call(b, c, b) })) }, slice: function() { - return this.pushStack(f.apply(this, arguments)) }, first: function() { - return this.eq(0) }, last: function() { - return this.eq(-1) }, eq: function(a) { - var b = this.length, - c = +a + (a < 0 ? b : 0); - return this.pushStack(c >= 0 && c < b ? [this[c]] : []) }, end: function() { - return this.prevObject || this.constructor() }, push: h, sort: c.sort, splice: c.splice }, r.extend = r.fn.extend = function() { - var a, b, c, d, e, f, g = arguments[0] || {}, - h = 1, - i = arguments.length, - j = !1; - for ("boolean" == typeof g && (j = g, g = arguments[h] || {}, h++), "object" == typeof g || r.isFunction(g) || (g = {}), h === i && (g = this, h--); h < i; h++) - if (null != (a = arguments[h])) - for (b in a) c = g[b], d = a[b], g !== d && (j && d && (r.isPlainObject(d) || (e = r.isArray(d))) ? (e ? (e = !1, f = c && r.isArray(c) ? c : []) : f = c && r.isPlainObject(c) ? c : {}, g[b] = r.extend(j, f, d)) : void 0 !== d && (g[b] = d)); - return g }, r.extend({ expando: "jQuery" + (q + Math.random()).replace(/\D/g, ""), isReady: !0, error: function(a) { - throw new Error(a) }, noop: function() {}, isFunction: function(a) { - return "function" === r.type(a) }, isArray: Array.isArray, isWindow: function(a) { - return null != a && a === a.window }, isNumeric: function(a) { - var b = r.type(a); - return ("number" === b || "string" === b) && !isNaN(a - parseFloat(a)) }, isPlainObject: function(a) { - var b, c; - return !(!a || "[object Object]" !== k.call(a)) && (!(b = e(a)) || (c = l.call(b, "constructor") && b.constructor, "function" == typeof c && m.call(c) === n)) }, isEmptyObject: function(a) { - var b; - for (b in a) return !1; - return !0 }, type: function(a) { - return null == a ? a + "" : "object" == typeof a || "function" == typeof a ? j[k.call(a)] || "object" : typeof a }, globalEval: function(a) { p(a) }, camelCase: function(a) { - return a.replace(t, "ms-").replace(u, v) }, nodeName: function(a, b) { - return a.nodeName && a.nodeName.toLowerCase() === b.toLowerCase() }, each: function(a, b) { - var c, d = 0; - if (w(a)) { - for (c = a.length; d < c; d++) - if (b.call(a[d], d, a[d]) === !1) break } else - for (d in a) - if (b.call(a[d], d, a[d]) === !1) break; return a }, trim: function(a) { - return null == a ? "" : (a + "").replace(s, "") }, makeArray: function(a, b) { - var c = b || []; - return null != a && (w(Object(a)) ? r.merge(c, "string" == typeof a ? [a] : a) : h.call(c, a)), c }, inArray: function(a, b, c) { - return null == b ? -1 : i.call(b, a, c) }, merge: function(a, b) { - for (var c = +b.length, d = 0, e = a.length; d < c; d++) a[e++] = b[d]; - return a.length = e, a }, grep: function(a, b, c) { - for (var d, e = [], f = 0, g = a.length, h = !c; f < g; f++) d = !b(a[f], f), d !== h && e.push(a[f]); - return e }, map: function(a, b, c) { - var d, e, f = 0, - h = []; - if (w(a)) - for (d = a.length; f < d; f++) e = b(a[f], f, c), null != e && h.push(e); - else - for (f in a) e = b(a[f], f, c), null != e && h.push(e); - return g.apply([], h) }, guid: 1, proxy: function(a, b) { - var c, d, e; - if ("string" == typeof b && (c = a[b], b = a, a = c), r.isFunction(a)) return d = f.call(arguments, 2), e = function() { - return a.apply(b || this, d.concat(f.call(arguments))) }, e.guid = a.guid = a.guid || r.guid++, e }, now: Date.now, support: o }), "function" == typeof Symbol && (r.fn[Symbol.iterator] = c[Symbol.iterator]), r.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function(a, b) { j["[object " + b + "]"] = b.toLowerCase() }); - - function w(a) { - var b = !!a && "length" in a && a.length, - c = r.type(a); - return "function" !== c && !r.isWindow(a) && ("array" === c || 0 === b || "number" == typeof b && b > 0 && b - 1 in a) } - var x = function(a) { - var b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u = "sizzle" + 1 * new Date, - v = a.document, - w = 0, - x = 0, - y = ha(), - z = ha(), - A = ha(), - B = function(a, b) { - return a === b && (l = !0), 0 }, - C = {}.hasOwnProperty, - D = [], - E = D.pop, - F = D.push, - G = D.push, - H = D.slice, - I = function(a, b) { - for (var c = 0, d = a.length; c < d; c++) - if (a[c] === b) return c; - return -1 }, - J = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - K = "[\\x20\\t\\r\\n\\f]", - L = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+", - M = "\\[" + K + "*(" + L + ")(?:" + K + "*([*^$|!~]?=)" + K + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + L + "))|)" + K + "*\\]", - N = ":(" + L + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + M + ")*)|.*)\\)|)", - O = new RegExp(K + "+", "g"), - P = new RegExp("^" + K + "+|((?:^|[^\\\\])(?:\\\\.)*)" + K + "+$", "g"), - Q = new RegExp("^" + K + "*," + K + "*"), - R = new RegExp("^" + K + "*([>+~]|" + K + ")" + K + "*"), - S = new RegExp("=" + K + "*([^\\]'\"]*?)" + K + "*\\]", "g"), - T = new RegExp(N), - U = new RegExp("^" + L + "$"), - V = { ID: new RegExp("^#(" + L + ")"), CLASS: new RegExp("^\\.(" + L + ")"), TAG: new RegExp("^(" + L + "|[*])"), ATTR: new RegExp("^" + M), PSEUDO: new RegExp("^" + N), CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + K + "*(even|odd|(([+-]|)(\\d*)n|)" + K + "*(?:([+-]|)" + K + "*(\\d+)|))" + K + "*\\)|)", "i"), bool: new RegExp("^(?:" + J + ")$", "i"), needsContext: new RegExp("^" + K + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + K + "*((?:-\\d)?\\d*)" + K + "*\\)|)(?=[^-]|$)", "i") }, - W = /^(?:input|select|textarea|button)$/i, - X = /^h\d$/i, - Y = /^[^{]+\{\s*\[native \w/, - Z = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - $ = /[+~]/, - _ = new RegExp("\\\\([\\da-f]{1,6}" + K + "?|(" + K + ")|.)", "ig"), - aa = function(a, b, c) { - var d = "0x" + b - 65536; - return d !== d || c ? b : d < 0 ? String.fromCharCode(d + 65536) : String.fromCharCode(d >> 10 | 55296, 1023 & d | 56320) }, - ba = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g, - ca = function(a, b) { - return b ? "\0" === a ? "\ufffd" : a.slice(0, -1) + "\\" + a.charCodeAt(a.length - 1).toString(16) + " " : "\\" + a }, - da = function() { m() }, - ea = ta(function(a) { - return a.disabled === !0 }, { dir: "parentNode", next: "legend" }); - try { G.apply(D = H.call(v.childNodes), v.childNodes), D[v.childNodes.length].nodeType } catch (fa) { G = { apply: D.length ? function(a, b) { F.apply(a, H.call(b)) } : function(a, b) { - var c = a.length, - d = 0; - while (a[c++] = b[d++]); - a.length = c - 1 } } } - - function ga(a, b, d, e) { - var f, h, j, k, l, o, r, s = b && b.ownerDocument, - w = b ? b.nodeType : 9; - if (d = d || [], "string" != typeof a || !a || 1 !== w && 9 !== w && 11 !== w) return d; - if (!e && ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, p)) { - if (11 !== w && (l = Z.exec(a))) - if (f = l[1]) { - if (9 === w) { - if (!(j = b.getElementById(f))) return d; - if (j.id === f) return d.push(j), d } else if (s && (j = s.getElementById(f)) && t(b, j) && j.id === f) return d.push(j), d } else { - if (l[2]) return G.apply(d, b.getElementsByTagName(a)), d; - if ((f = l[3]) && c.getElementsByClassName && b.getElementsByClassName) return G.apply(d, b.getElementsByClassName(f)), d } - if (c.qsa && !A[a + " "] && (!q || !q.test(a))) { - if (1 !== w) s = b, r = a; - else if ("object" !== b.nodeName.toLowerCase()) { - (k = b.getAttribute("id")) ? k = k.replace(ba, ca): b.setAttribute("id", k = u), o = g(a), h = o.length; - while (h--) o[h] = "#" + k + " " + sa(o[h]); - r = o.join(","), s = $.test(a) && qa(b.parentNode) || b } - if (r) try { - return G.apply(d, s.querySelectorAll(r)), d } catch (x) {} finally { k === u && b.removeAttribute("id") } } } - return i(a.replace(P, "$1"), b, d, e) } - - function ha() { - var a = []; - - function b(c, e) { - return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e } - return b } - - function ia(a) { - return a[u] = !0, a } - - function ja(a) { - var b = n.createElement("fieldset"); - try { - return !!a(b) } catch (c) { - return !1 } finally { b.parentNode && b.parentNode.removeChild(b), b = null } } - - function ka(a, b) { - var c = a.split("|"), - e = c.length; - while (e--) d.attrHandle[c[e]] = b } - - function la(a, b) { - var c = b && a, - d = c && 1 === a.nodeType && 1 === b.nodeType && a.sourceIndex - b.sourceIndex; - if (d) return d; - if (c) - while (c = c.nextSibling) - if (c === b) return -1; - return a ? 1 : -1 } - - function ma(a) { - return function(b) { - var c = b.nodeName.toLowerCase(); - return "input" === c && b.type === a } } - - function na(a) { - return function(b) { - var c = b.nodeName.toLowerCase(); - return ("input" === c || "button" === c) && b.type === a } } - - function oa(a) { - return function(b) { - return "label" in b && b.disabled === a || "form" in b && b.disabled === a || "form" in b && b.disabled === !1 && (b.isDisabled === a || b.isDisabled !== !a && ("label" in b || !ea(b)) !== a) } } - - function pa(a) { - return ia(function(b) { - return b = +b, ia(function(c, d) { - var e, f = a([], c.length, b), - g = f.length; - while (g--) c[e = f[g]] && (c[e] = !(d[e] = c[e])) }) }) } - - function qa(a) { - return a && "undefined" != typeof a.getElementsByTagName && a } - c = ga.support = {}, f = ga.isXML = function(a) { - var b = a && (a.ownerDocument || a).documentElement; - return !!b && "HTML" !== b.nodeName }, m = ga.setDocument = function(a) { - var b, e, g = a ? a.ownerDocument || a : v; - return g !== n && 9 === g.nodeType && g.documentElement ? (n = g, o = n.documentElement, p = !f(n), v !== n && (e = n.defaultView) && e.top !== e && (e.addEventListener ? e.addEventListener("unload", da, !1) : e.attachEvent && e.attachEvent("onunload", da)), c.attributes = ja(function(a) { - return a.className = "i", !a.getAttribute("className") }), c.getElementsByTagName = ja(function(a) { - return a.appendChild(n.createComment("")), !a.getElementsByTagName("*").length }), c.getElementsByClassName = Y.test(n.getElementsByClassName), c.getById = ja(function(a) { - return o.appendChild(a).id = u, !n.getElementsByName || !n.getElementsByName(u).length }), c.getById ? (d.find.ID = function(a, b) { - if ("undefined" != typeof b.getElementById && p) { - var c = b.getElementById(a); - return c ? [c] : [] } }, d.filter.ID = function(a) { - var b = a.replace(_, aa); - return function(a) { - return a.getAttribute("id") === b } }) : (delete d.find.ID, d.filter.ID = function(a) { - var b = a.replace(_, aa); - return function(a) { - var c = "undefined" != typeof a.getAttributeNode && a.getAttributeNode("id"); - return c && c.value === b } }), d.find.TAG = c.getElementsByTagName ? function(a, b) { - return "undefined" != typeof b.getElementsByTagName ? b.getElementsByTagName(a) : c.qsa ? b.querySelectorAll(a) : void 0 } : function(a, b) { - var c, d = [], - e = 0, - f = b.getElementsByTagName(a); - if ("*" === a) { - while (c = f[e++]) 1 === c.nodeType && d.push(c); - return d } - return f }, d.find.CLASS = c.getElementsByClassName && function(a, b) { - if ("undefined" != typeof b.getElementsByClassName && p) return b.getElementsByClassName(a) }, r = [], q = [], (c.qsa = Y.test(n.querySelectorAll)) && (ja(function(a) { o.appendChild(a).innerHTML = "
", a.querySelectorAll("[msallowcapture^='']").length && q.push("[*^$]=" + K + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + K + "*(?:value|" + J + ")"), a.querySelectorAll("[id~=" + u + "-]").length || q.push("~="), a.querySelectorAll(":checked").length || q.push(":checked"), a.querySelectorAll("a#" + u + "+*").length || q.push(".#.+[+~]") }), ja(function(a) { a.innerHTML = ""; - var b = n.createElement("input"); - b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + K + "*[*^$|!~]?="), 2 !== a.querySelectorAll(":enabled").length && q.push(":enabled", ":disabled"), o.appendChild(a).disabled = !0, 2 !== a.querySelectorAll(":disabled").length && q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:") })), (c.matchesSelector = Y.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ja(function(a) { c.disconnectedMatch = s.call(a, "*"), s.call(a, "[s!='']:x"), r.push("!=", N) }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = Y.test(o.compareDocumentPosition), t = b || Y.test(o.contains) ? function(a, b) { - var c = 9 === a.nodeType ? a.documentElement : a, - d = b && b.parentNode; - return a === d || !(!d || 1 !== d.nodeType || !(c.contains ? c.contains(d) : a.compareDocumentPosition && 16 & a.compareDocumentPosition(d))) } : function(a, b) { - if (b) - while (b = b.parentNode) - if (b === a) return !0; - return !1 }, B = b ? function(a, b) { - if (a === b) return l = !0, 0; - var d = !a.compareDocumentPosition - !b.compareDocumentPosition; - return d ? d : (d = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) : 1, 1 & d || !c.sortDetached && b.compareDocumentPosition(a) === d ? a === n || a.ownerDocument === v && t(v, a) ? -1 : b === n || b.ownerDocument === v && t(v, b) ? 1 : k ? I(k, a) - I(k, b) : 0 : 4 & d ? -1 : 1) } : function(a, b) { - if (a === b) return l = !0, 0; - var c, d = 0, - e = a.parentNode, - f = b.parentNode, - g = [a], - h = [b]; - if (!e || !f) return a === n ? -1 : b === n ? 1 : e ? -1 : f ? 1 : k ? I(k, a) - I(k, b) : 0; - if (e === f) return la(a, b); - c = a; - while (c = c.parentNode) g.unshift(c); - c = b; - while (c = c.parentNode) h.unshift(c); - while (g[d] === h[d]) d++; - return d ? la(g[d], h[d]) : g[d] === v ? -1 : h[d] === v ? 1 : 0 }, n) : n }, ga.matches = function(a, b) { - return ga(a, null, null, b) }, ga.matchesSelector = function(a, b) { - if ((a.ownerDocument || a) !== n && m(a), b = b.replace(S, "='$1']"), c.matchesSelector && p && !A[b + " "] && (!r || !r.test(b)) && (!q || !q.test(b))) try { - var d = s.call(a, b); - if (d || c.disconnectedMatch || a.document && 11 !== a.document.nodeType) return d } catch (e) {} - return ga(b, n, null, [a]).length > 0 }, ga.contains = function(a, b) { - return (a.ownerDocument || a) !== n && m(a), t(a, b) }, ga.attr = function(a, b) { - (a.ownerDocument || a) !== n && m(a); - var e = d.attrHandle[b.toLowerCase()], - f = e && C.call(d.attrHandle, b.toLowerCase()) ? e(a, b, !p) : void 0; - return void 0 !== f ? f : c.attributes || !p ? a.getAttribute(b) : (f = a.getAttributeNode(b)) && f.specified ? f.value : null }, ga.escape = function(a) { - return (a + "").replace(ba, ca) }, ga.error = function(a) { - throw new Error("Syntax error, unrecognized expression: " + a) }, ga.uniqueSort = function(a) { - var b, d = [], - e = 0, - f = 0; - if (l = !c.detectDuplicates, k = !c.sortStable && a.slice(0), a.sort(B), l) { - while (b = a[f++]) b === a[f] && (e = d.push(f)); - while (e--) a.splice(d[e], 1) } - return k = null, a }, e = ga.getText = function(a) { - var b, c = "", - d = 0, - f = a.nodeType; - if (f) { - if (1 === f || 9 === f || 11 === f) { - if ("string" == typeof a.textContent) return a.textContent; - for (a = a.firstChild; a; a = a.nextSibling) c += e(a) } else if (3 === f || 4 === f) return a.nodeValue } else - while (b = a[d++]) c += e(b); - return c }, d = ga.selectors = { cacheLength: 50, createPseudo: ia, match: V, attrHandle: {}, find: {}, relative: { ">": { dir: "parentNode", first: !0 }, " ": { dir: "parentNode" }, "+": { dir: "previousSibling", first: !0 }, "~": { dir: "previousSibling" } }, preFilter: { ATTR: function(a) { - return a[1] = a[1].replace(_, aa), a[3] = (a[3] || a[4] || a[5] || "").replace(_, aa), "~=" === a[2] && (a[3] = " " + a[3] + " "), a.slice(0, 4) }, CHILD: function(a) { - return a[1] = a[1].toLowerCase(), "nth" === a[1].slice(0, 3) ? (a[3] || ga.error(a[0]), a[4] = +(a[4] ? a[5] + (a[6] || 1) : 2 * ("even" === a[3] || "odd" === a[3])), a[5] = +(a[7] + a[8] || "odd" === a[3])) : a[3] && ga.error(a[0]), a }, PSEUDO: function(a) { - var b, c = !a[6] && a[2]; - return V.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && T.test(c) && (b = g(c, !0)) && (b = c.indexOf(")", c.length - b) - c.length) && (a[0] = a[0].slice(0, b), a[2] = c.slice(0, b)), a.slice(0, 3)) } }, filter: { TAG: function(a) { - var b = a.replace(_, aa).toLowerCase(); - return "*" === a ? function() { - return !0 } : function(a) { - return a.nodeName && a.nodeName.toLowerCase() === b } }, CLASS: function(a) { - var b = y[a + " "]; - return b || (b = new RegExp("(^|" + K + ")" + a + "(" + K + "|$)")) && y(a, function(a) { - return b.test("string" == typeof a.className && a.className || "undefined" != typeof a.getAttribute && a.getAttribute("class") || "") }) }, ATTR: function(a, b, c) { - return function(d) { - var e = ga.attr(d, a); - return null == e ? "!=" === b : !b || (e += "", "=" === b ? e === c : "!=" === b ? e !== c : "^=" === b ? c && 0 === e.indexOf(c) : "*=" === b ? c && e.indexOf(c) > -1 : "$=" === b ? c && e.slice(-c.length) === c : "~=" === b ? (" " + e.replace(O, " ") + " ").indexOf(c) > -1 : "|=" === b && (e === c || e.slice(0, c.length + 1) === c + "-")) } }, CHILD: function(a, b, c, d, e) { - var f = "nth" !== a.slice(0, 3), - g = "last" !== a.slice(-4), - h = "of-type" === b; - return 1 === d && 0 === e ? function(a) { - return !!a.parentNode } : function(b, c, i) { - var j, k, l, m, n, o, p = f !== g ? "nextSibling" : "previousSibling", - q = b.parentNode, - r = h && b.nodeName.toLowerCase(), - s = !i && !h, - t = !1; - if (q) { - if (f) { - while (p) { m = b; - while (m = m[p]) - if (h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) return !1; - o = p = "only" === a && !o && "nextSibling" } - return !0 } - if (o = [g ? q.firstChild : q.lastChild], g && s) { m = q, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n && j[2], m = n && q.childNodes[n]; - while (m = ++n && m && m[p] || (t = n = 0) || o.pop()) - if (1 === m.nodeType && ++t && m === b) { k[a] = [w, n, t]; - break } } else if (s && (m = b, l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), j = k[a] || [], n = j[0] === w && j[1], t = n), t === !1) - while (m = ++n && m && m[p] || (t = n = 0) || o.pop()) - if ((h ? m.nodeName.toLowerCase() === r : 1 === m.nodeType) && ++t && (s && (l = m[u] || (m[u] = {}), k = l[m.uniqueID] || (l[m.uniqueID] = {}), k[a] = [w, t]), m === b)) break; - return t -= e, t === d || t % d === 0 && t / d >= 0 } } }, PSEUDO: function(a, b) { - var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || ga.error("unsupported pseudo: " + a); - return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? ia(function(a, c) { - var d, f = e(a, b), - g = f.length; - while (g--) d = I(a, f[g]), a[d] = !(c[d] = f[g]) }) : function(a) { - return e(a, 0, c) }) : e } }, pseudos: { not: ia(function(a) { - var b = [], - c = [], - d = h(a.replace(P, "$1")); - return d[u] ? ia(function(a, b, c, e) { - var f, g = d(a, null, e, []), - h = a.length; - while (h--)(f = g[h]) && (a[h] = !(b[h] = f)) }) : function(a, e, f) { - return b[0] = a, d(b, null, f, c), b[0] = null, !c.pop() } }), has: ia(function(a) { - return function(b) { - return ga(a, b).length > 0 } }), contains: ia(function(a) { - return a = a.replace(_, aa), - function(b) { - return (b.textContent || b.innerText || e(b)).indexOf(a) > -1 } }), lang: ia(function(a) { - return U.test(a || "") || ga.error("unsupported lang: " + a), a = a.replace(_, aa).toLowerCase(), - function(b) { - var c; - do - if (c = p ? b.lang : b.getAttribute("xml:lang") || b.getAttribute("lang")) return c = c.toLowerCase(), c === a || 0 === c.indexOf(a + "-"); - while ((b = b.parentNode) && 1 === b.nodeType); - return !1 } }), target: function(b) { - var c = a.location && a.location.hash; - return c && c.slice(1) === b.id }, root: function(a) { - return a === o }, focus: function(a) { - return a === n.activeElement && (!n.hasFocus || n.hasFocus()) && !!(a.type || a.href || ~a.tabIndex) }, enabled: oa(!1), disabled: oa(!0), checked: function(a) { - var b = a.nodeName.toLowerCase(); - return "input" === b && !!a.checked || "option" === b && !!a.selected }, selected: function(a) { - return a.parentNode && a.parentNode.selectedIndex, a.selected === !0 }, empty: function(a) { - for (a = a.firstChild; a; a = a.nextSibling) - if (a.nodeType < 6) return !1; - return !0 }, parent: function(a) { - return !d.pseudos.empty(a) }, header: function(a) { - return X.test(a.nodeName) }, input: function(a) { - return W.test(a.nodeName) }, button: function(a) { - var b = a.nodeName.toLowerCase(); - return "input" === b && "button" === a.type || "button" === b }, text: function(a) { - var b; - return "input" === a.nodeName.toLowerCase() && "text" === a.type && (null == (b = a.getAttribute("type")) || "text" === b.toLowerCase()) }, first: pa(function() { - return [0] }), last: pa(function(a, b) { - return [b - 1] }), eq: pa(function(a, b, c) { - return [c < 0 ? c + b : c] }), even: pa(function(a, b) { - for (var c = 0; c < b; c += 2) a.push(c); - return a }), odd: pa(function(a, b) { - for (var c = 1; c < b; c += 2) a.push(c); - return a }), lt: pa(function(a, b, c) { - for (var d = c < 0 ? c + b : c; --d >= 0;) a.push(d); - return a }), gt: pa(function(a, b, c) { - for (var d = c < 0 ? c + b : c; ++d < b;) a.push(d); - return a }) } }, d.pseudos.nth = d.pseudos.eq; - for (b in { radio: !0, checkbox: !0, file: !0, password: !0, image: !0 }) d.pseudos[b] = ma(b); - for (b in { submit: !0, reset: !0 }) d.pseudos[b] = na(b); - - function ra() {} - ra.prototype = d.filters = d.pseudos, d.setFilters = new ra, g = ga.tokenize = function(a, b) { - var c, e, f, g, h, i, j, k = z[a + " "]; - if (k) return b ? 0 : k.slice(0); - h = a, i = [], j = d.preFilter; - while (h) { c && !(e = Q.exec(h)) || (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = R.exec(h)) && (c = e.shift(), f.push({ value: c, type: e[0].replace(P, " ") }), h = h.slice(c.length)); - for (g in d.filter) !(e = V[g].exec(h)) || j[g] && !(e = j[g](e)) || (c = e.shift(), f.push({ value: c, type: g, matches: e }), h = h.slice(c.length)); - if (!c) break } - return b ? h.length : h ? ga.error(a) : z(a, i).slice(0) }; - - function sa(a) { - for (var b = 0, c = a.length, d = ""; b < c; b++) d += a[b].value; - return d } - - function ta(a, b, c) { - var d = b.dir, - e = b.next, - f = e || d, - g = c && "parentNode" === f, - h = x++; - return b.first ? function(b, c, e) { - while (b = b[d]) - if (1 === b.nodeType || g) return a(b, c, e) } : function(b, c, i) { - var j, k, l, m = [w, h]; - if (i) { - while (b = b[d]) - if ((1 === b.nodeType || g) && a(b, c, i)) return !0 } else - while (b = b[d]) - if (1 === b.nodeType || g) - if (l = b[u] || (b[u] = {}), k = l[b.uniqueID] || (l[b.uniqueID] = {}), e && e === b.nodeName.toLowerCase()) b = b[d] || b; - else { - if ((j = k[f]) && j[0] === w && j[1] === h) return m[2] = j[2]; - if (k[f] = m, m[2] = a(b, c, i)) return !0 } } } - - function ua(a) { - return a.length > 1 ? function(b, c, d) { - var e = a.length; - while (e--) - if (!a[e](b, c, d)) return !1; - return !0 } : a[0] } - - function va(a, b, c) { - for (var d = 0, e = b.length; d < e; d++) ga(a, b[d], c); - return c } - - function wa(a, b, c, d, e) { - for (var f, g = [], h = 0, i = a.length, j = null != b; h < i; h++)(f = a[h]) && (c && !c(f, d, e) || (g.push(f), j && b.push(h))); - return g } - - function xa(a, b, c, d, e, f) { - return d && !d[u] && (d = xa(d)), e && !e[u] && (e = xa(e, f)), ia(function(f, g, h, i) { - var j, k, l, m = [], - n = [], - o = g.length, - p = f || va(b || "*", h.nodeType ? [h] : h, []), - q = !a || !f && b ? p : wa(p, m, a, h, i), - r = c ? e || (f ? a : o || d) ? [] : g : q; - if (c && c(q, r, h, i), d) { j = wa(r, n), d(j, [], h, i), k = j.length; - while (k--)(l = j[k]) && (r[n[k]] = !(q[n[k]] = l)) } - if (f) { - if (e || a) { - if (e) { j = [], k = r.length; - while (k--)(l = r[k]) && j.push(q[k] = l); - e(null, r = [], j, i) } - k = r.length; - while (k--)(l = r[k]) && (j = e ? I(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l)) } } else r = wa(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : G.apply(g, r) }) } - - function ya(a) { - for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = ta(function(a) { - return a === b }, h, !0), l = ta(function(a) { - return I(b, a) > -1 }, h, !0), m = [function(a, c, d) { - var e = !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d)); - return b = null, e }]; i < f; i++) - if (c = d.relative[a[i].type]) m = [ta(ua(m), c)]; - else { - if (c = d.filter[a[i].type].apply(null, a[i].matches), c[u]) { - for (e = ++i; e < f; e++) - if (d.relative[a[e].type]) break; - return xa(i > 1 && ua(m), i > 1 && sa(a.slice(0, i - 1).concat({ value: " " === a[i - 2].type ? "*" : "" })).replace(P, "$1"), c, i < e && ya(a.slice(i, e)), e < f && ya(a = a.slice(e)), e < f && sa(a)) } - m.push(c) } - return ua(m) } - - function za(a, b) { - var c = b.length > 0, - e = a.length > 0, - f = function(f, g, h, i, k) { - var l, o, q, r = 0, - s = "0", - t = f && [], - u = [], - v = j, - x = f || e && d.find.TAG("*", k), - y = w += null == v ? 1 : Math.random() || .1, - z = x.length; - for (k && (j = g === n || g || k); s !== z && null != (l = x[s]); s++) { - if (e && l) { o = 0, g || l.ownerDocument === n || (m(l), h = !p); - while (q = a[o++]) - if (q(l, g || n, h)) { i.push(l); - break } - k && (w = y) } - c && ((l = !q && l) && r--, f && t.push(l)) } - if (r += s, c && s !== r) { o = 0; - while (q = b[o++]) q(t, u, g, h); - if (f) { - if (r > 0) - while (s--) t[s] || u[s] || (u[s] = E.call(i)); - u = wa(u) } - G.apply(i, u), k && !f && u.length > 0 && r + b.length > 1 && ga.uniqueSort(i) } - return k && (w = y, j = v), t }; - return c ? ia(f) : f } - return h = ga.compile = function(a, b) { - var c, d = [], - e = [], - f = A[a + " "]; - if (!f) { b || (b = g(a)), c = b.length; - while (c--) f = ya(b[c]), f[u] ? d.push(f) : e.push(f); - f = A(a, za(e, d)), f.selector = a } - return f }, i = ga.select = function(a, b, e, f) { - var i, j, k, l, m, n = "function" == typeof a && a, - o = !f && g(a = n.selector || a); - if (e = e || [], 1 === o.length) { - if (j = o[0] = o[0].slice(0), j.length > 2 && "ID" === (k = j[0]).type && c.getById && 9 === b.nodeType && p && d.relative[j[1].type]) { - if (b = (d.find.ID(k.matches[0].replace(_, aa), b) || [])[0], !b) return e; - n && (b = b.parentNode), a = a.slice(j.shift().value.length) } - i = V.needsContext.test(a) ? 0 : j.length; - while (i--) { - if (k = j[i], d.relative[l = k.type]) break; - if ((m = d.find[l]) && (f = m(k.matches[0].replace(_, aa), $.test(j[0].type) && qa(b.parentNode) || b))) { - if (j.splice(i, 1), a = f.length && sa(j), !a) return G.apply(e, f), e; - break } } } - return (n || h(a, o))(f, b, !p, e, !b || $.test(a) && qa(b.parentNode) || b), e }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ja(function(a) { - return 1 & a.compareDocumentPosition(n.createElement("fieldset")) }), ja(function(a) { - return a.innerHTML = "", "#" === a.firstChild.getAttribute("href") }) || ka("type|href|height|width", function(a, b, c) { - if (!c) return a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2) }), c.attributes && ja(function(a) { - return a.innerHTML = "", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value") }) || ka("value", function(a, b, c) { - if (!c && "input" === a.nodeName.toLowerCase()) return a.defaultValue }), ja(function(a) { - return null == a.getAttribute("disabled") }) || ka(J, function(a, b, c) { - var d; - if (!c) return a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null }), ga }(a); - r.find = x, r.expr = x.selectors, r.expr[":"] = r.expr.pseudos, r.uniqueSort = r.unique = x.uniqueSort, r.text = x.getText, r.isXMLDoc = x.isXML, r.contains = x.contains, r.escapeSelector = x.escape; - var y = function(a, b, c) { - var d = [], - e = void 0 !== c; - while ((a = a[b]) && 9 !== a.nodeType) - if (1 === a.nodeType) { - if (e && r(a).is(c)) break; - d.push(a) } - return d }, - z = function(a, b) { - for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a); - return c }, - A = r.expr.match.needsContext, - B = /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i, - C = /^.[^:#\[\.,]*$/; - - function D(a, b, c) { - if (r.isFunction(b)) return r.grep(a, function(a, d) { - return !!b.call(a, d, a) !== c }); - if (b.nodeType) return r.grep(a, function(a) { - return a === b !== c }); - if ("string" == typeof b) { - if (C.test(b)) return r.filter(b, a, c); - b = r.filter(b, a) } - return r.grep(a, function(a) { - return i.call(b, a) > -1 !== c && 1 === a.nodeType }) } - r.filter = function(a, b, c) { - var d = b[0]; - return c && (a = ":not(" + a + ")"), 1 === b.length && 1 === d.nodeType ? r.find.matchesSelector(d, a) ? [d] : [] : r.find.matches(a, r.grep(b, function(a) { - return 1 === a.nodeType })) }, r.fn.extend({ find: function(a) { - var b, c, d = this.length, - e = this; - if ("string" != typeof a) return this.pushStack(r(a).filter(function() { - for (b = 0; b < d; b++) - if (r.contains(e[b], this)) return !0 })); - for (c = this.pushStack([]), b = 0; b < d; b++) r.find(a, e[b], c); - return d > 1 ? r.uniqueSort(c) : c }, filter: function(a) { - return this.pushStack(D(this, a || [], !1)) }, not: function(a) { - return this.pushStack(D(this, a || [], !0)) }, is: function(a) { - return !!D(this, "string" == typeof a && A.test(a) ? r(a) : a || [], !1).length } }); - var E, F = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, - G = r.fn.init = function(a, b, c) { - var e, f; - if (!a) return this; - if (c = c || E, "string" == typeof a) { - if (e = "<" === a[0] && ">" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : F.exec(a), !e || !e[1] && b) return !b || b.jquery ? (b || c).find(a) : this.constructor(b).find(a); - if (e[1]) { - if (b = b instanceof r ? b[0] : b, r.merge(this, r.parseHTML(e[1], b && b.nodeType ? b.ownerDocument || b : d, !0)), B.test(e[1]) && r.isPlainObject(b)) - for (e in b) r.isFunction(this[e]) ? this[e](b[e]) : this.attr(e, b[e]); - return this } - return f = d.getElementById(e[2]), f && (this[0] = f, this.length = 1), this } - return a.nodeType ? (this[0] = a, this.length = 1, this) : r.isFunction(a) ? void 0 !== c.ready ? c.ready(a) : a(r) : r.makeArray(a, this) }; - G.prototype = r.fn, E = r(d); - var H = /^(?:parents|prev(?:Until|All))/, - I = { children: !0, contents: !0, next: !0, prev: !0 }; - r.fn.extend({ has: function(a) { - var b = r(a, this), - c = b.length; - return this.filter(function() { - for (var a = 0; a < c; a++) - if (r.contains(this, b[a])) return !0 }) }, closest: function(a, b) { - var c, d = 0, - e = this.length, - f = [], - g = "string" != typeof a && r(a); - if (!A.test(a)) - for (; d < e; d++) - for (c = this[d]; c && c !== b; c = c.parentNode) - if (c.nodeType < 11 && (g ? g.index(c) > -1 : 1 === c.nodeType && r.find.matchesSelector(c, a))) { f.push(c); - break } - return this.pushStack(f.length > 1 ? r.uniqueSort(f) : f) }, index: function(a) { - return a ? "string" == typeof a ? i.call(r(a), this[0]) : i.call(this, a.jquery ? a[0] : a) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 }, add: function(a, b) { - return this.pushStack(r.uniqueSort(r.merge(this.get(), r(a, b)))) }, addBack: function(a) { - return this.add(null == a ? this.prevObject : this.prevObject.filter(a)) } }); - - function J(a, b) { - while ((a = a[b]) && 1 !== a.nodeType); - return a } - r.each({ parent: function(a) { - var b = a.parentNode; - return b && 11 !== b.nodeType ? b : null }, parents: function(a) { - return y(a, "parentNode") }, parentsUntil: function(a, b, c) { - return y(a, "parentNode", c) }, next: function(a) { - return J(a, "nextSibling") }, prev: function(a) { - return J(a, "previousSibling") }, nextAll: function(a) { - return y(a, "nextSibling") }, prevAll: function(a) { - return y(a, "previousSibling") }, nextUntil: function(a, b, c) { - return y(a, "nextSibling", c) }, prevUntil: function(a, b, c) { - return y(a, "previousSibling", c) }, siblings: function(a) { - return z((a.parentNode || {}).firstChild, a) }, children: function(a) { - return z(a.firstChild) }, contents: function(a) { - return a.contentDocument || r.merge([], a.childNodes) } }, function(a, b) { r.fn[a] = function(c, d) { - var e = r.map(this, b, c); - return "Until" !== a.slice(-5) && (d = c), d && "string" == typeof d && (e = r.filter(d, e)), this.length > 1 && (I[a] || r.uniqueSort(e), H.test(a) && e.reverse()), this.pushStack(e) } }); - var K = /\S+/g; - - function L(a) { - var b = {}; - return r.each(a.match(K) || [], function(a, c) { b[c] = !0 }), b } - r.Callbacks = function(a) { a = "string" == typeof a ? L(a) : r.extend({}, a); - var b, c, d, e, f = [], - g = [], - h = -1, - i = function() { - for (e = a.once, d = b = !0; g.length; h = -1) { c = g.shift(); - while (++h < f.length) f[h].apply(c[0], c[1]) === !1 && a.stopOnFalse && (h = f.length, c = !1) } - a.memory || (c = !1), b = !1, e && (f = c ? [] : "") }, - j = { add: function() { - return f && (c && !b && (h = f.length - 1, g.push(c)), function d(b) { r.each(b, function(b, c) { r.isFunction(c) ? a.unique && j.has(c) || f.push(c) : c && c.length && "string" !== r.type(c) && d(c) }) }(arguments), c && !b && i()), this }, remove: function() { - return r.each(arguments, function(a, b) { - var c; - while ((c = r.inArray(b, f, c)) > -1) f.splice(c, 1), c <= h && h-- }), this }, has: function(a) { - return a ? r.inArray(a, f) > -1 : f.length > 0 }, empty: function() { - return f && (f = []), this }, disable: function() { - return e = g = [], f = c = "", this }, disabled: function() { - return !f }, lock: function() { - return e = g = [], c || b || (f = c = ""), this }, locked: function() { - return !!e }, fireWith: function(a, c) { - return e || (c = c || [], c = [a, c.slice ? c.slice() : c], g.push(c), b || i()), this }, fire: function() { - return j.fireWith(this, arguments), this }, fired: function() { - return !!d } }; - return j }; - - function M(a) { - return a } - - function N(a) { - throw a } - - function O(a, b, c) { - var d; - try { a && r.isFunction(d = a.promise) ? d.call(a).done(b).fail(c) : a && r.isFunction(d = a.then) ? d.call(a, b, c) : b.call(void 0, a) } catch (a) { c.call(void 0, a) } } - r.extend({ Deferred: function(b) { - var c = [ - ["notify", "progress", r.Callbacks("memory"), r.Callbacks("memory"), 2], - ["resolve", "done", r.Callbacks("once memory"), r.Callbacks("once memory"), 0, "resolved"], - ["reject", "fail", r.Callbacks("once memory"), r.Callbacks("once memory"), 1, "rejected"] - ], - d = "pending", - e = { state: function() { - return d }, always: function() { - return f.done(arguments).fail(arguments), this }, "catch": function(a) { - return e.then(null, a) }, pipe: function() { - var a = arguments; - return r.Deferred(function(b) { r.each(c, function(c, d) { - var e = r.isFunction(a[d[4]]) && a[d[4]]; - f[d[1]](function() { - var a = e && e.apply(this, arguments); - a && r.isFunction(a.promise) ? a.promise().progress(b.notify).done(b.resolve).fail(b.reject) : b[d[0] + "With"](this, e ? [a] : arguments) }) }), a = null }).promise() }, then: function(b, d, e) { - var f = 0; - - function g(b, c, d, e) { - return function() { - var h = this, - i = arguments, - j = function() { - var a, j; - if (!(b < f)) { - if (a = d.apply(h, i), a === c.promise()) throw new TypeError("Thenable self-resolution"); - j = a && ("object" == typeof a || "function" == typeof a) && a.then, r.isFunction(j) ? e ? j.call(a, g(f, c, M, e), g(f, c, N, e)) : (f++, j.call(a, g(f, c, M, e), g(f, c, N, e), g(f, c, M, c.notifyWith))) : (d !== M && (h = void 0, i = [a]), (e || c.resolveWith)(h, i)) } }, - k = e ? j : function() { - try { j() } catch (a) { r.Deferred.exceptionHook && r.Deferred.exceptionHook(a, k.stackTrace), b + 1 >= f && (d !== N && (h = void 0, i = [a]), c.rejectWith(h, i)) } }; - b ? k() : (r.Deferred.getStackHook && (k.stackTrace = r.Deferred.getStackHook()), a.setTimeout(k)) } } - return r.Deferred(function(a) { c[0][3].add(g(0, a, r.isFunction(e) ? e : M, a.notifyWith)), c[1][3].add(g(0, a, r.isFunction(b) ? b : M)), c[2][3].add(g(0, a, r.isFunction(d) ? d : N)) }).promise() }, promise: function(a) { - return null != a ? r.extend(a, e) : e } }, - f = {}; - return r.each(c, function(a, b) { - var g = b[2], - h = b[5]; - e[b[1]] = g.add, h && g.add(function() { d = h }, c[3 - a][2].disable, c[0][2].lock), g.add(b[3].fire), f[b[0]] = function() { - return f[b[0] + "With"](this === f ? void 0 : this, arguments), this }, f[b[0] + "With"] = g.fireWith }), e.promise(f), b && b.call(f, f), f }, when: function(a) { - var b = arguments.length, - c = b, - d = Array(c), - e = f.call(arguments), - g = r.Deferred(), - h = function(a) { - return function(c) { d[a] = this, e[a] = arguments.length > 1 ? f.call(arguments) : c, --b || g.resolveWith(d, e) } }; - if (b <= 1 && (O(a, g.done(h(c)).resolve, g.reject), "pending" === g.state() || r.isFunction(e[c] && e[c].then))) return g.then(); - while (c--) O(e[c], h(c), g.reject); - return g.promise() } }); - var P = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; - r.Deferred.exceptionHook = function(b, c) { a.console && a.console.warn && b && P.test(b.name) && a.console.warn("jQuery.Deferred exception: " + b.message, b.stack, c) }, r.readyException = function(b) { a.setTimeout(function() { - throw b }) }; - var Q = r.Deferred(); - r.fn.ready = function(a) { - return Q.then(a)["catch"](function(a) { r.readyException(a) }), this }, r.extend({ isReady: !1, readyWait: 1, holdReady: function(a) { a ? r.readyWait++ : r.ready(!0) }, ready: function(a) { - (a === !0 ? --r.readyWait : r.isReady) || (r.isReady = !0, a !== !0 && --r.readyWait > 0 || Q.resolveWith(d, [r])) } }), r.ready.then = Q.then; - - function R() { d.removeEventListener("DOMContentLoaded", R), a.removeEventListener("load", R), r.ready() } - "complete" === d.readyState || "loading" !== d.readyState && !d.documentElement.doScroll ? a.setTimeout(r.ready) : (d.addEventListener("DOMContentLoaded", R), a.addEventListener("load", R)); - var S = function(a, b, c, d, e, f, g) { - var h = 0, - i = a.length, - j = null == c; - if ("object" === r.type(c)) { e = !0; - for (h in c) S(a, b, h, c[h], !0, f, g) } else if (void 0 !== d && (e = !0, - r.isFunction(d) || (g = !0), j && (g ? (b.call(a, d), b = null) : (j = b, b = function(a, b, c) { - return j.call(r(a), c) })), b)) - for (; h < i; h++) b(a[h], c, g ? d : d.call(a[h], h, b(a[h], c))); - return e ? a : j ? b.call(a) : i ? b(a[0], c) : f - }, - T = function(a) { - return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType }; - - function U() { this.expando = r.expando + U.uid++ } - U.uid = 1, U.prototype = { cache: function(a) { - var b = a[this.expando]; - return b || (b = {}, T(a) && (a.nodeType ? a[this.expando] = b : Object.defineProperty(a, this.expando, { value: b, configurable: !0 }))), b }, set: function(a, b, c) { - var d, e = this.cache(a); - if ("string" == typeof b) e[r.camelCase(b)] = c; - else - for (d in b) e[r.camelCase(d)] = b[d]; - return e }, get: function(a, b) { - return void 0 === b ? this.cache(a) : a[this.expando] && a[this.expando][r.camelCase(b)] }, access: function(a, b, c) { - return void 0 === b || b && "string" == typeof b && void 0 === c ? this.get(a, b) : (this.set(a, b, c), void 0 !== c ? c : b) }, remove: function(a, b) { - var c, d = a[this.expando]; - if (void 0 !== d) { - if (void 0 !== b) { r.isArray(b) ? b = b.map(r.camelCase) : (b = r.camelCase(b), b = b in d ? [b] : b.match(K) || []), c = b.length; - while (c--) delete d[b[c]] }(void 0 === b || r.isEmptyObject(d)) && (a.nodeType ? a[this.expando] = void 0 : delete a[this.expando]) } }, hasData: function(a) { - var b = a[this.expando]; - return void 0 !== b && !r.isEmptyObject(b) } }; - var V = new U, - W = new U, - X = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - Y = /[A-Z]/g; - - function Z(a, b, c) { - var d; - if (void 0 === c && 1 === a.nodeType) - if (d = "data-" + b.replace(Y, "-$&").toLowerCase(), c = a.getAttribute(d), "string" == typeof c) { - try { c = "true" === c || "false" !== c && ("null" === c ? null : +c + "" === c ? +c : X.test(c) ? JSON.parse(c) : c) } catch (e) {} - W.set(a, b, c) } else c = void 0; - return c } - r.extend({ hasData: function(a) { - return W.hasData(a) || V.hasData(a) }, data: function(a, b, c) { - return W.access(a, b, c) }, removeData: function(a, b) { W.remove(a, b) }, _data: function(a, b, c) { - return V.access(a, b, c) }, _removeData: function(a, b) { V.remove(a, b) } }), r.fn.extend({ data: function(a, b) { - var c, d, e, f = this[0], - g = f && f.attributes; - if (void 0 === a) { - if (this.length && (e = W.get(f), 1 === f.nodeType && !V.get(f, "hasDataAttrs"))) { c = g.length; - while (c--) g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = r.camelCase(d.slice(5)), Z(f, d, e[d]))); - V.set(f, "hasDataAttrs", !0) } - return e } - return "object" == typeof a ? this.each(function() { W.set(this, a) }) : S(this, function(b) { - var c; - if (f && void 0 === b) { - if (c = W.get(f, a), void 0 !== c) return c; - if (c = Z(f, a), void 0 !== c) return c } else this.each(function() { W.set(this, a, b) }) }, null, b, arguments.length > 1, null, !0) }, removeData: function(a) { - return this.each(function() { W.remove(this, a) }) } }), r.extend({ queue: function(a, b, c) { - var d; - if (a) return b = (b || "fx") + "queue", d = V.get(a, b), c && (!d || r.isArray(c) ? d = V.access(a, b, r.makeArray(c)) : d.push(c)), d || [] }, dequeue: function(a, b) { b = b || "fx"; - var c = r.queue(a, b), - d = c.length, - e = c.shift(), - f = r._queueHooks(a, b), - g = function() { r.dequeue(a, b) }; "inprogress" === e && (e = c.shift(), d--), e && ("fx" === b && c.unshift("inprogress"), delete f.stop, e.call(a, g, f)), !d && f && f.empty.fire() }, _queueHooks: function(a, b) { - var c = b + "queueHooks"; - return V.get(a, c) || V.access(a, c, { empty: r.Callbacks("once memory").add(function() { V.remove(a, [b + "queue", c]) }) }) } }), r.fn.extend({ queue: function(a, b) { - var c = 2; - return "string" != typeof a && (b = a, a = "fx", c--), arguments.length < c ? r.queue(this[0], a) : void 0 === b ? this : this.each(function() { - var c = r.queue(this, a, b); - r._queueHooks(this, a), "fx" === a && "inprogress" !== c[0] && r.dequeue(this, a) }) }, dequeue: function(a) { - return this.each(function() { r.dequeue(this, a) }) }, clearQueue: function(a) { - return this.queue(a || "fx", []) }, promise: function(a, b) { - var c, d = 1, - e = r.Deferred(), - f = this, - g = this.length, - h = function() {--d || e.resolveWith(f, [f]) }; "string" != typeof a && (b = a, a = void 0), a = a || "fx"; - while (g--) c = V.get(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h)); - return h(), e.promise(b) } }); - var $ = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, - _ = new RegExp("^(?:([+-])=|)(" + $ + ")([a-z%]*)$", "i"), - aa = ["Top", "Right", "Bottom", "Left"], - ba = function(a, b) { - return a = b || a, "none" === a.style.display || "" === a.style.display && r.contains(a.ownerDocument, a) && "none" === r.css(a, "display") }, - ca = function(a, b, c, d) { - var e, f, g = {}; - for (f in b) g[f] = a.style[f], a.style[f] = b[f]; - e = c.apply(a, d || []); - for (f in b) a.style[f] = g[f]; - return e }; - - function da(a, b, c, d) { - var e, f = 1, - g = 20, - h = d ? function() { - return d.cur() } : function() { - return r.css(a, b, "") }, - i = h(), - j = c && c[3] || (r.cssNumber[b] ? "" : "px"), - k = (r.cssNumber[b] || "px" !== j && +i) && _.exec(r.css(a, b)); - if (k && k[3] !== j) { j = j || k[3], c = c || [], k = +i || 1; - do f = f || ".5", k /= f, r.style(a, b, k + j); while (f !== (f = h() / i) && 1 !== f && --g) } - return c && (k = +k || +i || 0, e = c[1] ? k + (c[1] + 1) * c[2] : +c[2], d && (d.unit = j, d.start = k, d.end = e)), e } - var ea = {}; - - function fa(a) { - var b, c = a.ownerDocument, - d = a.nodeName, - e = ea[d]; - return e ? e : (b = c.body.appendChild(c.createElement(d)), e = r.css(b, "display"), b.parentNode.removeChild(b), "none" === e && (e = "block"), ea[d] = e, e) } - - function ga(a, b) { - for (var c, d, e = [], f = 0, g = a.length; f < g; f++) d = a[f], d.style && (c = d.style.display, b ? ("none" === c && (e[f] = V.get(d, "display") || null, e[f] || (d.style.display = "")), "" === d.style.display && ba(d) && (e[f] = fa(d))) : "none" !== c && (e[f] = "none", V.set(d, "display", c))); - for (f = 0; f < g; f++) null != e[f] && (a[f].style.display = e[f]); - return a } - r.fn.extend({ show: function() { - return ga(this, !0) }, hide: function() { - return ga(this) }, toggle: function(a) { - return "boolean" == typeof a ? a ? this.show() : this.hide() : this.each(function() { ba(this) ? r(this).show() : r(this).hide() }) } }); - var ha = /^(?:checkbox|radio)$/i, - ia = /<([a-z][^\/\0>\x20\t\r\n\f]+)/i, - ja = /^$|\/(?:java|ecma)script/i, - ka = { option: [1, ""], thead: [1, "", "
"], col: [2, "", "
"], tr: [2, "", "
"], td: [3, "", "
"], _default: [0, "", ""] }; - ka.optgroup = ka.option, ka.tbody = ka.tfoot = ka.colgroup = ka.caption = ka.thead, ka.th = ka.td; - - function la(a, b) { - var c = "undefined" != typeof a.getElementsByTagName ? a.getElementsByTagName(b || "*") : "undefined" != typeof a.querySelectorAll ? a.querySelectorAll(b || "*") : []; - return void 0 === b || b && r.nodeName(a, b) ? r.merge([a], c) : c } - - function ma(a, b) { - for (var c = 0, d = a.length; c < d; c++) V.set(a[c], "globalEval", !b || V.get(b[c], "globalEval")) } - var na = /<|&#?\w+;/; - - function oa(a, b, c, d, e) { - for (var f, g, h, i, j, k, l = b.createDocumentFragment(), m = [], n = 0, o = a.length; n < o; n++) - if (f = a[n], f || 0 === f) - if ("object" === r.type(f)) r.merge(m, f.nodeType ? [f] : f); - else if (na.test(f)) { g = g || l.appendChild(b.createElement("div")), h = (ia.exec(f) || ["", ""])[1].toLowerCase(), i = ka[h] || ka._default, g.innerHTML = i[1] + r.htmlPrefilter(f) + i[2], k = i[0]; - while (k--) g = g.lastChild; - r.merge(m, g.childNodes), g = l.firstChild, g.textContent = "" } else m.push(b.createTextNode(f)); - l.textContent = "", n = 0; - while (f = m[n++]) - if (d && r.inArray(f, d) > -1) e && e.push(f); - else if (j = r.contains(f.ownerDocument, f), g = la(l.appendChild(f), "script"), j && ma(g), c) { k = 0; - while (f = g[k++]) ja.test(f.type || "") && c.push(f) } - return l }! function() { - var a = d.createDocumentFragment(), - b = a.appendChild(d.createElement("div")), - c = d.createElement("input"); - c.setAttribute("type", "radio"), c.setAttribute("checked", "checked"), c.setAttribute("name", "t"), b.appendChild(c), o.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = "", o.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue }(); - var pa = d.documentElement, - qa = /^key/, - ra = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, - sa = /^([^.]*)(?:\.(.+)|)/; - - function ta() { - return !0 } - - function ua() { - return !1 } - - function va() { - try { - return d.activeElement } catch (a) {} } - - function wa(a, b, c, d, e, f) { - var g, h; - if ("object" == typeof b) { "string" != typeof c && (d = d || c, c = void 0); - for (h in b) wa(a, h, c, d, b[h], f); - return a } - if (null == d && null == e ? (e = c, d = c = void 0) : null == e && ("string" == typeof c ? (e = d, d = void 0) : (e = d, d = c, c = void 0)), e === !1) e = ua; - else if (!e) return a; - return 1 === f && (g = e, e = function(a) { - return r().off(a), g.apply(this, arguments) }, e.guid = g.guid || (g.guid = r.guid++)), a.each(function() { r.event.add(this, b, e, d, c) }) } - r.event = { global: {}, add: function(a, b, c, d, e) { - var f, g, h, i, j, k, l, m, n, o, p, q = V.get(a); - if (q) { c.handler && (f = c, c = f.handler, e = f.selector), e && r.find.matchesSelector(pa, e), c.guid || (c.guid = r.guid++), (i = q.events) || (i = q.events = {}), (g = q.handle) || (g = q.handle = function(b) { - return "undefined" != typeof r && r.event.triggered !== b.type ? r.event.dispatch.apply(a, arguments) : void 0 }), b = (b || "").match(K) || [""], j = b.length; - while (j--) h = sa.exec(b[j]) || [], n = p = h[1], o = (h[2] || "").split(".").sort(), n && (l = r.event.special[n] || {}, n = (e ? l.delegateType : l.bindType) || n, l = r.event.special[n] || {}, k = r.extend({ type: n, origType: p, data: d, handler: c, guid: c.guid, selector: e, needsContext: e && r.expr.match.needsContext.test(e), namespace: o.join(".") }, f), (m = i[n]) || (m = i[n] = [], m.delegateCount = 0, l.setup && l.setup.call(a, d, o, g) !== !1 || a.addEventListener && a.addEventListener(n, g)), l.add && (l.add.call(a, k), k.handler.guid || (k.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, k) : m.push(k), r.event.global[n] = !0) } }, remove: function(a, b, c, d, e) { - var f, g, h, i, j, k, l, m, n, o, p, q = V.hasData(a) && V.get(a); - if (q && (i = q.events)) { b = (b || "").match(K) || [""], j = b.length; - while (j--) - if (h = sa.exec(b[j]) || [], n = p = h[1], o = (h[2] || "").split(".").sort(), n) { l = r.event.special[n] || {}, n = (d ? l.delegateType : l.bindType) || n, m = i[n] || [], h = h[2] && new RegExp("(^|\\.)" + o.join("\\.(?:.*\\.|)") + "(\\.|$)"), g = f = m.length; - while (f--) k = m[f], !e && p !== k.origType || c && c.guid !== k.guid || h && !h.test(k.namespace) || d && d !== k.selector && ("**" !== d || !k.selector) || (m.splice(f, 1), k.selector && m.delegateCount--, l.remove && l.remove.call(a, k)); - g && !m.length && (l.teardown && l.teardown.call(a, o, q.handle) !== !1 || r.removeEvent(a, n, q.handle), delete i[n]) } else - for (n in i) r.event.remove(a, n + b[j], c, d, !0); - r.isEmptyObject(i) && V.remove(a, "handle events") } }, dispatch: function(a) { - var b = r.event.fix(a), - c, d, e, f, g, h, i = new Array(arguments.length), - j = (V.get(this, "events") || {})[b.type] || [], - k = r.event.special[b.type] || {}; - for (i[0] = b, c = 1; c < arguments.length; c++) i[c] = arguments[c]; - if (b.delegateTarget = this, !k.preDispatch || k.preDispatch.call(this, b) !== !1) { h = r.event.handlers.call(this, b, j), c = 0; - while ((f = h[c++]) && !b.isPropagationStopped()) { b.currentTarget = f.elem, d = 0; - while ((g = f.handlers[d++]) && !b.isImmediatePropagationStopped()) b.rnamespace && !b.rnamespace.test(g.namespace) || (b.handleObj = g, b.data = g.data, e = ((r.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== e && (b.result = e) === !1 && (b.preventDefault(), b.stopPropagation())) } - return k.postDispatch && k.postDispatch.call(this, b), b.result } }, handlers: function(a, b) { - var c, d, e, f, g = [], - h = b.delegateCount, - i = a.target; - if (h && i.nodeType && ("click" !== a.type || isNaN(a.button) || a.button < 1)) - for (; i !== this; i = i.parentNode || this) - if (1 === i.nodeType && (i.disabled !== !0 || "click" !== a.type)) { - for (d = [], c = 0; c < h; c++) f = b[c], e = f.selector + " ", void 0 === d[e] && (d[e] = f.needsContext ? r(e, this).index(i) > -1 : r.find(e, this, null, [i]).length), d[e] && d.push(f); - d.length && g.push({ elem: i, handlers: d }) } - return h < b.length && g.push({ elem: this, handlers: b.slice(h) }), g }, addProp: function(a, b) { Object.defineProperty(r.Event.prototype, a, { enumerable: !0, configurable: !0, get: r.isFunction(b) ? function() { - if (this.originalEvent) return b(this.originalEvent) } : function() { - if (this.originalEvent) return this.originalEvent[a] }, set: function(b) { Object.defineProperty(this, a, { enumerable: !0, configurable: !0, writable: !0, value: b }) } }) }, fix: function(a) { - return a[r.expando] ? a : new r.Event(a) }, special: { load: { noBubble: !0 }, focus: { trigger: function() { - if (this !== va() && this.focus) return this.focus(), !1 }, delegateType: "focusin" }, blur: { trigger: function() { - if (this === va() && this.blur) return this.blur(), !1 }, delegateType: "focusout" }, click: { trigger: function() { - if ("checkbox" === this.type && this.click && r.nodeName(this, "input")) return this.click(), !1 }, _default: function(a) { - return r.nodeName(a.target, "a") } }, beforeunload: { postDispatch: function(a) { void 0 !== a.result && a.originalEvent && (a.originalEvent.returnValue = a.result) } } } }, r.removeEvent = function(a, b, c) { a.removeEventListener && a.removeEventListener(b, c) }, r.Event = function(a, b) { - return this instanceof r.Event ? (a && a.type ? (this.originalEvent = a, this.type = a.type, this.isDefaultPrevented = a.defaultPrevented || void 0 === a.defaultPrevented && a.returnValue === !1 ? ta : ua, this.target = a.target && 3 === a.target.nodeType ? a.target.parentNode : a.target, this.currentTarget = a.currentTarget, this.relatedTarget = a.relatedTarget) : this.type = a, b && r.extend(this, b), this.timeStamp = a && a.timeStamp || r.now(), void(this[r.expando] = !0)) : new r.Event(a, b) }, r.Event.prototype = { constructor: r.Event, isDefaultPrevented: ua, isPropagationStopped: ua, isImmediatePropagationStopped: ua, isSimulated: !1, preventDefault: function() { - var a = this.originalEvent; - this.isDefaultPrevented = ta, a && !this.isSimulated && a.preventDefault() }, stopPropagation: function() { - var a = this.originalEvent; - this.isPropagationStopped = ta, a && !this.isSimulated && a.stopPropagation() }, stopImmediatePropagation: function() { - var a = this.originalEvent; - this.isImmediatePropagationStopped = ta, a && !this.isSimulated && a.stopImmediatePropagation(), this.stopPropagation() } }, r.each({ altKey: !0, bubbles: !0, cancelable: !0, changedTouches: !0, ctrlKey: !0, detail: !0, eventPhase: !0, metaKey: !0, pageX: !0, pageY: !0, shiftKey: !0, view: !0, "char": !0, charCode: !0, key: !0, keyCode: !0, button: !0, buttons: !0, clientX: !0, clientY: !0, offsetX: !0, offsetY: !0, pointerId: !0, pointerType: !0, screenX: !0, screenY: !0, targetTouches: !0, toElement: !0, touches: !0, which: function(a) { - var b = a.button; - return null == a.which && qa.test(a.type) ? null != a.charCode ? a.charCode : a.keyCode : !a.which && void 0 !== b && ra.test(a.type) ? 1 & b ? 1 : 2 & b ? 3 : 4 & b ? 2 : 0 : a.which } }, r.event.addProp), r.each({ mouseenter: "mouseover", mouseleave: "mouseout", pointerenter: "pointerover", pointerleave: "pointerout" }, function(a, b) { r.event.special[a] = { delegateType: b, bindType: b, handle: function(a) { - var c, d = this, - e = a.relatedTarget, - f = a.handleObj; - return e && (e === d || r.contains(d, e)) || (a.type = f.origType, c = f.handler.apply(this, arguments), a.type = b), c } } }), r.fn.extend({ on: function(a, b, c, d) { - return wa(this, a, b, c, d) }, one: function(a, b, c, d) { - return wa(this, a, b, c, d, 1) }, off: function(a, b, c) { - var d, e; - if (a && a.preventDefault && a.handleObj) return d = a.handleObj, r(a.delegateTarget).off(d.namespace ? d.origType + "." + d.namespace : d.origType, d.selector, d.handler), this; - if ("object" == typeof a) { - for (e in a) this.off(e, b, a[e]); - return this } - return b !== !1 && "function" != typeof b || (c = b, b = void 0), c === !1 && (c = ua), this.each(function() { r.event.remove(this, a, c, b) }) } }); - var xa = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi, - ya = /\s*$/g; - - function Ca(a, b) { - return r.nodeName(a, "table") && r.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a : a } - - function Da(a) { - return a.type = (null !== a.getAttribute("type")) + "/" + a.type, a } - - function Ea(a) { - var b = Aa.exec(a.type); - return b ? a.type = b[1] : a.removeAttribute("type"), a } - - function Fa(a, b) { - var c, d, e, f, g, h, i, j; - if (1 === b.nodeType) { - if (V.hasData(a) && (f = V.access(a), g = V.set(b, f), j = f.events)) { delete g.handle, g.events = {}; - for (e in j) - for (c = 0, d = j[e].length; c < d; c++) r.event.add(b, e, j[e][c]) } - W.hasData(a) && (h = W.access(a), i = r.extend({}, h), W.set(b, i)) } } - - function Ga(a, b) { - var c = b.nodeName.toLowerCase(); "input" === c && ha.test(a.type) ? b.checked = a.checked : "input" !== c && "textarea" !== c || (b.defaultValue = a.defaultValue) } - - function Ha(a, b, c, d) { b = g.apply([], b); - var e, f, h, i, j, k, l = 0, - m = a.length, - n = m - 1, - q = b[0], - s = r.isFunction(q); - if (s || m > 1 && "string" == typeof q && !o.checkClone && za.test(q)) return a.each(function(e) { - var f = a.eq(e); - s && (b[0] = q.call(this, e, f.html())), Ha(f, b, c, d) }); - if (m && (e = oa(b, a[0].ownerDocument, !1, a, d), f = e.firstChild, 1 === e.childNodes.length && (e = f), f || d)) { - for (h = r.map(la(e, "script"), Da), i = h.length; l < m; l++) j = e, l !== n && (j = r.clone(j, !0, !0), i && r.merge(h, la(j, "script"))), c.call(a[l], j, l); - if (i) - for (k = h[h.length - 1].ownerDocument, r.map(h, Ea), l = 0; l < i; l++) j = h[l], ja.test(j.type || "") && !V.access(j, "globalEval") && r.contains(k, j) && (j.src ? r._evalUrl && r._evalUrl(j.src) : p(j.textContent.replace(Ba, ""), k)) } - return a } - - function Ia(a, b, c) { - for (var d, e = b ? r.filter(b, a) : a, f = 0; null != (d = e[f]); f++) c || 1 !== d.nodeType || r.cleanData(la(d)), d.parentNode && (c && r.contains(d.ownerDocument, d) && ma(la(d, "script")), d.parentNode.removeChild(d)); - return a } - r.extend({ htmlPrefilter: function(a) { - return a.replace(xa, "<$1>") }, clone: function(a, b, c) { - var d, e, f, g, h = a.cloneNode(!0), - i = r.contains(a.ownerDocument, a); - if (!(o.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || r.isXMLDoc(a))) - for (g = la(h), f = la(a), d = 0, e = f.length; d < e; d++) Ga(f[d], g[d]); - if (b) - if (c) - for (f = f || la(a), g = g || la(h), d = 0, e = f.length; d < e; d++) Fa(f[d], g[d]); - else Fa(a, h); - return g = la(h, "script"), g.length > 0 && ma(g, !i && la(a, "script")), h }, cleanData: function(a) { - for (var b, c, d, e = r.event.special, f = 0; void 0 !== (c = a[f]); f++) - if (T(c)) { - if (b = c[V.expando]) { - if (b.events) - for (d in b.events) e[d] ? r.event.remove(c, d) : r.removeEvent(c, d, b.handle); - c[V.expando] = void 0 } - c[W.expando] && (c[W.expando] = void 0) } } }), r.fn.extend({ detach: function(a) { - return Ia(this, a, !0) }, remove: function(a) { - return Ia(this, a) }, text: function(a) { - return S(this, function(a) { - return void 0 === a ? r.text(this) : this.empty().each(function() { 1 !== this.nodeType && 11 !== this.nodeType && 9 !== this.nodeType || (this.textContent = a) }) }, null, a, arguments.length) }, append: function() { - return Ha(this, arguments, function(a) { - if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { - var b = Ca(this, a); - b.appendChild(a) } }) }, prepend: function() { - return Ha(this, arguments, function(a) { - if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { - var b = Ca(this, a); - b.insertBefore(a, b.firstChild) } }) }, before: function() { - return Ha(this, arguments, function(a) { this.parentNode && this.parentNode.insertBefore(a, this) }) }, after: function() { - return Ha(this, arguments, function(a) { this.parentNode && this.parentNode.insertBefore(a, this.nextSibling) }) }, empty: function() { - for (var a, b = 0; null != (a = this[b]); b++) 1 === a.nodeType && (r.cleanData(la(a, !1)), a.textContent = ""); - return this }, clone: function(a, b) { - return a = null != a && a, b = null == b ? a : b, this.map(function() { - return r.clone(this, a, b) }) }, html: function(a) { - return S(this, function(a) { - var b = this[0] || {}, - c = 0, - d = this.length; - if (void 0 === a && 1 === b.nodeType) return b.innerHTML; - if ("string" == typeof a && !ya.test(a) && !ka[(ia.exec(a) || ["", ""])[1].toLowerCase()]) { a = r.htmlPrefilter(a); - try { - for (; c < d; c++) b = this[c] || {}, 1 === b.nodeType && (r.cleanData(la(b, !1)), b.innerHTML = a); - b = 0 } catch (e) {} } - b && this.empty().append(a) }, null, a, arguments.length) }, replaceWith: function() { - var a = []; - return Ha(this, arguments, function(b) { - var c = this.parentNode; - r.inArray(this, a) < 0 && (r.cleanData(la(this)), c && c.replaceChild(b, this)) }, a) } }), r.each({ appendTo: "append", prependTo: "prepend", insertBefore: "before", insertAfter: "after", replaceAll: "replaceWith" }, function(a, b) { r.fn[a] = function(a) { - for (var c, d = [], e = r(a), f = e.length - 1, g = 0; g <= f; g++) c = g === f ? this : this.clone(!0), r(e[g])[b](c), h.apply(d, c.get()); - return this.pushStack(d) } }); - var Ja = /^margin/, - Ka = new RegExp("^(" + $ + ")(?!px)[a-z%]+$", "i"), - La = function(b) { - var c = b.ownerDocument.defaultView; - return c && c.opener || (c = a), c.getComputedStyle(b) }; - ! function() { - function b() { - if (i) { i.style.cssText = "box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%", i.innerHTML = "", pa.appendChild(h); - var b = a.getComputedStyle(i); - c = "1%" !== b.top, g = "2px" === b.marginLeft, e = "4px" === b.width, i.style.marginRight = "50%", f = "4px" === b.marginRight, pa.removeChild(h), i = null } } - var c, e, f, g, h = d.createElement("div"), - i = d.createElement("div"); - i.style && (i.style.backgroundClip = "content-box", i.cloneNode(!0).style.backgroundClip = "", o.clearCloneStyle = "content-box" === i.style.backgroundClip, h.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute", h.appendChild(i), r.extend(o, { pixelPosition: function() { - return b(), c }, boxSizingReliable: function() { - return b(), e }, pixelMarginRight: function() { - return b(), f }, reliableMarginLeft: function() { - return b(), g } })) }(); - - function Ma(a, b, c) { - var d, e, f, g, h = a.style; - return c = c || La(a), c && (g = c.getPropertyValue(b) || c[b], "" !== g || r.contains(a.ownerDocument, a) || (g = r.style(a, b)), !o.pixelMarginRight() && Ka.test(g) && Ja.test(b) && (d = h.width, e = h.minWidth, f = h.maxWidth, h.minWidth = h.maxWidth = h.width = g, g = c.width, h.width = d, h.minWidth = e, h.maxWidth = f)), void 0 !== g ? g + "" : g } - - function Na(a, b) { - return { get: function() { - return a() ? void delete this.get : (this.get = b).apply(this, arguments) } } } - var Oa = /^(none|table(?!-c[ea]).+)/, - Pa = { position: "absolute", visibility: "hidden", display: "block" }, - Qa = { letterSpacing: "0", fontWeight: "400" }, - Ra = ["Webkit", "Moz", "ms"], - Sa = d.createElement("div").style; - - function Ta(a) { - if (a in Sa) return a; - var b = a[0].toUpperCase() + a.slice(1), - c = Ra.length; - while (c--) - if (a = Ra[c] + b, a in Sa) return a } - - function Ua(a, b, c) { - var d = _.exec(b); - return d ? Math.max(0, d[2] - (c || 0)) + (d[3] || "px") : b } - - function Va(a, b, c, d, e) { - for (var f = c === (d ? "border" : "content") ? 4 : "width" === b ? 1 : 0, g = 0; f < 4; f += 2) "margin" === c && (g += r.css(a, c + aa[f], !0, e)), d ? ("content" === c && (g -= r.css(a, "padding" + aa[f], !0, e)), "margin" !== c && (g -= r.css(a, "border" + aa[f] + "Width", !0, e))) : (g += r.css(a, "padding" + aa[f], !0, e), "padding" !== c && (g += r.css(a, "border" + aa[f] + "Width", !0, e))); - return g } - - function Wa(a, b, c) { - var d, e = !0, - f = La(a), - g = "border-box" === r.css(a, "boxSizing", !1, f); - if (a.getClientRects().length && (d = a.getBoundingClientRect()[b]), d <= 0 || null == d) { - if (d = Ma(a, b, f), (d < 0 || null == d) && (d = a.style[b]), Ka.test(d)) return d; - e = g && (o.boxSizingReliable() || d === a.style[b]), d = parseFloat(d) || 0 } - return d + Va(a, b, c || (g ? "border" : "content"), e, f) + "px" } - r.extend({ cssHooks: { opacity: { get: function(a, b) { - if (b) { - var c = Ma(a, "opacity"); - return "" === c ? "1" : c } } } }, cssNumber: { animationIterationCount: !0, columnCount: !0, fillOpacity: !0, flexGrow: !0, flexShrink: !0, fontWeight: !0, lineHeight: !0, opacity: !0, order: !0, orphans: !0, widows: !0, zIndex: !0, zoom: !0 }, cssProps: { "float": "cssFloat" }, style: function(a, b, c, d) { - if (a && 3 !== a.nodeType && 8 !== a.nodeType && a.style) { - var e, f, g, h = r.camelCase(b), - i = a.style; - return b = r.cssProps[h] || (r.cssProps[h] = Ta(h) || h), g = r.cssHooks[b] || r.cssHooks[h], void 0 === c ? g && "get" in g && void 0 !== (e = g.get(a, !1, d)) ? e : i[b] : (f = typeof c, "string" === f && (e = _.exec(c)) && e[1] && (c = da(a, b, e), f = "number"), null != c && c === c && ("number" === f && (c += e && e[3] || (r.cssNumber[h] ? "" : "px")), o.clearCloneStyle || "" !== c || 0 !== b.indexOf("background") || (i[b] = "inherit"), g && "set" in g && void 0 === (c = g.set(a, c, d)) || (i[b] = c)), void 0) } }, css: function(a, b, c, d) { - var e, f, g, h = r.camelCase(b); - return b = r.cssProps[h] || (r.cssProps[h] = Ta(h) || h), g = r.cssHooks[b] || r.cssHooks[h], g && "get" in g && (e = g.get(a, !0, c)), void 0 === e && (e = Ma(a, b, d)), "normal" === e && b in Qa && (e = Qa[b]), "" === c || c ? (f = parseFloat(e), c === !0 || isFinite(f) ? f || 0 : e) : e } }), r.each(["height", "width"], function(a, b) { r.cssHooks[b] = { get: function(a, c, d) { - if (c) return !Oa.test(r.css(a, "display")) || a.getClientRects().length && a.getBoundingClientRect().width ? Wa(a, b, d) : ca(a, Pa, function() { - return Wa(a, b, d) }) }, set: function(a, c, d) { - var e, f = d && La(a), - g = d && Va(a, b, d, "border-box" === r.css(a, "boxSizing", !1, f), f); - return g && (e = _.exec(c)) && "px" !== (e[3] || "px") && (a.style[b] = c, c = r.css(a, b)), Ua(a, c, g) } } }), r.cssHooks.marginLeft = Na(o.reliableMarginLeft, function(a, b) { - if (b) return (parseFloat(Ma(a, "marginLeft")) || a.getBoundingClientRect().left - ca(a, { marginLeft: 0 }, function() { - return a.getBoundingClientRect().left })) + "px" }), r.each({ margin: "", padding: "", border: "Width" }, function(a, b) { r.cssHooks[a + b] = { expand: function(c) { - for (var d = 0, e = {}, f = "string" == typeof c ? c.split(" ") : [c]; d < 4; d++) e[a + aa[d] + b] = f[d] || f[d - 2] || f[0]; - return e } }, Ja.test(a) || (r.cssHooks[a + b].set = Ua) }), r.fn.extend({ css: function(a, b) { - return S(this, function(a, b, c) { - var d, e, f = {}, - g = 0; - if (r.isArray(b)) { - for (d = La(a), e = b.length; g < e; g++) f[b[g]] = r.css(a, b[g], !1, d); - return f } - return void 0 !== c ? r.style(a, b, c) : r.css(a, b) }, a, b, arguments.length > 1) } }); - - function Xa(a, b, c, d, e) { - return new Xa.prototype.init(a, b, c, d, e) } - r.Tween = Xa, Xa.prototype = { constructor: Xa, init: function(a, b, c, d, e, f) { this.elem = a, this.prop = c, this.easing = e || r.easing._default, this.options = b, this.start = this.now = this.cur(), this.end = d, this.unit = f || (r.cssNumber[c] ? "" : "px") }, cur: function() { - var a = Xa.propHooks[this.prop]; - return a && a.get ? a.get(this) : Xa.propHooks._default.get(this) }, run: function(a) { - var b, c = Xa.propHooks[this.prop]; - return this.options.duration ? this.pos = b = r.easing[this.easing](a, this.options.duration * a, 0, 1, this.options.duration) : this.pos = b = a, this.now = (this.end - this.start) * b + this.start, this.options.step && this.options.step.call(this.elem, this.now, this), c && c.set ? c.set(this) : Xa.propHooks._default.set(this), this } }, Xa.prototype.init.prototype = Xa.prototype, Xa.propHooks = { _default: { get: function(a) { - var b; - return 1 !== a.elem.nodeType || null != a.elem[a.prop] && null == a.elem.style[a.prop] ? a.elem[a.prop] : (b = r.css(a.elem, a.prop, ""), b && "auto" !== b ? b : 0) }, set: function(a) { r.fx.step[a.prop] ? r.fx.step[a.prop](a) : 1 !== a.elem.nodeType || null == a.elem.style[r.cssProps[a.prop]] && !r.cssHooks[a.prop] ? a.elem[a.prop] = a.now : r.style(a.elem, a.prop, a.now + a.unit) } } }, Xa.propHooks.scrollTop = Xa.propHooks.scrollLeft = { set: function(a) { a.elem.nodeType && a.elem.parentNode && (a.elem[a.prop] = a.now) } }, r.easing = { linear: function(a) { - return a }, swing: function(a) { - return .5 - Math.cos(a * Math.PI) / 2 }, _default: "swing" }, r.fx = Xa.prototype.init, r.fx.step = {}; - var Ya, Za, $a = /^(?:toggle|show|hide)$/, - _a = /queueHooks$/; - - function ab() { Za && (a.requestAnimationFrame(ab), r.fx.tick()) } - - function bb() { - return a.setTimeout(function() { Ya = void 0 }), Ya = r.now() } - - function cb(a, b) { - var c, d = 0, - e = { height: a }; - for (b = b ? 1 : 0; d < 4; d += 2 - b) c = aa[d], e["margin" + c] = e["padding" + c] = a; - return b && (e.opacity = e.width = a), e } - - function db(a, b, c) { - for (var d, e = (gb.tweeners[b] || []).concat(gb.tweeners["*"]), f = 0, g = e.length; f < g; f++) - if (d = e[f].call(c, b, a)) return d } - - function eb(a, b, c) { - var d, e, f, g, h, i, j, k, l = "width" in b || "height" in b, - m = this, - n = {}, - o = a.style, - p = a.nodeType && ba(a), - q = V.get(a, "fxshow"); - c.queue || (g = r._queueHooks(a, "fx"), null == g.unqueued && (g.unqueued = 0, h = g.empty.fire, g.empty.fire = function() { g.unqueued || h() }), g.unqueued++, m.always(function() { m.always(function() { g.unqueued--, r.queue(a, "fx").length || g.empty.fire() }) })); - for (d in b) - if (e = b[d], $a.test(e)) { - if (delete b[d], f = f || "toggle" === e, e === (p ? "hide" : "show")) { - if ("show" !== e || !q || void 0 === q[d]) continue; - p = !0 } - n[d] = q && q[d] || r.style(a, d) } - if (i = !r.isEmptyObject(b), i || !r.isEmptyObject(n)) { l && 1 === a.nodeType && (c.overflow = [o.overflow, o.overflowX, o.overflowY], j = q && q.display, null == j && (j = V.get(a, "display")), k = r.css(a, "display"), "none" === k && (j ? k = j : (ga([a], !0), j = a.style.display || j, k = r.css(a, "display"), ga([a]))), ("inline" === k || "inline-block" === k && null != j) && "none" === r.css(a, "float") && (i || (m.done(function() { o.display = j }), null == j && (k = o.display, j = "none" === k ? "" : k)), o.display = "inline-block")), c.overflow && (o.overflow = "hidden", m.always(function() { o.overflow = c.overflow[0], o.overflowX = c.overflow[1], o.overflowY = c.overflow[2] })), i = !1; - for (d in n) i || (q ? "hidden" in q && (p = q.hidden) : q = V.access(a, "fxshow", { display: j }), f && (q.hidden = !p), p && ga([a], !0), m.done(function() { p || ga([a]), V.remove(a, "fxshow"); - for (d in n) r.style(a, d, n[d]) })), i = db(p ? q[d] : 0, d, m), d in q || (q[d] = i.start, p && (i.end = i.start, i.start = 0)) } } - - function fb(a, b) { - var c, d, e, f, g; - for (c in a) - if (d = r.camelCase(c), e = b[d], f = a[c], r.isArray(f) && (e = f[1], f = a[c] = f[0]), c !== d && (a[d] = f, delete a[c]), g = r.cssHooks[d], g && "expand" in g) { f = g.expand(f), delete a[d]; - for (c in f) c in a || (a[c] = f[c], b[c] = e) } else b[d] = e } - - function gb(a, b, c) { - var d, e, f = 0, - g = gb.prefilters.length, - h = r.Deferred().always(function() { delete i.elem }), - i = function() { - if (e) return !1; - for (var b = Ya || bb(), c = Math.max(0, j.startTime + j.duration - b), d = c / j.duration || 0, f = 1 - d, g = 0, i = j.tweens.length; g < i; g++) j.tweens[g].run(f); - return h.notifyWith(a, [j, f, c]), f < 1 && i ? c : (h.resolveWith(a, [j]), !1) }, - j = h.promise({ elem: a, props: r.extend({}, b), opts: r.extend(!0, { specialEasing: {}, easing: r.easing._default }, c), originalProperties: b, originalOptions: c, startTime: Ya || bb(), duration: c.duration, tweens: [], createTween: function(b, c) { - var d = r.Tween(a, j.opts, b, c, j.opts.specialEasing[b] || j.opts.easing); - return j.tweens.push(d), d }, stop: function(b) { - var c = 0, - d = b ? j.tweens.length : 0; - if (e) return this; - for (e = !0; c < d; c++) j.tweens[c].run(1); - return b ? (h.notifyWith(a, [j, 1, 0]), h.resolveWith(a, [j, b])) : h.rejectWith(a, [j, b]), this } }), - k = j.props; - for (fb(k, j.opts.specialEasing); f < g; f++) - if (d = gb.prefilters[f].call(j, a, k, j.opts)) return r.isFunction(d.stop) && (r._queueHooks(j.elem, j.opts.queue).stop = r.proxy(d.stop, d)), d; - return r.map(k, db, j), r.isFunction(j.opts.start) && j.opts.start.call(a, j), r.fx.timer(r.extend(i, { elem: a, anim: j, queue: j.opts.queue })), j.progress(j.opts.progress).done(j.opts.done, j.opts.complete).fail(j.opts.fail).always(j.opts.always) } - r.Animation = r.extend(gb, { tweeners: { "*": [function(a, b) { - var c = this.createTween(a, b); - return da(c.elem, a, _.exec(b), c), c }] }, tweener: function(a, b) { r.isFunction(a) ? (b = a, a = ["*"]) : a = a.match(K); - for (var c, d = 0, e = a.length; d < e; d++) c = a[d], gb.tweeners[c] = gb.tweeners[c] || [], gb.tweeners[c].unshift(b) }, prefilters: [eb], prefilter: function(a, b) { b ? gb.prefilters.unshift(a) : gb.prefilters.push(a) } }), r.speed = function(a, b, c) { - var e = a && "object" == typeof a ? r.extend({}, a) : { complete: c || !c && b || r.isFunction(a) && a, duration: a, easing: c && b || b && !r.isFunction(b) && b }; - return r.fx.off || d.hidden ? e.duration = 0 : e.duration = "number" == typeof e.duration ? e.duration : e.duration in r.fx.speeds ? r.fx.speeds[e.duration] : r.fx.speeds._default, null != e.queue && e.queue !== !0 || (e.queue = "fx"), e.old = e.complete, e.complete = function() { r.isFunction(e.old) && e.old.call(this), e.queue && r.dequeue(this, e.queue) }, e }, r.fn.extend({ fadeTo: function(a, b, c, d) { - return this.filter(ba).css("opacity", 0).show().end().animate({ opacity: b }, a, c, d) }, animate: function(a, b, c, d) { - var e = r.isEmptyObject(a), - f = r.speed(b, c, d), - g = function() { - var b = gb(this, r.extend({}, a), f); - (e || V.get(this, "finish")) && b.stop(!0) }; - return g.finish = g, e || f.queue === !1 ? this.each(g) : this.queue(f.queue, g) }, stop: function(a, b, c) { - var d = function(a) { - var b = a.stop; - delete a.stop, b(c) }; - return "string" != typeof a && (c = b, b = a, a = void 0), b && a !== !1 && this.queue(a || "fx", []), this.each(function() { - var b = !0, - e = null != a && a + "queueHooks", - f = r.timers, - g = V.get(this); - if (e) g[e] && g[e].stop && d(g[e]); - else - for (e in g) g[e] && g[e].stop && _a.test(e) && d(g[e]); - for (e = f.length; e--;) f[e].elem !== this || null != a && f[e].queue !== a || (f[e].anim.stop(c), b = !1, f.splice(e, 1));!b && c || r.dequeue(this, a) }) }, finish: function(a) { - return a !== !1 && (a = a || "fx"), this.each(function() { - var b, c = V.get(this), - d = c[a + "queue"], - e = c[a + "queueHooks"], - f = r.timers, - g = d ? d.length : 0; - for (c.finish = !0, r.queue(this, a, []), e && e.stop && e.stop.call(this, !0), b = f.length; b--;) f[b].elem === this && f[b].queue === a && (f[b].anim.stop(!0), f.splice(b, 1)); - for (b = 0; b < g; b++) d[b] && d[b].finish && d[b].finish.call(this); - delete c.finish }) } }), r.each(["toggle", "show", "hide"], function(a, b) { - var c = r.fn[b]; - r.fn[b] = function(a, d, e) { - return null == a || "boolean" == typeof a ? c.apply(this, arguments) : this.animate(cb(b, !0), a, d, e) } }), r.each({ slideDown: cb("show"), slideUp: cb("hide"), slideToggle: cb("toggle"), fadeIn: { opacity: "show" }, fadeOut: { opacity: "hide" }, fadeToggle: { opacity: "toggle" } }, function(a, b) { r.fn[a] = function(a, c, d) { - return this.animate(b, a, c, d) } }), r.timers = [], r.fx.tick = function() { - var a, b = 0, - c = r.timers; - for (Ya = r.now(); b < c.length; b++) a = c[b], a() || c[b] !== a || c.splice(b--, 1); - c.length || r.fx.stop(), Ya = void 0 }, r.fx.timer = function(a) { r.timers.push(a), a() ? r.fx.start() : r.timers.pop() }, r.fx.interval = 13, r.fx.start = function() { Za || (Za = a.requestAnimationFrame ? a.requestAnimationFrame(ab) : a.setInterval(r.fx.tick, r.fx.interval)) }, r.fx.stop = function() { a.cancelAnimationFrame ? a.cancelAnimationFrame(Za) : a.clearInterval(Za), Za = null }, r.fx.speeds = { slow: 600, fast: 200, _default: 400 }, r.fn.delay = function(b, c) { - return b = r.fx ? r.fx.speeds[b] || b : b, c = c || "fx", this.queue(c, function(c, d) { - var e = a.setTimeout(c, b); - d.stop = function() { a.clearTimeout(e) } }) }, - function() { - var a = d.createElement("input"), - b = d.createElement("select"), - c = b.appendChild(d.createElement("option")); - a.type = "checkbox", o.checkOn = "" !== a.value, o.optSelected = c.selected, a = d.createElement("input"), a.value = "t", a.type = "radio", o.radioValue = "t" === a.value }(); - var hb, ib = r.expr.attrHandle; - r.fn.extend({ attr: function(a, b) { - return S(this, r.attr, a, b, arguments.length > 1) }, removeAttr: function(a) { - return this.each(function() { r.removeAttr(this, a) }) } }), r.extend({ - attr: function(a, b, c) { - var d, e, f = a.nodeType; - if (3 !== f && 8 !== f && 2 !== f) return "undefined" == typeof a.getAttribute ? r.prop(a, b, c) : (1 === f && r.isXMLDoc(a) || (e = r.attrHooks[b.toLowerCase()] || (r.expr.match.bool.test(b) ? hb : void 0)), void 0 !== c ? null === c ? void r.removeAttr(a, b) : e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : (a.setAttribute(b, c + ""), c) : e && "get" in e && null !== (d = e.get(a, b)) ? d : (d = r.find.attr(a, b), null == d ? void 0 : d)) }, - attrHooks: { type: { set: function(a, b) { - if (!o.radioValue && "radio" === b && r.nodeName(a, "input")) { - var c = a.value; - return a.setAttribute("type", b), c && (a.value = c), b } } } }, - removeAttr: function(a, b) { - var c, d = 0, - e = b && b.match(K); - if (e && 1 === a.nodeType) - while (c = e[d++]) a.removeAttribute(c) - } - }), hb = { set: function(a, b, c) { - return b === !1 ? r.removeAttr(a, c) : a.setAttribute(c, c), c } }, r.each(r.expr.match.bool.source.match(/\w+/g), function(a, b) { - var c = ib[b] || r.find.attr; - ib[b] = function(a, b, d) { - var e, f, g = b.toLowerCase(); - return d || (f = ib[g], ib[g] = e, e = null != c(a, b, d) ? g : null, ib[g] = f), e } }); - var jb = /^(?:input|select|textarea|button)$/i, - kb = /^(?:a|area)$/i; - r.fn.extend({ prop: function(a, b) { - return S(this, r.prop, a, b, arguments.length > 1) }, removeProp: function(a) { - return this.each(function() { delete this[r.propFix[a] || a] }) } }), r.extend({ prop: function(a, b, c) { - var d, e, f = a.nodeType; - if (3 !== f && 8 !== f && 2 !== f) return 1 === f && r.isXMLDoc(a) || (b = r.propFix[b] || b, e = r.propHooks[b]), void 0 !== c ? e && "set" in e && void 0 !== (d = e.set(a, c, b)) ? d : a[b] = c : e && "get" in e && null !== (d = e.get(a, b)) ? d : a[b] }, propHooks: { tabIndex: { get: function(a) { - var b = r.find.attr(a, "tabindex"); - return b ? parseInt(b, 10) : jb.test(a.nodeName) || kb.test(a.nodeName) && a.href ? 0 : -1 } } }, propFix: { "for": "htmlFor", "class": "className" } }), o.optSelected || (r.propHooks.selected = { get: function(a) { - var b = a.parentNode; - return b && b.parentNode && b.parentNode.selectedIndex, null }, set: function(a) { - var b = a.parentNode; - b && (b.selectedIndex, b.parentNode && b.parentNode.selectedIndex) } }), r.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function() { r.propFix[this.toLowerCase()] = this }); - var lb = /[\t\r\n\f]/g; - - function mb(a) { - return a.getAttribute && a.getAttribute("class") || "" } - r.fn.extend({ addClass: function(a) { - var b, c, d, e, f, g, h, i = 0; - if (r.isFunction(a)) return this.each(function(b) { r(this).addClass(a.call(this, b, mb(this))) }); - if ("string" == typeof a && a) { b = a.match(K) || []; - while (c = this[i++]) - if (e = mb(c), d = 1 === c.nodeType && (" " + e + " ").replace(lb, " ")) { g = 0; - while (f = b[g++]) d.indexOf(" " + f + " ") < 0 && (d += f + " "); - h = r.trim(d), e !== h && c.setAttribute("class", h) } } - return this }, removeClass: function(a) { - var b, c, d, e, f, g, h, i = 0; - if (r.isFunction(a)) return this.each(function(b) { r(this).removeClass(a.call(this, b, mb(this))) }); - if (!arguments.length) return this.attr("class", ""); - if ("string" == typeof a && a) { b = a.match(K) || []; - while (c = this[i++]) - if (e = mb(c), d = 1 === c.nodeType && (" " + e + " ").replace(lb, " ")) { g = 0; - while (f = b[g++]) - while (d.indexOf(" " + f + " ") > -1) d = d.replace(" " + f + " ", " "); - h = r.trim(d), e !== h && c.setAttribute("class", h) } } - return this }, toggleClass: function(a, b) { - var c = typeof a; - return "boolean" == typeof b && "string" === c ? b ? this.addClass(a) : this.removeClass(a) : r.isFunction(a) ? this.each(function(c) { r(this).toggleClass(a.call(this, c, mb(this), b), b) }) : this.each(function() { - var b, d, e, f; - if ("string" === c) { d = 0, e = r(this), f = a.match(K) || []; - while (b = f[d++]) e.hasClass(b) ? e.removeClass(b) : e.addClass(b) } else void 0 !== a && "boolean" !== c || (b = mb(this), b && V.set(this, "__className__", b), this.setAttribute && this.setAttribute("class", b || a === !1 ? "" : V.get(this, "__className__") || "")) }) }, hasClass: function(a) { - var b, c, d = 0; - b = " " + a + " "; - while (c = this[d++]) - if (1 === c.nodeType && (" " + mb(c) + " ").replace(lb, " ").indexOf(b) > -1) return !0; - return !1 } }); - var nb = /\r/g, - ob = /[\x20\t\r\n\f]+/g; - r.fn.extend({ val: function(a) { - var b, c, d, e = this[0]; { - if (arguments.length) return d = r.isFunction(a), this.each(function(c) { - var e; - 1 === this.nodeType && (e = d ? a.call(this, c, r(this).val()) : a, null == e ? e = "" : "number" == typeof e ? e += "" : r.isArray(e) && (e = r.map(e, function(a) { - return null == a ? "" : a + "" })), b = r.valHooks[this.type] || r.valHooks[this.nodeName.toLowerCase()], b && "set" in b && void 0 !== b.set(this, e, "value") || (this.value = e)) }); - if (e) return b = r.valHooks[e.type] || r.valHooks[e.nodeName.toLowerCase()], b && "get" in b && void 0 !== (c = b.get(e, "value")) ? c : (c = e.value, "string" == typeof c ? c.replace(nb, "") : null == c ? "" : c) } } }), r.extend({ valHooks: { option: { get: function(a) { - var b = r.find.attr(a, "value"); - return null != b ? b : r.trim(r.text(a)).replace(ob, " ") } }, select: { get: function(a) { - for (var b, c, d = a.options, e = a.selectedIndex, f = "select-one" === a.type, g = f ? null : [], h = f ? e + 1 : d.length, i = e < 0 ? h : f ? e : 0; i < h; i++) - if (c = d[i], (c.selected || i === e) && !c.disabled && (!c.parentNode.disabled || !r.nodeName(c.parentNode, "optgroup"))) { - if (b = r(c).val(), f) return b; - g.push(b) } - return g }, set: function(a, b) { - var c, d, e = a.options, - f = r.makeArray(b), - g = e.length; - while (g--) d = e[g], (d.selected = r.inArray(r.valHooks.option.get(d), f) > -1) && (c = !0); - return c || (a.selectedIndex = -1), f } } } }), r.each(["radio", "checkbox"], function() { r.valHooks[this] = { set: function(a, b) { - if (r.isArray(b)) return a.checked = r.inArray(r(a).val(), b) > -1 } }, o.checkOn || (r.valHooks[this].get = function(a) { - return null === a.getAttribute("value") ? "on" : a.value }) }); - var pb = /^(?:focusinfocus|focusoutblur)$/; - r.extend(r.event, { trigger: function(b, c, e, f) { - var g, h, i, j, k, m, n, o = [e || d], - p = l.call(b, "type") ? b.type : b, - q = l.call(b, "namespace") ? b.namespace.split(".") : []; - if (h = i = e = e || d, 3 !== e.nodeType && 8 !== e.nodeType && !pb.test(p + r.event.triggered) && (p.indexOf(".") > -1 && (q = p.split("."), p = q.shift(), q.sort()), k = p.indexOf(":") < 0 && "on" + p, b = b[r.expando] ? b : new r.Event(p, "object" == typeof b && b), b.isTrigger = f ? 2 : 3, b.namespace = q.join("."), b.rnamespace = b.namespace ? new RegExp("(^|\\.)" + q.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = e), c = null == c ? [b] : r.makeArray(c, [b]), n = r.event.special[p] || {}, f || !n.trigger || n.trigger.apply(e, c) !== !1)) { - if (!f && !n.noBubble && !r.isWindow(e)) { - for (j = n.delegateType || p, pb.test(j + p) || (h = h.parentNode); h; h = h.parentNode) o.push(h), i = h; - i === (e.ownerDocument || d) && o.push(i.defaultView || i.parentWindow || a) } - g = 0; - while ((h = o[g++]) && !b.isPropagationStopped()) b.type = g > 1 ? j : n.bindType || p, m = (V.get(h, "events") || {})[b.type] && V.get(h, "handle"), m && m.apply(h, c), m = k && h[k], m && m.apply && T(h) && (b.result = m.apply(h, c), b.result === !1 && b.preventDefault()); - return b.type = p, f || b.isDefaultPrevented() || n._default && n._default.apply(o.pop(), c) !== !1 || !T(e) || k && r.isFunction(e[p]) && !r.isWindow(e) && (i = e[k], i && (e[k] = null), r.event.triggered = p, e[p](), r.event.triggered = void 0, i && (e[k] = i)), b.result } }, simulate: function(a, b, c) { - var d = r.extend(new r.Event, c, { type: a, isSimulated: !0 }); - r.event.trigger(d, null, b) } }), r.fn.extend({ trigger: function(a, b) { - return this.each(function() { r.event.trigger(a, b, this) }) }, triggerHandler: function(a, b) { - var c = this[0]; - if (c) return r.event.trigger(a, b, c, !0) } }), r.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "), function(a, b) { r.fn[b] = function(a, c) { - return arguments.length > 0 ? this.on(b, null, a, c) : this.trigger(b) } }), r.fn.extend({ hover: function(a, b) { - return this.mouseenter(a).mouseleave(b || a) } }), o.focusin = "onfocusin" in a, o.focusin || r.each({ focus: "focusin", blur: "focusout" }, function(a, b) { - var c = function(a) { r.event.simulate(b, a.target, r.event.fix(a)) }; - r.event.special[b] = { setup: function() { - var d = this.ownerDocument || this, - e = V.access(d, b); - e || d.addEventListener(a, c, !0), V.access(d, b, (e || 0) + 1) }, teardown: function() { - var d = this.ownerDocument || this, - e = V.access(d, b) - 1; - e ? V.access(d, b, e) : (d.removeEventListener(a, c, !0), V.remove(d, b)) } } }); - var qb = a.location, - rb = r.now(), - sb = /\?/; - r.parseXML = function(b) { - var c; - if (!b || "string" != typeof b) return null; - try { c = (new a.DOMParser).parseFromString(b, "text/xml") } catch (d) { c = void 0 } - return c && !c.getElementsByTagName("parsererror").length || r.error("Invalid XML: " + b), c }; - var tb = /\[\]$/, - ub = /\r?\n/g, - vb = /^(?:submit|button|image|reset|file)$/i, - wb = /^(?:input|select|textarea|keygen)/i; - - function xb(a, b, c, d) { - var e; - if (r.isArray(b)) r.each(b, function(b, e) { c || tb.test(a) ? d(a, e) : xb(a + "[" + ("object" == typeof e && null != e ? b : "") + "]", e, c, d) }); - else if (c || "object" !== r.type(b)) d(a, b); - else - for (e in b) xb(a + "[" + e + "]", b[e], c, d) } - r.param = function(a, b) { - var c, d = [], - e = function(a, b) { - var c = r.isFunction(b) ? b() : b; - d[d.length] = encodeURIComponent(a) + "=" + encodeURIComponent(null == c ? "" : c) }; - if (r.isArray(a) || a.jquery && !r.isPlainObject(a)) r.each(a, function() { e(this.name, this.value) }); - else - for (c in a) xb(c, a[c], b, e); - return d.join("&") }, r.fn.extend({ serialize: function() { - return r.param(this.serializeArray()) }, serializeArray: function() { - return this.map(function() { - var a = r.prop(this, "elements"); - return a ? r.makeArray(a) : this }).filter(function() { - var a = this.type; - return this.name && !r(this).is(":disabled") && wb.test(this.nodeName) && !vb.test(a) && (this.checked || !ha.test(a)) }).map(function(a, b) { - var c = r(this).val(); - return null == c ? null : r.isArray(c) ? r.map(c, function(a) { - return { name: b.name, value: a.replace(ub, "\r\n") } }) : { name: b.name, value: c.replace(ub, "\r\n") } }).get() } }); - var yb = /%20/g, - zb = /#.*$/, - Ab = /([?&])_=[^&]*/, - Bb = /^(.*?):[ \t]*([^\r\n]*)$/gm, - Cb = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, - Db = /^(?:GET|HEAD)$/, - Eb = /^\/\//, - Fb = {}, - Gb = {}, - Hb = "*/".concat("*"), - Ib = d.createElement("a"); - Ib.href = qb.href; - - function Jb(a) { - return function(b, c) { "string" != typeof b && (c = b, b = "*"); - var d, e = 0, - f = b.toLowerCase().match(K) || []; - if (r.isFunction(c)) - while (d = f[e++]) "+" === d[0] ? (d = d.slice(1) || "*", (a[d] = a[d] || []).unshift(c)) : (a[d] = a[d] || []).push(c) } } - - function Kb(a, b, c, d) { - var e = {}, - f = a === Gb; - - function g(h) { - var i; - return e[h] = !0, r.each(a[h] || [], function(a, h) { - var j = h(b, c, d); - return "string" != typeof j || f || e[j] ? f ? !(i = j) : void 0 : (b.dataTypes.unshift(j), g(j), !1) }), i } - return g(b.dataTypes[0]) || !e["*"] && g("*") } - - function Lb(a, b) { - var c, d, e = r.ajaxSettings.flatOptions || {}; - for (c in b) void 0 !== b[c] && ((e[c] ? a : d || (d = {}))[c] = b[c]); - return d && r.extend(!0, a, d), a } - - function Mb(a, b, c) { - var d, e, f, g, h = a.contents, - i = a.dataTypes; - while ("*" === i[0]) i.shift(), void 0 === d && (d = a.mimeType || b.getResponseHeader("Content-Type")); - if (d) - for (e in h) - if (h[e] && h[e].test(d)) { i.unshift(e); - break } - if (i[0] in c) f = i[0]; - else { - for (e in c) { - if (!i[0] || a.converters[e + " " + i[0]]) { f = e; - break } - g || (g = e) } - f = f || g } - if (f) return f !== i[0] && i.unshift(f), c[f] } - - function Nb(a, b, c, d) { - var e, f, g, h, i, j = {}, - k = a.dataTypes.slice(); - if (k[1]) - for (g in a.converters) j[g.toLowerCase()] = a.converters[g]; - f = k.shift(); - while (f) - if (a.responseFields[f] && (c[a.responseFields[f]] = b), !i && d && a.dataFilter && (b = a.dataFilter(b, a.dataType)), i = f, f = k.shift()) - if ("*" === f) f = i; - else if ("*" !== i && i !== f) { - if (g = j[i + " " + f] || j["* " + f], !g) - for (e in j) - if (h = e.split(" "), h[1] === f && (g = j[i + " " + h[0]] || j["* " + h[0]])) { g === !0 ? g = j[e] : j[e] !== !0 && (f = h[0], k.unshift(h[1])); - break } - if (g !== !0) - if (g && a["throws"]) b = g(b); - else try { b = g(b) } catch (l) { - return { state: "parsererror", error: g ? l : "No conversion from " + i + " to " + f } } } - return { state: "success", data: b } } - r.extend({ active: 0, lastModified: {}, etag: {}, ajaxSettings: { url: qb.href, type: "GET", isLocal: Cb.test(qb.protocol), global: !0, processData: !0, async: !0, contentType: "application/x-www-form-urlencoded; charset=UTF-8", accepts: { "*": Hb, text: "text/plain", html: "text/html", xml: "application/xml, text/xml", json: "application/json, text/javascript" }, contents: { xml: /\bxml\b/, html: /\bhtml/, json: /\bjson\b/ }, responseFields: { xml: "responseXML", text: "responseText", json: "responseJSON" }, converters: { "* text": String, "text html": !0, "text json": JSON.parse, "text xml": r.parseXML }, flatOptions: { url: !0, context: !0 } }, ajaxSetup: function(a, b) { - return b ? Lb(Lb(a, r.ajaxSettings), b) : Lb(r.ajaxSettings, a) }, ajaxPrefilter: Jb(Fb), ajaxTransport: Jb(Gb), ajax: function(b, c) { "object" == typeof b && (c = b, b = void 0), c = c || {}; - var e, f, g, h, i, j, k, l, m, n, o = r.ajaxSetup({}, c), - p = o.context || o, - q = o.context && (p.nodeType || p.jquery) ? r(p) : r.event, - s = r.Deferred(), - t = r.Callbacks("once memory"), - u = o.statusCode || {}, - v = {}, - w = {}, - x = "canceled", - y = { readyState: 0, getResponseHeader: function(a) { - var b; - if (k) { - if (!h) { h = {}; - while (b = Bb.exec(g)) h[b[1].toLowerCase()] = b[2] } - b = h[a.toLowerCase()] } - return null == b ? null : b }, getAllResponseHeaders: function() { - return k ? g : null }, setRequestHeader: function(a, b) { - return null == k && (a = w[a.toLowerCase()] = w[a.toLowerCase()] || a, v[a] = b), this }, overrideMimeType: function(a) { - return null == k && (o.mimeType = a), this }, statusCode: function(a) { - var b; - if (a) - if (k) y.always(a[y.status]); - else - for (b in a) u[b] = [u[b], a[b]]; - return this }, abort: function(a) { - var b = a || x; - return e && e.abort(b), A(0, b), this } }; - if (s.promise(y), o.url = ((b || o.url || qb.href) + "").replace(Eb, qb.protocol + "//"), o.type = c.method || c.type || o.method || o.type, o.dataTypes = (o.dataType || "*").toLowerCase().match(K) || [""], null == o.crossDomain) { j = d.createElement("a"); - try { j.href = o.url, j.href = j.href, o.crossDomain = Ib.protocol + "//" + Ib.host != j.protocol + "//" + j.host } catch (z) { o.crossDomain = !0 } } - if (o.data && o.processData && "string" != typeof o.data && (o.data = r.param(o.data, o.traditional)), Kb(Fb, o, c, y), k) return y; - l = r.event && o.global, l && 0 === r.active++ && r.event.trigger("ajaxStart"), o.type = o.type.toUpperCase(), o.hasContent = !Db.test(o.type), f = o.url.replace(zb, ""), o.hasContent ? o.data && o.processData && 0 === (o.contentType || "").indexOf("application/x-www-form-urlencoded") && (o.data = o.data.replace(yb, "+")) : (n = o.url.slice(f.length), o.data && (f += (sb.test(f) ? "&" : "?") + o.data, delete o.data), o.cache === !1 && (f = f.replace(Ab, ""), n = (sb.test(f) ? "&" : "?") + "_=" + rb++ + n), o.url = f + n), o.ifModified && (r.lastModified[f] && y.setRequestHeader("If-Modified-Since", r.lastModified[f]), r.etag[f] && y.setRequestHeader("If-None-Match", r.etag[f])), (o.data && o.hasContent && o.contentType !== !1 || c.contentType) && y.setRequestHeader("Content-Type", o.contentType), y.setRequestHeader("Accept", o.dataTypes[0] && o.accepts[o.dataTypes[0]] ? o.accepts[o.dataTypes[0]] + ("*" !== o.dataTypes[0] ? ", " + Hb + "; q=0.01" : "") : o.accepts["*"]); - for (m in o.headers) y.setRequestHeader(m, o.headers[m]); - if (o.beforeSend && (o.beforeSend.call(p, y, o) === !1 || k)) return y.abort(); - if (x = "abort", t.add(o.complete), y.done(o.success), y.fail(o.error), e = Kb(Gb, o, c, y)) { - if (y.readyState = 1, l && q.trigger("ajaxSend", [y, o]), k) return y; - o.async && o.timeout > 0 && (i = a.setTimeout(function() { y.abort("timeout") }, o.timeout)); - try { k = !1, e.send(v, A) } catch (z) { - if (k) throw z; - A(-1, z) } } else A(-1, "No Transport"); - - function A(b, c, d, h) { - var j, m, n, v, w, x = c; - k || (k = !0, i && a.clearTimeout(i), e = void 0, g = h || "", y.readyState = b > 0 ? 4 : 0, j = b >= 200 && b < 300 || 304 === b, d && (v = Mb(o, y, d)), v = Nb(o, v, y, j), j ? (o.ifModified && (w = y.getResponseHeader("Last-Modified"), w && (r.lastModified[f] = w), w = y.getResponseHeader("etag"), w && (r.etag[f] = w)), 204 === b || "HEAD" === o.type ? x = "nocontent" : 304 === b ? x = "notmodified" : (x = v.state, m = v.data, n = v.error, j = !n)) : (n = x, !b && x || (x = "error", b < 0 && (b = 0))), y.status = b, y.statusText = (c || x) + "", j ? s.resolveWith(p, [m, x, y]) : s.rejectWith(p, [y, x, n]), y.statusCode(u), u = void 0, l && q.trigger(j ? "ajaxSuccess" : "ajaxError", [y, o, j ? m : n]), t.fireWith(p, [y, x]), l && (q.trigger("ajaxComplete", [y, o]), --r.active || r.event.trigger("ajaxStop"))) } - return y }, getJSON: function(a, b, c) { - return r.get(a, b, c, "json") }, getScript: function(a, b) { - return r.get(a, void 0, b, "script") } }), r.each(["get", "post"], function(a, b) { r[b] = function(a, c, d, e) { - return r.isFunction(c) && (e = e || d, d = c, c = void 0), r.ajax(r.extend({ url: a, type: b, dataType: e, data: c, success: d }, r.isPlainObject(a) && a)) } }), r._evalUrl = function(a) { - return r.ajax({ url: a, type: "GET", dataType: "script", cache: !0, async: !1, global: !1, "throws": !0 }) }, r.fn.extend({ wrapAll: function(a) { - var b; - return this[0] && (r.isFunction(a) && (a = a.call(this[0])), b = r(a, this[0].ownerDocument).eq(0).clone(!0), this[0].parentNode && b.insertBefore(this[0]), b.map(function() { - var a = this; - while (a.firstElementChild) a = a.firstElementChild; - return a }).append(this)), this }, wrapInner: function(a) { - return r.isFunction(a) ? this.each(function(b) { r(this).wrapInner(a.call(this, b)) }) : this.each(function() { - var b = r(this), - c = b.contents(); - c.length ? c.wrapAll(a) : b.append(a) }) }, wrap: function(a) { - var b = r.isFunction(a); - return this.each(function(c) { r(this).wrapAll(b ? a.call(this, c) : a) }) }, unwrap: function(a) { - return this.parent(a).not("body").each(function() { r(this).replaceWith(this.childNodes) }), this } }), r.expr.pseudos.hidden = function(a) { - return !r.expr.pseudos.visible(a) }, r.expr.pseudos.visible = function(a) { - return !!(a.offsetWidth || a.offsetHeight || a.getClientRects().length) }, r.ajaxSettings.xhr = function() { - try { - return new a.XMLHttpRequest } catch (b) {} }; - var Ob = { 0: 200, 1223: 204 }, - Pb = r.ajaxSettings.xhr(); - o.cors = !!Pb && "withCredentials" in Pb, o.ajax = Pb = !!Pb, r.ajaxTransport(function(b) { - var c, d; - if (o.cors || Pb && !b.crossDomain) return { send: function(e, f) { - var g, h = b.xhr(); - if (h.open(b.type, b.url, b.async, b.username, b.password), b.xhrFields) - for (g in b.xhrFields) h[g] = b.xhrFields[g]; - b.mimeType && h.overrideMimeType && h.overrideMimeType(b.mimeType), b.crossDomain || e["X-Requested-With"] || (e["X-Requested-With"] = "XMLHttpRequest"); - for (g in e) h.setRequestHeader(g, e[g]); - c = function(a) { - return function() { c && (c = d = h.onload = h.onerror = h.onabort = h.onreadystatechange = null, "abort" === a ? h.abort() : "error" === a ? "number" != typeof h.status ? f(0, "error") : f(h.status, h.statusText) : f(Ob[h.status] || h.status, h.statusText, "text" !== (h.responseType || "text") || "string" != typeof h.responseText ? { binary: h.response } : { text: h.responseText }, h.getAllResponseHeaders())) } }, h.onload = c(), d = h.onerror = c("error"), void 0 !== h.onabort ? h.onabort = d : h.onreadystatechange = function() { 4 === h.readyState && a.setTimeout(function() { c && d() }) }, c = c("abort"); - try { h.send(b.hasContent && b.data || null) } catch (i) { - if (c) throw i } }, abort: function() { c && c() } } }), r.ajaxPrefilter(function(a) { a.crossDomain && (a.contents.script = !1) }), r.ajaxSetup({ accepts: { script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" }, contents: { script: /\b(?:java|ecma)script\b/ }, converters: { "text script": function(a) { - return r.globalEval(a), a } } }), r.ajaxPrefilter("script", function(a) { void 0 === a.cache && (a.cache = !1), a.crossDomain && (a.type = "GET") }), r.ajaxTransport("script", function(a) { - if (a.crossDomain) { - var b, c; - return { send: function(e, f) { b = r(" - {{/unless}} - - - - - - - - - - - - - - - - -
-
-
-
-
-
- {{#each scripts.polyfills}} - - {{/each}} - - - - - diff --git a/samples/simm-valuation-demo/src/main/web/src/main.ts b/samples/simm-valuation-demo/src/main/web/src/main.ts deleted file mode 100644 index 3afef742c0..0000000000 --- a/samples/simm-valuation-demo/src/main/web/src/main.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { bootstrap } from '@angular/platform-browser-dynamic'; -import { enableProdMode } from '@angular/core'; -import { HTTP_PROVIDERS } from '@angular/http'; -import {disableDeprecatedForms, provideForms} from '@angular/forms'; -import { AppComponent, environment } from './app/'; -import { appRouterProviders } from './app/app.routes'; - -if (environment.production) { - enableProdMode(); -} - -bootstrap(AppComponent, [ - appRouterProviders, - HTTP_PROVIDERS, - // magic to fix ngModel error on ng2-bootstrap: - disableDeprecatedForms(), - provideForms() -]) -.catch(err => console.error(err)); diff --git a/samples/simm-valuation-demo/src/main/web/src/system-config.ts b/samples/simm-valuation-demo/src/main/web/src/system-config.ts deleted file mode 100644 index 0d3079dc2b..0000000000 --- a/samples/simm-valuation-demo/src/main/web/src/system-config.ts +++ /dev/null @@ -1,98 +0,0 @@ -"use strict"; - -// SystemJS configuration file, see links for more information -// https://github.com/systemjs/systemjs -// https://github.com/systemjs/systemjs/blob/master/docs/config-api.md - -/*********************************************************************************************** - * User Configuration. - **********************************************************************************************/ -/** Map relative paths to URLs. */ -const map: any = { - 'moment': 'vendor/moment/moment.js', - 'underscore': 'vendor/underscore/underscore.js', - 'jquery': 'vendor/dist/jquery.js', - 'highcharts': 'vendor/highcharts/highstock.src.js', - 'ng2-bootstrap': 'vendor/ng2-bootstrap', - 'ng2-popover': 'vendor/ng2-popover', - 'ng2-select': 'vendor/ng2-select', - 'ng2-table': 'vendor/ng2-table' -}; - -/** User packages configuration. */ -const packages: any = { - 'moment': { - format: 'cjs' - }, - 'underscore': { - format: 'cjs' - }, - 'ng2-bootstrap': { - format: 'cjs', - defaultExtension: 'js', - main: 'ng2-bootstrap.js' - }, - 'ng2-popover': { - main: 'index.js', - defaultExtension: 'js' - }, - 'ng2-select': { - defaultExtension: 'js' - }, - 'ng2-table': { - defaultExtension: 'js' - } -}; - -//////////////////////////////////////////////////////////////////////////////////////////////// -/***************************************httpWrapperService******************************************************** - * Everything underneath this line is managed by the CLI. - **********************************************************************************************/ -const barrels: string[] = [ - // Angular specific barrels. - '@angular/core', - '@angular/common', - '@angular/compiler', - '@angular/forms', - '@angular/http', - '@angular/router', - '@angular/platform-browser', - '@angular/platform-browser-dynamic', - - // Thirdparty barrels. - 'rxjs', - - // App specific barrels. - 'app', - 'app/shared', - 'app/portfolio-component', - 'app/portfolio', - 'app/valuations', - 'app/create-trade', - 'app/view-trade', - /** @cli-barrel */ -]; - -const cliSystemConfigPackages: any = {}; -barrels.forEach((barrelName: string) => { - cliSystemConfigPackages[barrelName] = { main: 'index' }; -}); - -/** Type declaration for ambient System. */ -/* beautify preserve:start */ -declare var System: any; -/* beautify preserve:end */ - -// Apply the CLI SystemJS configuration. -System.config({ - baseURL: "/web/simmvaluationdemo", - map: { - '@angular': 'vendor/@angular', - 'rxjs': 'vendor/rxjs', - 'main': 'main.js' - }, - packages: cliSystemConfigPackages -}); - -// Apply the user's configuration. -System.config({ map, packages }); diff --git a/samples/simm-valuation-demo/src/main/web/src/tsconfig.json b/samples/simm-valuation-demo/src/main/web/src/tsconfig.json deleted file mode 100644 index 4f68f35461..0000000000 --- a/samples/simm-valuation-demo/src/main/web/src/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "declaration": false, - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "mapRoot": "/", - "module": "commonjs", - "moduleResolution": "node", - "noEmitOnError": true, - "noImplicitAny": false, - "outDir": "../dist/", - "rootDir": ".", - "sourceMap": true, - "target": "es5", - "inlineSources": true - }, - - "files": [ - "main.ts", - "typings.d.ts" - ] -} diff --git a/samples/simm-valuation-demo/src/main/web/src/typings.d.ts b/samples/simm-valuation-demo/src/main/web/src/typings.d.ts deleted file mode 100644 index 0d813fd4e5..0000000000 --- a/samples/simm-valuation-demo/src/main/web/src/typings.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Typings reference file, see links for more information -// https://github.com/typings/typings -// https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html - -/// -declare var module: { id: string }; diff --git a/samples/simm-valuation-demo/src/main/web/tslint.json b/samples/simm-valuation-demo/src/main/web/tslint.json deleted file mode 100644 index 7b13bd1790..0000000000 --- a/samples/simm-valuation-demo/src/main/web/tslint.json +++ /dev/null @@ -1,110 +0,0 @@ -{ - "rulesDirectory": [ - "node_modules/codelyzer" - ], - "rules": { - "class-name": true, - "comment-format": [ - true, - "check-space" - ], - "curly": true, - "eofline": true, - "forin": true, - "indent": [ - true, - "spaces" - ], - "label-position": true, - "label-undefined": true, - "max-line-length": [ - true, - 140 - ], - "member-access": false, - "member-ordering": [ - true, - "static-before-instance", - "variables-before-functions" - ], - "no-arg": true, - "no-bitwise": true, - "no-console": [ - true, - "debug", - "info", - "time", - "timeEnd", - "trace" - ], - "no-construct": true, - "no-debugger": true, - "no-duplicate-key": true, - "no-duplicate-variable": true, - "no-empty": false, - "no-eval": true, - "no-inferrable-types": true, - "no-shadowed-variable": true, - "no-string-literal": false, - "no-switch-case-fall-through": true, - "no-trailing-whitespace": true, - "no-unused-expression": true, - "no-unused-variable": true, - "no-unreachable": true, - "no-use-before-declare": true, - "no-var-keyword": true, - "object-literal-sort-keys": false, - "one-line": [ - true, - "check-open-brace", - "check-catch", - "check-else", - "check-whitespace" - ], - "quotemark": [ - true, - "single" - ], - "radix": true, - "semicolon": [ - "always" - ], - "triple-equals": [ - true, - "allow-null-check" - ], - "typedef-whitespace": [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace" - } - ], - "variable-name": false, - "whitespace": [ - true, - "check-branch", - "check-decl", - "check-operator", - "check-separator", - "check-type" - ], - - "directive-selector-name": [true, "camelCase"], - "component-selector-name": [true, "kebab-case"], - "directive-selector-type": [true, "attribute"], - "component-selector-type": [true, "element"], - "use-input-property-decorator": true, - "use-output-property-decorator": true, - "use-host-property-decorator": true, - "no-input-rename": true, - "no-output-rename": true, - "use-life-cycle-interface": true, - "use-pipe-transform-interface": true, - "component-class-suffix": true, - "directive-class-suffix": true - } -} diff --git a/samples/simm-valuation-demo/src/main/web/typings.json b/samples/simm-valuation-demo/src/main/web/typings.json deleted file mode 100644 index ea32c5c4aa..0000000000 --- a/samples/simm-valuation-demo/src/main/web/typings.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "globalDevDependencies": { - "angular-protractor": "registry:dt/angular-protractor#1.5.0+20160425143459", - "jasmine": "registry:dt/jasmine#2.2.0+20160621224255", - "selenium-webdriver": "registry:dt/selenium-webdriver#2.44.0+20160317120654" - }, - "globalDependencies": { - "es6-shim": "registry:dt/es6-shim#0.31.2+20160602141504", - "moment": "registry:dt/moment#2.8.0+20160316155526", - "underscore": "registry:dt/underscore#1.7.0+20160720002543" - } -} From fd9c79659df10919b30629ae9d2cfa2b547c57b4 Mon Sep 17 00:00:00 2001 From: Maksymilian Pawlak <120831+m4ksio@users.noreply.github.com> Date: Thu, 21 Sep 2017 10:19:42 +0100 Subject: [PATCH 020/230] CordaX500Name JAX-RS parameter converter (#1571) --- .../corda/webserver/converters/Converters.kt | 23 +++++++++++++++++++ .../corda/webserver/internal/NodeWebServer.kt | 2 ++ 2 files changed, 25 insertions(+) create mode 100644 webserver/src/main/kotlin/net/corda/webserver/converters/Converters.kt diff --git a/webserver/src/main/kotlin/net/corda/webserver/converters/Converters.kt b/webserver/src/main/kotlin/net/corda/webserver/converters/Converters.kt new file mode 100644 index 0000000000..ca47c80173 --- /dev/null +++ b/webserver/src/main/kotlin/net/corda/webserver/converters/Converters.kt @@ -0,0 +1,23 @@ +package net.corda.webserver.converters + +import net.corda.core.identity.CordaX500Name +import java.lang.reflect.Type +import javax.ws.rs.ext.ParamConverter +import javax.ws.rs.ext.ParamConverterProvider +import javax.ws.rs.ext.Provider + +object CordaX500NameConverter : ParamConverter { + override fun toString(value: CordaX500Name) = value.toString() + override fun fromString(value: String) = CordaX500Name.parse(value) +} + +@Provider +object CordaConverterProvider : ParamConverterProvider { + override fun getConverter(rawType: Class, genericType: Type?, annotations: Array?): ParamConverter? { + if (rawType == CordaX500Name::class.java) { + @Suppress("UNCHECKED_CAST") + return CordaX500NameConverter as ParamConverter + } + return null + } +} \ No newline at end of file diff --git a/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt b/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt index 80d337cc39..b61243fbf8 100644 --- a/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt +++ b/webserver/src/main/kotlin/net/corda/webserver/internal/NodeWebServer.kt @@ -7,6 +7,7 @@ import net.corda.core.messaging.CordaRPCOps import net.corda.core.utilities.loggerFor import net.corda.nodeapi.ArtemisMessagingComponent import net.corda.webserver.WebServerConfig +import net.corda.webserver.converters.CordaConverterProvider import net.corda.webserver.services.WebServerPluginRegistry import net.corda.webserver.servlets.* import org.apache.activemq.artemis.api.core.ActiveMQNotConnectedException @@ -136,6 +137,7 @@ class NodeWebServer(val config: WebServerConfig) { val resourceConfig = ResourceConfig() .register(ObjectMapperConfig(rpcObjectMapper)) .register(ResponseFilter()) + .register(CordaConverterProvider) .register(APIServerImpl(localRpc)) val webAPIsOnClasspath = pluginRegistries.flatMap { x -> x.webApis } From 0314e650a45c5f51d982f3a4aa214de8f2edc661 Mon Sep 17 00:00:00 2001 From: Andrius Dagys Date: Thu, 21 Sep 2017 10:28:18 +0100 Subject: [PATCH 021/230] Clean up API for selecting notaries (#1573) * Remove getAnyNotary() from network map API. Change notaryIdentities() signature to return a Party instead of PartyAndCertificate. Some API doc updates. * Minor API doc formatting and typo fix * Update changelog * Address comments * Address comments --- .../client/jfx/model/NetworkIdentityModel.kt | 7 +- .../client/jfx/model/NodeMonitorModel.kt | 4 +- .../net/corda/core/messaging/CordaRPCOps.kt | 66 +++++++------------ .../corda/core/node/services/CordaService.kt | 2 +- .../core/node/services/NetworkMapCache.kt | 39 +++++------ docs/source/changelog.rst | 2 +- .../corda/docs/IntegrationTestingTutorial.kt | 2 +- .../java/net/corda/docs/FlowCookbookJava.java | 9 ++- .../net/corda/docs/ClientRpcTutorial.kt | 2 +- .../kotlin/net/corda/docs/CustomVaultQuery.kt | 4 +- .../kotlin/net/corda/docs/FlowCookbook.kt | 9 ++- .../corda/docs/FxTransactionBuildTutorial.kt | 2 +- .../docs/WorkflowTransactionBuildTutorial.kt | 3 +- .../net/corda/node/NodePerformanceTests.kt | 2 +- .../services/messaging/P2PMessagingTest.kt | 10 ++- .../test/node/NodeStatePersistenceTests.kt | 2 +- .../corda/node/internal/CordaRPCOpsImpl.kt | 3 +- .../network/PersistentNetworkMapCache.kt | 38 +++++++---- .../net/corda/node/CordaRPCOpsImplTest.kt | 2 +- .../services/events/ScheduledFlowTests.kt | 4 +- .../corda/bank/BankOfCordaRPCClientTest.kt | 2 +- .../net/corda/irs/flows/AutoOfferFlow.kt | 2 +- .../corda/irs/flows/UpdateBusinessDayFlow.kt | 2 +- .../corda/netmap/simulation/IRSSimulation.kt | 2 +- .../kotlin/net/corda/notarydemo/Notarise.kt | 4 +- .../kotlin/net/corda/vega/api/PortfolioApi.kt | 2 +- .../net/corda/vega/flows/IRSTradeFlow.kt | 4 +- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 2 +- .../corda/traderdemo/TraderDemoClientApi.kt | 3 +- .../net/corda/traderdemo/flow/BuyerFlow.kt | 5 +- .../net/corda/traderdemo/flow/SellerFlow.kt | 2 - .../kotlin/net/corda/testing/CoreTestUtils.kt | 4 +- .../net/corda/explorer/ExplorerSimulation.kt | 2 +- .../views/cordapps/cash/NewTransaction.kt | 2 +- .../kotlin/net/corda/loadtest/Disruption.kt | 3 +- .../kotlin/net/corda/loadtest/LoadTest.kt | 3 +- .../net/corda/loadtest/tests/CrossCashTest.kt | 2 +- .../net/corda/loadtest/tests/SelfIssueTest.kt | 2 +- .../net/corda/loadtest/tests/StabilityTest.kt | 2 +- 39 files changed, 118 insertions(+), 144 deletions(-) diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt index 93d76405a5..c17a9f5140 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt @@ -8,6 +8,7 @@ import javafx.collections.ObservableList import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.map import net.corda.core.identity.AnonymousParty +import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache.MapChange @@ -36,9 +37,9 @@ class NetworkIdentityModel { publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } } }) - val notaries: ObservableList = FXCollections.observableList(rpcProxy.value?.notaryIdentities()) - val notaryNodes: ObservableList = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it.party) }) - val parties: ObservableList = networkIdentities.filtered { it.legalIdentitiesAndCerts.all { it !in notaries } } + val notaries: ObservableList = FXCollections.observableList(rpcProxy.value?.notaryIdentities()) + val notaryNodes: ObservableList = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }) + val parties: ObservableList = networkIdentities.filtered { it.legalIdentities.all { it !in notaries } } val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party } fun partyFromPublicKey(publicKey: PublicKey): ObservableValue = identityCache[publicKey] diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt index 434b405d2d..328b164e85 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt @@ -5,7 +5,7 @@ import net.corda.client.rpc.CordaRPCClient import net.corda.client.rpc.CordaRPCClientConfiguration import net.corda.core.contracts.ContractState import net.corda.core.flows.StateMachineRunId -import net.corda.core.identity.PartyAndCertificate +import net.corda.core.identity.Party import net.corda.core.messaging.* import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.Vault @@ -46,7 +46,7 @@ class NodeMonitorModel { val networkMap: Observable = networkMapSubject val proxyObservable = SimpleObjectProperty() - lateinit var notaryIdentities: List + lateinit var notaryIdentities: List /** * Register for updates to/from a given vault. diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index a6bf3c63cb..bdf85ce48a 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -9,7 +9,6 @@ import net.corda.core.flows.StateMachineRunId import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache import net.corda.core.node.services.Vault @@ -59,13 +58,12 @@ interface CordaRPCOps : RPCOps { */ override val protocolVersion: Int get() = nodeInfo().platformVersion - /** - * Returns a list of currently in-progress state machine infos. - */ + /** Returns a list of currently in-progress state machine infos. */ fun stateMachinesSnapshot(): List /** - * Returns a data feed of currently in-progress state machine infos and an observable of future state machine adds/removes. + * Returns a data feed of currently in-progress state machine infos and an observable of + * future state machine adds/removes. */ @RPCReturnsObservables fun stateMachinesFeed(): DataFeed, StateMachineUpdate> @@ -172,9 +170,7 @@ interface CordaRPCOps : RPCOps { @RPCReturnsObservables fun internalVerifiedTransactionsFeed(): DataFeed, SignedTransaction> - /** - * Returns a snapshot list of existing state machine id - recorded transaction hash mappings. - */ + /** Returns a snapshot list of existing state machine id - recorded transaction hash mappings. */ fun stateMachineRecordedTransactionMappingSnapshot(): List /** @@ -184,19 +180,19 @@ interface CordaRPCOps : RPCOps { @RPCReturnsObservables fun stateMachineRecordedTransactionMappingFeed(): DataFeed, StateMachineTransactionMapping> - /** - * Returns all parties currently visible on the network with their advertised services. - */ + /** Returns all parties currently visible on the network with their advertised services. */ fun networkMapSnapshot(): List /** - * Returns all parties currently visible on the network with their advertised services and an observable of future updates to the network. + * Returns all parties currently visible on the network with their advertised services and an observable of + * future updates to the network. */ @RPCReturnsObservables fun networkMapFeed(): DataFeed, NetworkMapCache.MapChange> /** - * Start the given flow with the given arguments. [logicType] must be annotated with [net.corda.core.flows.StartableByRPC]. + * Start the given flow with the given arguments. [logicType] must be annotated + * with [net.corda.core.flows.StartableByRPC]. */ @RPCReturnsObservables fun startFlowDynamic(logicType: Class>, vararg args: Any?): FlowHandle @@ -208,44 +204,32 @@ interface CordaRPCOps : RPCOps { @RPCReturnsObservables fun startTrackedFlowDynamic(logicType: Class>, vararg args: Any?): FlowProgressHandle - /** - * Returns Node's NodeInfo, assuming this will not change while the node is running. - */ + /** Returns Node's NodeInfo, assuming this will not change while the node is running. */ fun nodeInfo(): NodeInfo /** * Returns network's notary identities, assuming this will not change while the node is running. + * + * Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced. */ - fun notaryIdentities(): List + fun notaryIdentities(): List - /* - * Add note(s) to an existing Vault transaction - */ + /** Add note(s) to an existing Vault transaction. */ fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) - /* - * Retrieve existing note(s) for a given Vault transaction - */ + /** Retrieve existing note(s) for a given Vault transaction. */ fun getVaultTransactionNotes(txnId: SecureHash): Iterable - /** - * Checks whether an attachment with the given hash is stored on the node. - */ + /** Checks whether an attachment with the given hash is stored on the node. */ fun attachmentExists(id: SecureHash): Boolean - /** - * Download an attachment JAR by ID - */ + /** Download an attachment JAR by ID. */ fun openAttachment(id: SecureHash): InputStream - /** - * Uploads a jar to the node, returns it's hash. - */ + /** Uploads a jar to the node, returns it's hash. */ fun uploadAttachment(jar: InputStream): SecureHash - /** - * Returns the node's current time. - */ + /** Returns the node's current time. */ fun currentNodeTime(): Instant /** @@ -266,14 +250,10 @@ interface CordaRPCOps : RPCOps { * @return well known identity, if found. */ fun partyFromAnonymous(party: AbstractParty): Party? - /** - * Returns the [Party] corresponding to the given key, if found. - */ + /** Returns the [Party] corresponding to the given key, if found. */ fun partyFromKey(key: PublicKey): Party? - /** - * Returns the [Party] with the X.500 principal as it's [Party.name] - */ + /** Returns the [Party] with the X.500 principal as it's [Party.name]. */ fun partyFromX500Name(x500Name: CordaX500Name): Party? /** @@ -296,9 +276,7 @@ interface CordaRPCOps : RPCOps { */ fun nodeInfoFromParty(party: AbstractParty): NodeInfo? - /** - * Clear all network map data from local node cache. - */ + /** Clear all network map data from local node cache. */ fun clearNetworkMapCache() } diff --git a/core/src/main/kotlin/net/corda/core/node/services/CordaService.kt b/core/src/main/kotlin/net/corda/core/node/services/CordaService.kt index c1b64cdc7c..0e40e3acce 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/CordaService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/CordaService.kt @@ -7,7 +7,7 @@ import kotlin.annotation.AnnotationTarget.CLASS /** * Annotate any class that needs to be a long-lived service within the node, such as an oracle, with this annotation. - * Such a class needs to have a constructor with a single parameter of type [ServiceHub]. This construtor will be invoked + * Such a class needs to have a constructor with a single parameter of type [ServiceHub]. This constructor will be invoked * during node start to initialise the service. The service hub provided can be used to get information about the node * that may be necessary for the service. Corda services are created as singletons within the node and are available * to flows via [ServiceHub.cordaService]. diff --git a/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt b/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt index d19541eef3..8eb0a52a07 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/NetworkMapCache.kt @@ -1,12 +1,9 @@ package net.corda.core.node.services import net.corda.core.concurrent.CordaFuture -import net.corda.core.contracts.Contract import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate -import net.corda.core.internal.randomOrNull import net.corda.core.messaging.DataFeed import net.corda.core.node.NodeInfo import net.corda.core.serialization.CordaSerializable @@ -31,10 +28,14 @@ interface NetworkMapCache { data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange() } - /** A list of notary services available on the network */ + /** + * A list of notary services available on the network. + * + * Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced. + */ // TODO this list will be taken from NetworkParameters distributed by NetworkMap. - val notaryIdentities: List - /** Tracks changes to the network map cache */ + val notaryIdentities: List + /** Tracks changes to the network map cache. */ val changed: Observable /** Future to track completion of the NetworkMapService registration. */ val nodeReady: CordaFuture @@ -66,7 +67,7 @@ interface NetworkMapCache { it.legalIdentitiesAndCerts.singleOrNull { it.name == name }?.party } - /** Return all [NodeInfo]s the node currently is aware of (including ourselves). */ + /** Return all [NodeInfo]s the node currently is aware of (including ourselves). */ val allNodes: List /** @@ -81,25 +82,17 @@ interface NetworkMapCache { fun getPartyInfo(party: Party): PartyInfo? /** Gets a notary identity by the given name. */ - fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }?.party + fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name } - /** - * Returns a notary identity advertised by any of the nodes on the network (chosen at random) - * @param type Limits the result to notaries of the specified type (optional) - */ - fun getAnyNotary(): Party? = notaryIdentities.randomOrNull()?.party + /** Checks whether a given party is an advertised notary identity. */ + fun isNotary(party: Party): Boolean = party in notaryIdentities - /** Checks whether a given party is an advertised notary identity */ - fun isNotary(party: Party): Boolean = notaryIdentities.any { party == it.party } - - /** Checks whether a given party is an validating notary identity */ + /** Checks whether a given party is an validating notary identity. */ fun isValidatingNotary(party: Party): Boolean { - val notary = notaryIdentities.firstOrNull { it.party == party } ?: - throw IllegalArgumentException("No notary found with identity $party.") - return !notary.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters. + require(isNotary(party)) { "No notary found with identity $party." } + return !party.name.toString().contains("corda.notary.simple", true) // TODO This implementation will change after introducing of NetworkParameters. } - /** - * Clear all network map data from local node cache. - */ + + /** Clear all network map data from local node cache. */ fun clearNetworkMapCache() } diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 7426adade4..173c9f2a73 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -18,7 +18,7 @@ UNRELEASED * We no longer support advertising services in network map. Removed ``NodeInfo::advertisedServices``, ``serviceIdentities`` and ``notaryIdentity``. * Removed service methods from ``NetworkMapCache``: ``partyNodes``, ``networkMapNodes``, ``notaryNodes``, ``regulatorNodes``, - ``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, + ``getNodesWithService``, ``getPeersWithService``, ``getRecommended``, ``getNodesByAdvertisedServiceIdentityKey``, ``getAnyNotary``, ``notaryNode``, ``getAnyServiceOfType``. To get all known ``NodeInfo``s call ``allNodes``. * In preparation for ``NetworkMapService`` redesign and distributing notaries through ``NetworkParameters`` we added ``NetworkMapCache::notaryIdentities`` list to enable to lookup for notary parties known to the network. Related ``CordaRPCOps::notaryIdentities`` diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index c181ea39c8..8838e86368 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -56,7 +56,7 @@ class IntegrationTestingTutorial { // START 4 val issueRef = OpaqueBytes.of(0) - val notaryParty = aliceProxy.notaryIdentities().first().party + val notaryParty = aliceProxy.notaryIdentities().first() (1..10).map { i -> aliceProxy.startFlow(::CashIssueFlow, i.DOLLARS, diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java index a02b7183e2..a4e0228066 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java @@ -125,11 +125,10 @@ public class FlowCookbookJava { // We retrieve a notary from the network map. // DOCSTART 1 Party specificNotary = getServiceHub().getNetworkMapCache().getNotary(new CordaX500Name("Notary Service", "London", "UK")); - Party anyNotary = getServiceHub().getNetworkMapCache().getAnyNotary(); - // Unlike the first two methods, ``getNotaryNodes`` returns a - // ``List``. We have to extract the notary identity of - // the node we want. - Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0).getParty(); + // Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to + // specify which notary to use explicitly, as the notary list might change when new notaries are introduced, + // or old ones decommissioned. + Party firstNotary = getServiceHub().getNetworkMapCache().getNotaryIdentities().get(0); // DOCEND 1 // We may also need to identify a specific counterparty. diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index 9c4ca13eef..7812a71bdc 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -113,7 +113,7 @@ fun generateTransactions(proxy: CordaRPCOps) { sum + state.state.data.amount.quantity } val issueRef = OpaqueBytes.of(0) - val notary = proxy.notaryIdentities().first().party + val notary = proxy.notaryIdentities().first() val me = proxy.nodeInfo().legalIdentities.first() while (true) { Thread.sleep(1000) diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt index b540d11df4..0a5c060d21 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt @@ -20,7 +20,6 @@ import net.corda.finance.flows.AbstractCashFlow import net.corda.finance.flows.CashException import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow -import net.corda.testing.getDefaultNotary import java.util.* // DOCSTART CustomVaultQuery @@ -133,7 +132,8 @@ object TopupIssuerFlow { issueTo: Party, issuerPartyRef: OpaqueBytes): AbstractCashFlow.Result { // TODO: pass notary in as request parameter - val notaryParty = serviceHub.networkMapCache.getAnyNotary() ?: throw IllegalArgumentException("Couldn't find any notary in NetworkMapCache") + val notaryParty = serviceHub.networkMapCache.notaryIdentities.firstOrNull() + ?: throw IllegalArgumentException("Couldn't find any notary in NetworkMapCache") // invoke Cash subflow to issue Asset progressTracker.currentStep = ISSUING val issueCashFlow = CashIssueFlow(amount, issuerPartyRef, notaryParty) diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt index d6a361d7f5..ac13f8ac66 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt @@ -104,11 +104,10 @@ object FlowCookbook { // We retrieve the notary from the network map. // DOCSTART 1 val specificNotary: Party? = serviceHub.networkMapCache.getNotary(CordaX500Name(organisation = "Notary Service", locality = "London", country = "UK")) - val anyNotary: Party? = serviceHub.networkMapCache.getAnyNotary() - // Unlike the first two methods, ``getNotaryNodes`` returns a - // ``List``. We have to extract the notary identity of - // the node we want. - val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities[0].party + // Alternatively, we can pick an arbitrary notary from the notary list. However, it is always preferable to + // specify which notary to use explicitly, as the notary list might change when new notaries are introduced, + // or old ones decommissioned. + val firstNotary: Party = serviceHub.networkMapCache.notaryIdentities.first() // DOCEND 1 // We may also need to identify a specific counterparty. We diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt index 08e6defaf9..aa0fa394fa 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt @@ -39,7 +39,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub, val ourParties = ourKeys.map { serviceHub.identityService.partyFromKey(it) ?: throw IllegalStateException("Unable to resolve party from key") } val fungibleCriteria = QueryCriteria.FungibleAssetQueryCriteria(owner = ourParties) - val notaries = notary ?: serviceHub.networkMapCache.getAnyNotary() + val notaries = notary ?: serviceHub.networkMapCache.notaryIdentities.first() val vaultCriteria: QueryCriteria = QueryCriteria.VaultQueryCriteria(notary = listOf(notaries as AbstractParty)) val logicalExpression = builder { CashSchemaV1.PersistentCashState::currency.equal(amountRequired.token.product.currencyCode) } diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index 5f34291ead..b95f6a99ac 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -17,7 +17,6 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.seconds import net.corda.core.utilities.unwrap -import net.corda.testing.chooseIdentity // Minimal state model of a manual approval process @CordaSerializable @@ -102,7 +101,7 @@ class SubmitTradeApprovalFlow(private val tradeId: String, // Manufacture an initial state val tradeProposal = TradeApprovalContract.State(tradeId, ourIdentity, counterparty) // identify a notary. This might also be done external to the flow - val notary = serviceHub.networkMapCache.getAnyNotary() + val notary = serviceHub.networkMapCache.notaryIdentities.first() // Create the TransactionBuilder and populate with the new state. val tx = TransactionBuilder(notary).withItems( StateAndContract(tradeProposal, TRADE_APPROVAL_PROGRAM_ID), diff --git a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt index 93290c3079..9aed7cf1c9 100644 --- a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt @@ -110,7 +110,7 @@ class NodePerformanceTests { a as NodeHandle.InProcess val metricRegistry = startReporter(shutdownManager, a.node.services.monitoringService.metrics) a.rpcClientToNode().use("A", "A") { connection -> - val notary = connection.proxy.notaryIdentities().first().party + val notary = connection.proxy.notaryIdentities().first() println("ISSUING") val doneFutures = (1..100).toList().parallelStream().map { connection.proxy.startFlow(::CashIssueFlow, 1.DOLLARS, OpaqueBytes.of(0), notary).returnValue diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index 97b488130e..23fe7caf9b 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -5,6 +5,7 @@ import net.corda.core.crypto.random63BitValue import net.corda.core.identity.CordaX500Name import net.corda.core.internal.concurrent.transpose import net.corda.core.internal.elapsedTime +import net.corda.core.internal.randomOrNull import net.corda.core.internal.times import net.corda.core.messaging.MessageRecipients import net.corda.core.messaging.SingleMessageRecipient @@ -55,7 +56,8 @@ class P2PMessagingTest : NodeBasedTest() { networkMapNode.respondWith("Hello") val alice = startNode(ALICE.name).getOrThrow() val serviceAddress = alice.services.networkMapCache.run { - alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) + val notaryParty = notaryIdentities.randomOrNull()!! + alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!) } val received = alice.receiveFrom(serviceAddress).getOrThrow(10.seconds) assertThat(received).isEqualTo("Hello") @@ -100,7 +102,8 @@ class P2PMessagingTest : NodeBasedTest() { val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow() val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow() val serviceAddress = alice.services.networkMapCache.run { - alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) + val notaryParty = notaryIdentities.randomOrNull()!! + alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!) } val dummyTopic = "dummy.topic" @@ -131,7 +134,8 @@ class P2PMessagingTest : NodeBasedTest() { val distributedServiceNodes = startNotaryCluster(DISTRIBUTED_SERVICE_NAME, 2).getOrThrow() val alice = startNode(ALICE.name, configOverrides = mapOf("messageRedeliveryDelaySeconds" to 1)).getOrThrow() val serviceAddress = alice.services.networkMapCache.run { - alice.network.getAddressOfParty(getPartyInfo(getAnyNotary()!!)!!) + val notaryParty = notaryIdentities.randomOrNull()!! + alice.network.getAddressOfParty(getPartyInfo(notaryParty)!!) } val dummyTopic = "dummy.topic" diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index d37ad7f9ba..045ebcf52f 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -136,7 +136,7 @@ class SendMessageFlow(private val message: Message) : FlowLogic { + override fun notaryIdentities(): List { return services.networkMapCache.notaryIdentities } diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index 4e6d232600..788e0a94fb 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -4,7 +4,6 @@ import net.corda.core.concurrent.CordaFuture import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.bufferUntilSubscribed import net.corda.core.internal.concurrent.map @@ -73,11 +72,20 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) // As a temporary hack, just assume for now that every network has a notary service named "Notary Service" that can be looked up in the map. // This should eliminate the only required usage of services. // It is ensured on node startup when constructing a notary that the name contains "notary". - override val notaryIdentities: List get() { - return partyNodes.flatMap { it.legalIdentitiesAndCerts }.filter { - it.name.toString().contains("corda.notary", true) - }.distinct().sortedBy { it.name.toString() } // Distinct, because of distributed service nodes. - } + override val notaryIdentities: List + get() { + return partyNodes + .flatMap { + // TODO: validate notary identity certificates before loading into network map cache. + // Notary certificates have to be signed by the doorman directly + it.legalIdentities + } + .filter { + it.name.toString().contains("corda.notary", true) + } + .distinct() // Distinct, because of distributed service nodes + .sortedBy { it.name.toString() } + } init { serviceHub.database.transaction { loadFromDB() } @@ -127,9 +135,9 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) data = NetworkMapService.UpdateAcknowledge(req.mapVersion, network.myAddress).serialize().bytes) network.send(ackMessage, req.replyTo) processUpdatePush(req) - } catch(e: NodeMapError) { + } catch (e: NodeMapError) { logger.warn("Failure during node map update due to bad update: ${e.javaClass.name}") - } catch(e: Exception) { + } catch (e: Exception) { logger.error("Exception processing update from network map service", e) } } @@ -183,7 +191,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) // Fetch the network map and register for updates at the same time val req = NetworkMapService.SubscribeRequest(false, network.myAddress) // `network.getAddressOfParty(partyInfo)` is a work-around for MockNetwork and InMemoryMessaging to get rid of SingleMessageRecipient in NodeInfo. - val address = getPartyInfo(mapParty)?.let{ network.getAddressOfParty(it) } ?: + val address = getPartyInfo(mapParty)?.let { network.getAddressOfParty(it) } ?: throw IllegalArgumentException("Can't deregister for updates, don't know the party: $mapParty") val future = network.sendRequest(NetworkMapService.SUBSCRIPTION_TOPIC, req, address).map { if (it.confirmed) Unit else throw NetworkCacheError.DeregistrationFailed() @@ -201,11 +209,12 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) } } - override val allNodes: List get () = serviceHub.database.transaction { - createSession { - getAllInfos(it).map { it.toNodeInfo() } + override val allNodes: List + get () = serviceHub.database.transaction { + createSession { + getAllInfos(it).map { it.toNodeInfo() } + } } - } private fun processRegistration(reg: NodeRegistration) { // TODO: Implement filtering by sequence number, so we only accept changes that are @@ -333,7 +342,8 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) addresses = nodeInfo.addresses.map { NodeInfoSchemaV1.DBHostAndPort.fromHostAndPort(it) }, // TODO Another ugly hack with special first identity... legalIdentitiesAndCerts = nodeInfo.legalIdentitiesAndCerts.mapIndexed { idx, elem -> - NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) }, + NodeInfoSchemaV1.DBPartyAndCertificate(elem, isMain = idx == 0) + }, platformVersion = nodeInfo.platformVersion, serial = nodeInfo.serial ) diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index d818a90fae..af82b87cd3 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -80,7 +80,7 @@ class CordaRPCOpsImplTest { mockNet.runNetwork() networkMap.internals.ensureRegistered() - notary = rpc.notaryIdentities().first().party + notary = rpc.notaryIdentities().first() } @After diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 97d4d6b4e6..f4b7d79de1 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -24,6 +24,7 @@ import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.dummyCommand +import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Assert.assertTrue @@ -64,8 +65,7 @@ class ScheduledFlowTests { @Suspendable override fun call() { val scheduledState = ScheduledState(serviceHub.clock.instant(), ourIdentity, destination) - - val notary = serviceHub.networkMapCache.getAnyNotary() + val notary = serviceHub.getDefaultNotary() val builder = TransactionBuilder(notary) .addOutputState(scheduledState, DUMMY_PROGRAM_ID) .addCommand(dummyCommand(ourIdentity.owningKey)) diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index c12f39a48f..34c659fa58 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -45,7 +45,7 @@ class BankOfCordaRPCClientTest { // Kick-off actual Issuer Flow val anonymous = true - val notary = bocProxy.notaryIdentities().first().party + val notary = bocProxy.notaryIdentities().first() bocProxy.startFlow(::CashIssueAndPaymentFlow, 1000.DOLLARS, BIG_CORP_PARTY_REF, nodeBigCorporation.nodeInfo.chooseIdentity(), diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt index aaa1b17e89..f57bb5f14e 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt @@ -48,7 +48,7 @@ object AutoOfferFlow { @Suspendable override fun call(): SignedTransaction { require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } - val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. + val notary = serviceHub.networkMapCache.notaryIdentities.first() // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. // need to pick which ever party is not us val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single() progressTracker.currentStep = DEALING diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt index 11534c404c..92f0bc52f8 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt @@ -54,7 +54,7 @@ object UpdateBusinessDayFlow { * the notary or counterparty still use the old clock, so the time-window on the transaction does not validate. */ private fun getRecipients(): Iterable { - val notaryParties = serviceHub.networkMapCache.notaryIdentities.map { it.party } + val notaryParties = serviceHub.networkMapCache.notaryIdentities val peerParties = serviceHub.networkMapCache.allNodes.filter { it.legalIdentities.all { !serviceHub.networkMapCache.isNotary(it) } }.map { it.legalIdentities[0] }.sortedBy { it.name.toString() } diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt index c6c1d513df..6e3c665303 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt @@ -138,7 +138,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten node1.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) node2.internals.registerInitiatedFlow(FixingFlow.Fixer::class.java) - val notaryId = node1.rpcOps.notaryIdentities().first().party + val notaryId = node1.rpcOps.notaryIdentities().first() @InitiatingFlow class StartDealFlow(val otherParty: Party, val payload: AutoOffer) : FlowLogic() { diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt index 503310711c..c107c44578 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/Notarise.kt @@ -5,7 +5,6 @@ import net.corda.core.crypto.toStringShort import net.corda.core.identity.PartyAndCertificate import net.corda.core.messaging.CordaRPCOps import net.corda.core.messaging.startFlow -import net.corda.core.node.NodeInfo import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.getOrThrow @@ -13,7 +12,6 @@ import net.corda.notarydemo.flows.DummyIssueAndMove import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient import net.corda.testing.BOB import java.util.concurrent.Future -import kotlin.streams.asSequence fun main(args: Array) { val address = NetworkHostAndPort("localhost", 10003) @@ -26,7 +24,7 @@ fun main(args: Array) { /** Interface for using the notary demo API from a client. */ private class NotaryDemoClientApi(val rpc: CordaRPCOps) { private val notary by lazy { - val id = rpc.notaryIdentities().distinct().singleOrNull()?.party + val id = rpc.notaryIdentities().singleOrNull() checkNotNull(id) { "No unique notary identity, try cleaning the node directories." } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt index e0f0458994..a10b756319 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/api/PortfolioApi.kt @@ -254,7 +254,7 @@ class PortfolioApi(val rpc: CordaRPCOps) { val parties = rpc.networkMapSnapshot() val notaries = rpc.notaryIdentities() // TODO We are not able to filter by network map node now - val counterParties = parties.filterNot { it.legalIdentitiesAndCerts.any { it in notaries } + val counterParties = parties.filterNot { it.legalIdentities.any { it in notaries } || ownParty in it.legalIdentities } return AvailableParties( diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt index 52d4c4d733..d3816e680e 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt @@ -23,7 +23,7 @@ object IRSTradeFlow { @Suspendable override fun call(): SignedTransaction { require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } - val notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. + val notary = serviceHub.networkMapCache.notaryIdentities.first() // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. val (buyer, seller) = if (swap.buyer.second == ourIdentity.owningKey) { Pair(ourIdentity, otherParty) @@ -52,7 +52,7 @@ object IRSTradeFlow { val offer = receive(replyToParty).unwrap { it } // Automatically agree - in reality we'd vet the offer message - require(serviceHub.networkMapCache.notaryIdentities.map { it.party }.contains(offer.notary)) + require(serviceHub.networkMapCache.notaryIdentities.contains(offer.notary)) send(replyToParty, true) subFlow(TwoPartyDealFlow.Acceptor(replyToParty)) } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index 50feca8445..b5c9c5ca79 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -62,7 +62,7 @@ object SimmFlow { override fun call(): RevisionedState { logger.debug("Calling from: $ourIdentity. Sending to: $otherParty") require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } - notary = serviceHub.networkMapCache.notaryIdentities.first().party // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. + notary = serviceHub.networkMapCache.notaryIdentities.first() // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. val criteria = LinearStateQueryCriteria(participants = listOf(otherParty)) val trades = serviceHub.vaultQueryService.queryBy(criteria).states diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt index dd6fab51f6..5fdccd69af 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt @@ -18,7 +18,6 @@ import net.corda.finance.contracts.getCashBalance import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.vault.VaultSchemaV1 -import net.corda.testing.DUMMY_NOTARY import net.corda.testing.contracts.calculateRandomlySizedAmounts import net.corda.traderdemo.flow.CommercialPaperIssueFlow import net.corda.traderdemo.flow.SellerFlow @@ -46,7 +45,7 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) { val ref = OpaqueBytes.of(1) val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") - val notaryIdentity = rpc.notaryIdentities().first().party + val notaryIdentity = rpc.notaryIdentities().first() val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) rpc.startFlow(::CashIssueFlow, amount, OpaqueBytes.of(1), notaryIdentity).returnValue.getOrThrow() diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt index c7b8c61b2c..2c4cffbaf8 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt @@ -6,7 +6,6 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatedBy import net.corda.core.identity.Party import net.corda.core.internal.Emoji -import net.corda.core.node.NodeInfo import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.unwrap @@ -30,7 +29,7 @@ class BuyerFlow(val otherParty: Party) : FlowLogic() { // Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation) val amount = receive>(otherParty).unwrap { it } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } - val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party + val notary: Party = serviceHub.networkMapCache.notaryIdentities.first() val buyer = TwoPartyTradeFlow.Buyer( otherParty, notary, @@ -59,7 +58,7 @@ class BuyerFlow(val otherParty: Party) : FlowLogic() { // the state. val search = TransactionGraphSearch(serviceHub.validatedTransactions, listOf(tradeTX.tx), TransactionGraphSearch.Query(withCommandOfType = CommercialPaper.Commands.Issue::class.java, - followInputsOfType = CommercialPaper.State::class.java)) + followInputsOfType = CommercialPaper.State::class.java)) val cpIssuance = search.call().single() // Buyer will fetch the attachment from the seller automatically when it resolves the transaction. diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt index 1d6b3717ba..f0f5f91bcb 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt @@ -7,7 +7,6 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.StartableByRPC import net.corda.core.identity.Party -import net.corda.core.node.NodeInfo import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.finance.contracts.CommercialPaper @@ -40,7 +39,6 @@ class SellerFlow(private val otherParty: Party, override fun call(): SignedTransaction { progressTracker.currentStep = SELF_ISSUING - val notary: Party = serviceHub.networkMapCache.notaryIdentities[0].party val cpOwner = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, false) val commercialPaper = serviceHub.vaultQueryService.queryBy(CommercialPaper.State::class.java).states.first() diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt index e449461ab8..78d66ea45e 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/CoreTestUtils.kt @@ -163,5 +163,5 @@ inline fun amqpSpecific(reason: String, function: () -> Unit) */ fun NodeInfo.chooseIdentityAndCert(): PartyAndCertificate = legalIdentitiesAndCerts.first() fun NodeInfo.chooseIdentity(): Party = chooseIdentityAndCert().party - -fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first().party +/** Returns the identity of the first notary found on the network */ +fun ServiceHub.getDefaultNotary(): Party = networkMapCache.notaryIdentities.first() diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index eef900b1b7..1b4b9371c7 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -173,7 +173,7 @@ class ExplorerSimulation(val options: OptionSet) { private fun startNormalSimulation() { println("Running simulation mode ...") setUpRPC() - notary = aliceNode.rpc.notaryIdentities().first().party + notary = aliceNode.rpc.notaryIdentities().first() val eventGenerator = EventGenerator( parties = parties.map { it.first }, notary = notary, diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt index d92993d52a..1cfebe9554 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt @@ -156,7 +156,7 @@ class NewTransaction : Fragment() { val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef when (it) { executeButton -> when (transactionTypeCB.value) { - CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first().party, anonymous) + CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first(), anonymous) CashTransaction.Pay -> PaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), partyBChoiceBox.value.party, anonymous = anonymous) CashTransaction.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef) else -> null diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt index b914b12028..87aa80de90 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/Disruption.kt @@ -1,7 +1,6 @@ package net.corda.loadtest import net.corda.client.mock.* -import net.corda.node.services.network.NetworkMapService import org.slf4j.LoggerFactory import java.util.* import java.util.concurrent.Callable @@ -44,7 +43,7 @@ data class DisruptionSpec( */ val isNotary = { node: NodeConnection -> val notaries = node.proxy.notaryIdentities() - node.info.legalIdentitiesAndCerts.any { it in notaries } + node.info.legalIdentities.any { it in notaries } } fun ((A) -> Boolean).or(other: (A) -> Boolean): (A) -> Boolean = { this(it) || other(it) } diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt index b90fa55076..645b31ad67 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/LoadTest.kt @@ -3,7 +3,6 @@ package net.corda.loadtest import com.google.common.util.concurrent.RateLimiter import net.corda.client.mock.Generator import net.corda.core.utilities.toBase58String -import net.corda.node.services.network.NetworkMapService import net.corda.testing.driver.PortAllocation import org.slf4j.LoggerFactory import java.util.* @@ -195,7 +194,7 @@ fun runLoadTests(configuration: LoadTestConfiguration, tests: List( generate = { (nodeVaults), parallelism -> val nodeMap = simpleNodes.associateBy { it.mainIdentity } - val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first() Generator.pickN(parallelism, simpleNodes).flatMap { nodes -> Generator.sequence( nodes.map { node -> diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt index bb259d19bf..9cbdbcc462 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/SelfIssueTest.kt @@ -36,7 +36,7 @@ val selfIssueTest = LoadTest( // DOCS END 1 "Self issuing cash randomly", generate = { _, parallelism -> - val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first() val generateIssue = Generator.pickOne(simpleNodes).flatMap { node -> generateIssue(1000, USD, notaryIdentity, listOf(node.mainIdentity)).map { SelfIssueCommand(it, node) diff --git a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt index d92f8deadf..66379f6e16 100644 --- a/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt +++ b/tools/loadtest/src/main/kotlin/net/corda/loadtest/tests/StabilityTest.kt @@ -49,7 +49,7 @@ object StabilityTest { fun selfIssueTest(replication: Int) = LoadTest( "Self issuing lot of cash", generate = { _, _ -> - val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first().party + val notaryIdentity = simpleNodes[0].proxy.notaryIdentities().first() // Self issue cash is fast, its ok to flood the node with this command. val generateIssue = simpleNodes.map { issuer -> From d1e5fbb73db71e3fcb8c3f2895de27b637f9a761 Mon Sep 17 00:00:00 2001 From: Andrzej Cichocki Date: Thu, 21 Sep 2017 11:08:07 +0100 Subject: [PATCH 022/230] Ban common name. (#1568) --- node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt | 4 ++-- .../net/corda/node/services/config/NodeConfiguration.kt | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 4588efa7ed..e922bca66d 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -155,7 +155,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, * or has loaded network map data from local database */ val nodeReadyFuture: CordaFuture get() = _nodeReadyFuture - + /** A [CordaX500Name] with null common name. */ protected val myLegalName: CordaX500Name by lazy { val cert = loadKeyStore(configuration.nodeKeystore, configuration.keyStorePassword).getX509Certificate(X509Utilities.CORDA_CLIENT_CA) CordaX500Name.build(cert.subjectX500Principal).copy(commonName = null) @@ -643,7 +643,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val (id, name) = if (serviceInfo == null) { // Create node identity if service info = null - Pair("identity", myLegalName.copy(commonName = null)) + Pair("identity", myLegalName) } else { val name = serviceInfo.name ?: myLegalName.copy(commonName = serviceInfo.type.id) Pair(serviceInfo.type.id, name) diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index 67a7d8efe1..30f87dc06b 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -79,6 +79,7 @@ data class FullNodeConfiguration( rpcUsers.forEach { require(it.username.matches("\\w+".toRegex())) { "Username ${it.username} contains invalid characters" } } + require(myLegalName.commonName == null) { "Common name must be null: $myLegalName" } } fun calculateServices(): Set { From 767aaadccea9902bf065e0a340c2370b68c3c6e9 Mon Sep 17 00:00:00 2001 From: Maksymilian Pawlak <120831+m4ksio@users.noreply.github.com> Date: Thu, 21 Sep 2017 11:20:42 +0100 Subject: [PATCH 023/230] Removal of non-used webserver (#1572) --- docs/source/tutorial-cordapp.rst | 1 - 1 file changed, 1 deletion(-) diff --git a/docs/source/tutorial-cordapp.rst b/docs/source/tutorial-cordapp.rst index 9b1b965941..086c146747 100644 --- a/docs/source/tutorial-cordapp.rst +++ b/docs/source/tutorial-cordapp.rst @@ -307,7 +307,6 @@ IOUs, agree new IOUs, and see who is on the network. The nodes are running locally on the following ports: -* Controller: ``localhost:10004`` * NodeA: ``localhost:10007`` * NodeB: ``localhost:10010`` * NodeC: ``localhost:10013`` From 78500205dfb5fd05161b07e8a97f07b60464c28b Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 21 Sep 2017 11:22:01 +0100 Subject: [PATCH 024/230] Move IdentitySyncFlow into confidential-identities (#1583) --- .../main/kotlin/net/corda/confidential}/IdentitySyncFlow.kt | 3 ++- .../kotlin/net/corda/confidential}/IdentitySyncFlowTests.kt | 5 ++++- .../main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) rename {core/src/main/kotlin/net/corda/core/flows => confidential-identities/src/main/kotlin/net/corda/confidential}/IdentitySyncFlow.kt (98%) rename {core/src/test/kotlin/net/corda/core/flows => confidential-identities/src/test/kotlin/net/corda/confidential}/IdentitySyncFlowTests.kt (95%) diff --git a/core/src/main/kotlin/net/corda/core/flows/IdentitySyncFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt similarity index 98% rename from core/src/main/kotlin/net/corda/core/flows/IdentitySyncFlow.kt rename to confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt index 9e694e42e7..127e93bc3c 100644 --- a/core/src/main/kotlin/net/corda/core/flows/IdentitySyncFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt @@ -1,7 +1,8 @@ -package net.corda.core.flows +package net.corda.confidential import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.ContractState +import net.corda.core.flows.FlowLogic import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate diff --git a/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt similarity index 95% rename from core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt rename to confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt index f75635d418..5d8ca6c4f6 100644 --- a/core/src/test/kotlin/net/corda/core/flows/IdentitySyncFlowTests.kt +++ b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt @@ -1,6 +1,9 @@ -package net.corda.core.flows +package net.corda.confidential import co.paralleluniverse.fibers.Suspendable +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.InitiatedBy +import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.OpaqueBytes diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index 991a95d464..fd83370c6f 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -1,11 +1,11 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable +import net.corda.confidential.IdentitySyncFlow import net.corda.core.contracts.* import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate -import net.corda.core.node.NodeInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder From 33421bdd447cc653cf0bb5b9d536f246289ae6a7 Mon Sep 17 00:00:00 2001 From: Andras Slemmer <0slemi0@gmail.com> Date: Thu, 21 Sep 2017 12:12:25 +0100 Subject: [PATCH 025/230] CORDA-577: FlowSession porting (#1530) * Throw exception if a flow is initiated twice for the same Party * Chunk of porting * Need ReceiveTransactionFlow (cherry picked from commit 774383e) * Notaries compile * TwoPartyTrade * SimmFlow & StateRevisionFlow (cherry picked from commit da602b1) * TwoPArtyDealFlow regulator send * installCoreFlow * IRSTradeFlow UpdateBusinessDayFlow RatesFixFlow NodeInterestRates (cherry picked from commit 6c8d314) * Added recordTransaction parameter to ReceiveTransactionFlow * Some Tests, Flows * Fixed typo in record tx param * more things * Fix CollectSignatures * FlowFrameworkTests (cherry picked from commit 2c50bc3) * Fix TwoPartyTradeFlow * CustomVaultQuery (cherry picked from commit 48f88e8) * FlowsInJavaTest * WorkflowTransactionBuildTutorial * PersistentNetworkMapCacheTest * FlowCookBookJava (cherry picked from commit 9b48114) * Fix RatesFixFlow * Fix TwoPartyDealFlow to get signature of initiating side * Integration tests (cherry picked from commit dbcd965) * CordappSmokeTest (cherry picked from commit d19cbd6) * Inlined FinalityFlow * Updated uses of FinalityFlow * ContractUpgradeFlowTest passes * CollectSignaturesFlow refactor (cherry picked from commit 5e7b1a7) * Check that we are not the recipient of cash * Fix Simm demo * WorkflowTransactionBuildTutorialTest * Fix CashPaymentFlowTests * ScheduledFlowTests * FlowFrameworkTests * Add cordappPackagesToScan Driver param * FinalityFlowTests * Fix LoaderTestFlow * NodeMonitorModelTest * BankOfCordaRPCClientTest * rename to extraCordappPackagesToScan * Fixed broken merge * BankOfCordaHttpAPITest * Fix CollectSignaturesFlow * Fix annotation on DummyFlow to stop warning * Fix TraderDemoTest * Review feedback * Doc improvements and minor changes * Address some PR comments * Looping regulators into the FinalityFlow broadcast rather than sending separately in TwoPartyDealFlow. * Add Uninitiated FlowState * Add test for double initiateFlow exception * Some more s&r victims * FlowSession utilities (#1562) * Merge fix * CollectSignatureFlow can handle several signing keys * Actually handle several signing keys * update kdoc * Correct SignTransactionFlow error message * Create deprecated flows package * Add internal deprecated flows * Reverted FinalityFlow to auto-broadcast all tx participants * Move the deprecated packages into another PR --- .../corda/client/jfx/NodeMonitorModelTest.kt | 2 +- .../corda/confidential/IdentitySyncFlow.kt | 20 +-- .../corda/confidential/SwapIdentitiesFlow.kt | 15 +- .../confidential/SwapIdentitiesHandler.kt | 11 +- .../confidential/IdentitySyncFlowTests.kt | 18 +- .../flows/AbstractStateReplacementFlow.kt | 60 +++---- .../core/flows/BroadcastTransactionFlow.kt | 28 --- .../corda/core/flows/CollectSignaturesFlow.kt | 109 ++++++------ .../corda/core/flows/ContractUpgradeFlow.kt | 7 +- .../net/corda/core/flows/FinalityFlow.kt | 130 +++++--------- .../net/corda/core/flows/FlowException.kt | 2 +- .../kotlin/net/corda/core/flows/FlowLogic.kt | 6 + .../net/corda/core/flows/FlowSession.kt | 4 +- .../corda/core/flows/ManualFinalityFlow.kt | 20 --- .../net/corda/core/flows/NotaryChangeFlow.kt | 2 +- .../kotlin/net/corda/core/flows/NotaryFlow.kt | 19 +- .../core/flows/ReceiveTransactionFlow.kt | 35 ++-- .../corda/core/flows/SendTransactionFlow.kt | 21 ++- .../net/corda/core/internal/FetchDataFlow.kt | 14 +- .../net/corda/core/internal/InternalUtils.kt | 2 + .../core/internal/ResolveTransactionsFlow.kt | 8 +- .../kotlin/net/corda/core/node/ServiceHub.kt | 75 +++++++- .../corda/core/node/services/NotaryService.kt | 9 +- .../transactions/TransactionWithSignatures.kt | 7 +- .../net/corda/core/flows/FlowsInJavaTest.java | 16 +- .../net/corda/core/flows/AttachmentTests.kt | 9 +- .../core/flows/CollectSignaturesFlowTests.kt | 43 +++-- .../core/flows/ContractUpgradeFlowTest.kt | 18 +- .../net/corda/core/flows/FinalityFlowTests.kt | 14 +- .../core/flows/ManualFinalityFlowTests.kt | 67 ------- .../corda/core/flows/TestDataVendingFlow.kt | 9 +- .../internal/ResolveTransactionsFlowTest.kt | 17 +- .../AttachmentSerializationTest.kt | 30 ++-- .../corda/docs/IntegrationTestingTutorial.kt | 2 +- .../java/net/corda/docs/FlowCookbookJava.java | 57 +++--- .../net/corda/docs/CustomNotaryTutorial.kt | 7 +- .../kotlin/net/corda/docs/CustomVaultQuery.kt | 13 +- .../kotlin/net/corda/docs/FlowCookbook.kt | 45 ++--- .../corda/docs/FxTransactionBuildTutorial.kt | 58 +++--- .../docs/WorkflowTransactionBuildTutorial.kt | 20 +-- .../docs/FxTransactionBuildTutorialTest.kt | 8 +- .../WorkflowTransactionBuildTutorialTest.kt | 2 +- .../corda/finance/flows/AbstractCashFlow.kt | 4 +- .../net/corda/finance/flows/CashExitFlow.kt | 9 +- .../net/corda/finance/flows/CashIssueFlow.kt | 4 +- .../corda/finance/flows/CashPaymentFlow.kt | 13 +- .../corda/finance/flows/TwoPartyDealFlow.kt | 71 +++----- .../corda/finance/flows/TwoPartyTradeFlow.kt | 46 ++--- .../AbstractStateReplacementFlowTest.java | 6 +- .../finance/flows/CashPaymentFlowTests.kt | 5 +- .../corda/node/CordappScanningDriverTest.kt | 17 +- .../statemachine/FlowVersioningTest.kt | 10 +- .../statemachine/LargeTransactionsTest.kt | 12 +- .../services/messaging/MQSecurityTest.kt | 15 +- .../test/node/NodeStatePersistenceTests.kt | 4 +- .../net/corda/node/internal/AbstractNode.kt | 19 +- .../node/internal/cordapp/CordappLoader.kt | 27 +-- .../corda/node/services/CoreFlowHandlers.kt | 11 +- .../statemachine/FlowSessionInternal.kt | 11 +- .../statemachine/FlowStateMachineImpl.kt | 74 +++++--- .../BFTNonValidatingNotaryService.kt | 11 +- .../transactions/NonValidatingNotaryFlow.kt | 6 +- .../RaftNonValidatingNotaryService.kt | 4 +- .../RaftValidatingNotaryService.kt | 4 +- .../transactions/SimpleNotaryService.kt | 4 +- .../transactions/ValidatingNotaryFlow.kt | 5 +- .../transactions/ValidatingNotaryService.kt | 4 +- .../kotlin/net/corda/node/CordappSmokeTest.kt | 16 +- .../corda/node/cordapp/CordappLoaderTest.kt | 9 +- .../node/messaging/TwoPartyTradeFlowTests.kt | 16 +- .../services/events/ScheduledFlowTests.kt | 15 +- .../network/PersistentNetworkMapCacheTest.kt | 12 +- .../persistence/DataVendingServiceTests.kt | 116 ------------ .../services/schema/NodeSchemaServiceTest.kt | 2 +- .../statemachine/FlowFrameworkTests.kt | 165 ++++++++++++------ .../corda/attachmentdemo/AttachmentDemo.kt | 10 +- .../net/corda/bank/BankOfCordaHttpAPITest.kt | 2 +- .../corda/bank/BankOfCordaRPCClientTest.kt | 2 +- .../net/corda/irs/api/NodeInterestRates.kt | 18 +- .../net/corda/irs/flows/AutoOfferFlow.kt | 18 +- .../kotlin/net/corda/irs/flows/FixingFlow.kt | 12 +- .../net/corda/irs/flows/RatesFixFlow.kt | 9 +- .../corda/irs/flows/UpdateBusinessDayFlow.kt | 8 +- .../corda/netmap/simulation/IRSSimulation.kt | 8 +- .../netmap/simulation/IRSSimulationTest.kt | 4 +- .../net/corda/vega/flows/IRSTradeFlow.kt | 18 +- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 43 +++-- .../net/corda/vega/flows/StateRevisionFlow.kt | 12 +- .../net/corda/traderdemo/TraderDemoTest.kt | 8 +- .../net/corda/traderdemo/flow/BuyerFlow.kt | 7 +- .../flow/CommercialPaperIssueFlow.kt | 5 +- .../net/corda/traderdemo/flow/SellerFlow.kt | 5 +- .../kotlin/net/corda/testing/RPCDriver.kt | 4 +- .../kotlin/net/corda/testing/driver/Driver.kt | 21 ++- .../net/corda/verifier/VerifierDriver.kt | 4 +- 95 files changed, 956 insertions(+), 1068 deletions(-) delete mode 100644 core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt delete mode 100644 core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt delete mode 100644 core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt delete mode 100644 node/src/test/kotlin/net/corda/node/services/persistence/DataVendingServiceTests.kt diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt index 0fe1b48557..519b668cc6 100644 --- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt +++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt @@ -52,7 +52,7 @@ class NodeMonitorModelTest : DriverBasedTest() { lateinit var networkMapUpdates: Observable lateinit var newNode: (CordaX500Name) -> NodeInfo - override fun setup() = driver { + override fun setup() = driver(extraCordappPackagesToScan = listOf("net.corda.finance")) { val cashUser = User("user1", "test", permissions = setOf( startFlowPermission(), startFlowPermission(), diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt index 127e93bc3c..e5f68de31f 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt @@ -3,8 +3,8 @@ package net.corda.confidential import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.ContractState import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.identity.AbstractParty -import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate import net.corda.core.transactions.WireTransaction import net.corda.core.utilities.ProgressTracker @@ -22,10 +22,10 @@ object IdentitySyncFlow { * @return a mapping of well known identities to the confidential identities used in the transaction. */ // TODO: Can this be triggered automatically from [SendTransactionFlow] - class Send(val otherSides: Set, + class Send(val otherSideSessions: Set, val tx: WireTransaction, override val progressTracker: ProgressTracker) : FlowLogic() { - constructor(otherSide: Party, tx: WireTransaction) : this(setOf(otherSide), tx, tracker()) + constructor(otherSide: FlowSession, tx: WireTransaction) : this(setOf(otherSide), tx, tracker()) companion object { object SYNCING_IDENTITIES : ProgressTracker.Step("Syncing identities") @@ -45,9 +45,9 @@ object IdentitySyncFlow { val identityCertificates: Map = identities .map { Pair(it, serviceHub.identityService.certificateFromKey(it.owningKey)) }.toMap() - otherSides.forEach { otherSide -> - val requestedIdentities: List = sendAndReceive>(otherSide, confidentialIdentities).unwrap { req -> - require(req.all { it in identityCertificates.keys }) { "${otherSide} requested a confidential identity not part of transaction: ${tx.id}" } + otherSideSessions.forEach { otherSideSession -> + val requestedIdentities: List = otherSideSession.sendAndReceive>(confidentialIdentities).unwrap { req -> + require(req.all { it in identityCertificates.keys }) { "${otherSideSession.counterparty} requested a confidential identity not part of transaction: ${tx.id}" } req } val sendIdentities: List = requestedIdentities.map { @@ -57,7 +57,7 @@ object IdentitySyncFlow { else throw IllegalStateException("Counterparty requested a confidential identity for which we do not have the certificate path: ${tx.id}") } - send(otherSide, sendIdentities) + otherSideSession.send(sendIdentities) } } @@ -67,7 +67,7 @@ object IdentitySyncFlow { * Handle an offer to provide proof of identity (in the form of certificate paths) for confidential identities which * we do not yet know about. */ - class Receive(val otherSide: Party) : FlowLogic() { + class Receive(val otherSideSession: FlowSession) : FlowLogic() { companion object { object RECEIVING_IDENTITIES : ProgressTracker.Step("Receiving confidential identities") object RECEIVING_CERTIFICATES : ProgressTracker.Step("Receiving certificates for unknown identities") @@ -78,10 +78,10 @@ object IdentitySyncFlow { @Suspendable override fun call(): Unit { progressTracker.currentStep = RECEIVING_IDENTITIES - val allIdentities = receive>(otherSide).unwrap { it } + val allIdentities = otherSideSession.receive>().unwrap { it } val unknownIdentities = allIdentities.filter { serviceHub.identityService.partyFromAnonymous(it) == null } progressTracker.currentStep = RECEIVING_CERTIFICATES - val missingIdentities = sendAndReceive>(otherSide, unknownIdentities) + val missingIdentities = otherSideSession.sendAndReceive>(unknownIdentities) // Batch verify the identities we've received, so we know they're all correct before we start storing them in // the identity service diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt index 58ab4ea99e..7257620d19 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesFlow.kt @@ -18,10 +18,10 @@ import net.corda.core.utilities.unwrap */ @StartableByRPC @InitiatingFlow -class SwapIdentitiesFlow(private val otherSide: Party, +class SwapIdentitiesFlow(private val otherParty: Party, private val revocationEnabled: Boolean, override val progressTracker: ProgressTracker) : FlowLogic>() { - constructor(otherSide: Party) : this(otherSide, false, tracker()) + constructor(otherParty: Party) : this(otherParty, false, tracker()) companion object { object AWAITING_KEY : ProgressTracker.Step("Awaiting key") @@ -43,14 +43,15 @@ class SwapIdentitiesFlow(private val otherSide: Party, // Special case that if we're both parties, a single identity is generated val identities = LinkedHashMap() - if (serviceHub.myInfo.isLegalIdentity(otherSide)) { - identities.put(otherSide, legalIdentityAnonymous.party.anonymise()) + if (serviceHub.myInfo.isLegalIdentity(otherParty)) { + identities.put(otherParty, legalIdentityAnonymous.party.anonymise()) } else { - val anonymousOtherSide = sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> - validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) + val otherSession = initiateFlow(otherParty) + val anonymousOtherSide = otherSession.sendAndReceive(legalIdentityAnonymous).unwrap { confidentialIdentity -> + validateAndRegisterIdentity(serviceHub.identityService, otherSession.counterparty, confidentialIdentity) } identities.put(ourIdentity, legalIdentityAnonymous.party.anonymise()) - identities.put(otherSide, anonymousOtherSide.party.anonymise()) + identities.put(otherSession.counterparty, anonymousOtherSide.party.anonymise()) } return identities } diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt index 67d9e0b7b6..753d9a3927 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/SwapIdentitiesHandler.kt @@ -2,13 +2,14 @@ package net.corda.confidential import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic -import net.corda.core.identity.Party +import net.corda.core.flows.FlowSession import net.corda.core.identity.PartyAndCertificate import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.unwrap -class SwapIdentitiesHandler(val otherSide: Party, val revocationEnabled: Boolean) : FlowLogic() { - constructor(otherSide: Party) : this(otherSide, false) +class SwapIdentitiesHandler(val otherSideSession: FlowSession, val revocationEnabled: Boolean) : FlowLogic() { + constructor(otherSideSession: FlowSession) : this(otherSideSession, false) + companion object { object SENDING_KEY : ProgressTracker.Step("Sending key") } @@ -20,8 +21,8 @@ class SwapIdentitiesHandler(val otherSide: Party, val revocationEnabled: Boolean val revocationEnabled = false progressTracker.currentStep = SENDING_KEY val legalIdentityAnonymous = serviceHub.keyManagementService.freshKeyAndCert(ourIdentityAndCert, revocationEnabled) - sendAndReceive(otherSide, legalIdentityAnonymous).unwrap { confidentialIdentity -> - SwapIdentitiesFlow.validateAndRegisterIdentity(serviceHub.identityService, otherSide, confidentialIdentity) + otherSideSession.sendAndReceive(legalIdentityAnonymous).unwrap { confidentialIdentity -> + SwapIdentitiesFlow.validateAndRegisterIdentity(serviceHub.identityService, otherSideSession.counterparty, confidentialIdentity) } } } \ No newline at end of file diff --git a/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt index 5d8ca6c4f6..867931718b 100644 --- a/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt +++ b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt @@ -2,6 +2,7 @@ package net.corda.confidential import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party @@ -12,11 +13,7 @@ import net.corda.core.utilities.unwrap import net.corda.finance.DOLLARS import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashIssueAndPaymentFlow -import net.corda.testing.ALICE -import net.corda.testing.BOB -import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.chooseIdentity -import net.corda.testing.getDefaultNotary +import net.corda.testing.* import net.corda.testing.node.MockNetwork import org.junit.After import org.junit.Before @@ -75,19 +72,20 @@ class IdentitySyncFlowTests { class Initiator(val otherSide: Party, val tx: WireTransaction): FlowLogic() { @Suspendable override fun call(): Boolean { - subFlow(IdentitySyncFlow.Send(otherSide, tx)) + val session = initiateFlow(otherSide) + subFlow(IdentitySyncFlow.Send(session, tx)) // Wait for the counterparty to indicate they're done - return receive(otherSide).unwrap { it } + return session.receive().unwrap { it } } } @InitiatedBy(IdentitySyncFlowTests.Initiator::class) - class Receive(val otherSide: Party): FlowLogic() { + class Receive(val otherSideSession: FlowSession): FlowLogic() { @Suspendable override fun call() { - subFlow(IdentitySyncFlow.Receive(otherSide)) + subFlow(IdentitySyncFlow.Receive(otherSideSession)) // Notify the initiator that we've finished syncing - send(otherSide, true) + otherSideSession.send(true) } } } \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt b/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt index 323669cffc..44e3dfe982 100644 --- a/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/AbstractStateReplacementFlow.kt @@ -6,13 +6,12 @@ import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateRef import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.isFulfilledBy -import net.corda.core.identity.Party +import net.corda.core.identity.AbstractParty import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.UntrustworthyData import net.corda.core.utilities.unwrap -import java.security.PublicKey /** * Abstract flow to be used for replacing one state with another, for example when changing the notary of a state. @@ -33,10 +32,8 @@ abstract class AbstractStateReplacementFlow { * The assembled transaction for upgrading a contract. * * @param stx signed transaction to do the upgrade. - * @param participants the parties involved in the upgrade transaction. - * @param myKey key */ - data class UpgradeTx(val stx: SignedTransaction, val participants: Iterable, val myKey: PublicKey) + data class UpgradeTx(val stx: SignedTransaction) /** * The [Instigator] assembles the transaction for state replacement and sends out change proposals to all participants @@ -62,15 +59,11 @@ abstract class AbstractStateReplacementFlow { @Suspendable @Throws(StateReplacementException::class) override fun call(): StateAndRef { - val (stx, participantKeys, myKey) = assembleTx() - + val (stx) = assembleTx() + val participantSessions = getParticipantSessions() progressTracker.currentStep = SIGNING - val signatures = if (participantKeys.singleOrNull() == myKey) { - getNotarySignatures(stx) - } else { - collectSignatures(participantKeys - myKey, stx) - } + val signatures = collectSignatures(participantSessions, stx) val finalTx = stx + signatures serviceHub.recordTransactions(finalTx) @@ -89,35 +82,38 @@ abstract class AbstractStateReplacementFlow { /** * Build the upgrade transaction. * - * @return a triple of the transaction, the public keys of all participants, and the participating public key of - * this node. + * @return the transaction */ abstract protected fun assembleTx(): UpgradeTx - @Suspendable - private fun collectSignatures(participants: Iterable, stx: SignedTransaction): List { - // In identity service we record all identities we know about from network map. - val parties = participants.map { - serviceHub.identityService.partyFromKey(it) ?: - throw IllegalStateException("Participant $it to state $originalState not found on the network") - } + /** + * Initiate sessions with parties we want signatures from. + */ + open fun getParticipantSessions(): List>> { + return serviceHub.excludeMe(serviceHub.groupAbstractPartyByWellKnownParty(originalState.state.data.participants)).map { initiateFlow(it.key) to it.value } + } - val participantSignatures = parties.map { getParticipantSignature(it, stx) } + @Suspendable + private fun collectSignatures(sessions: List>>, stx: SignedTransaction): List { + val participantSignatures = sessions.map { getParticipantSignature(it.first, it.second, stx) } val allPartySignedTx = stx + participantSignatures val allSignatures = participantSignatures + getNotarySignatures(allPartySignedTx) - parties.forEach { send(it, allSignatures) } + sessions.forEach { it.first.send(allSignatures) } return allSignatures } @Suspendable - private fun getParticipantSignature(party: Party, stx: SignedTransaction): TransactionSignature { + private fun getParticipantSignature(session: FlowSession, party: List, stx: SignedTransaction): TransactionSignature { + require(party.size == 1) { + "We do not currently support multiple signatures from the same party ${session.counterparty}: $party" + } val proposal = Proposal(originalState.ref, modification) - subFlow(SendTransactionFlow(party, stx)) - return sendAndReceive(party, proposal).unwrap { - check(party.owningKey.isFulfilledBy(it.by)) { "Not signed by the required participant" } + subFlow(SendTransactionFlow(session, stx)) + return session.sendAndReceive(proposal).unwrap { + check(party.single().owningKey.isFulfilledBy(it.by)) { "Not signed by the required participant" } it.verify(stx.id) it } @@ -136,9 +132,9 @@ abstract class AbstractStateReplacementFlow { // Type parameter should ideally be Unit but that prevents Java code from subclassing it (https://youtrack.jetbrains.com/issue/KT-15964). // We use Void? instead of Unit? as that's what you'd use in Java. - abstract class Acceptor(val otherSide: Party, + abstract class Acceptor(val initiatingSession: FlowSession, override val progressTracker: ProgressTracker = Acceptor.tracker()) : FlowLogic() { - constructor(otherSide: Party) : this(otherSide, Acceptor.tracker()) + constructor(initiatingSession: FlowSession) : this(initiatingSession, Acceptor.tracker()) companion object { object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal") object APPROVING : ProgressTracker.Step("State replacement approved") @@ -151,9 +147,9 @@ abstract class AbstractStateReplacementFlow { override fun call(): Void? { progressTracker.currentStep = VERIFYING // We expect stx to have insufficient signatures here - val stx = subFlow(ReceiveTransactionFlow(otherSide, checkSufficientSignatures = false)) + val stx = subFlow(ReceiveTransactionFlow(initiatingSession, checkSufficientSignatures = false)) checkMySignatureRequired(stx) - val maybeProposal: UntrustworthyData> = receive(otherSide) + val maybeProposal: UntrustworthyData> = initiatingSession.receive() maybeProposal.unwrap { verifyProposal(stx, it) } @@ -166,7 +162,7 @@ abstract class AbstractStateReplacementFlow { progressTracker.currentStep = APPROVING val mySignature = sign(stx) - val swapSignatures = sendAndReceive>(otherSide, mySignature) + val swapSignatures = initiatingSession.sendAndReceive>(mySignature) // TODO: This step should not be necessary, as signatures are re-checked in verifyRequiredSignatures. val allSignatures = swapSignatures.unwrap { signatures -> diff --git a/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt deleted file mode 100644 index 4aada740a4..0000000000 --- a/core/src/main/kotlin/net/corda/core/flows/BroadcastTransactionFlow.kt +++ /dev/null @@ -1,28 +0,0 @@ -package net.corda.core.flows - -import co.paralleluniverse.fibers.Suspendable -import net.corda.core.identity.Party -import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.NonEmptySet - -/** - * Notify the specified parties about a transaction. The remote peers will download this transaction and its - * dependency graph, verifying them all. The flow returns when all peers have acknowledged the transactions - * as valid. Normally you wouldn't use this directly, it would be called via [FinalityFlow]. - * - * @param notarisedTransaction transaction which has been notarised (if needed) and is ready to notify nodes about. - * @param participants a list of participants involved in the transaction. - * @return a list of participants who were successfully notified of the transaction. - */ -@InitiatingFlow -class BroadcastTransactionFlow(val notarisedTransaction: SignedTransaction, - val participants: NonEmptySet) : FlowLogic() { - @Suspendable - override fun call() { - // TODO: Messaging layer should handle this broadcast for us - participants.filter { !serviceHub.myInfo.isLegalIdentity(it) }.forEach { participant -> - // SendTransactionFlow allows otherParty to access our data to resolve the transaction. - subFlow(SendTransactionFlow(participant, notarisedTransaction)) - } - } -} diff --git a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt index 559b55807b..aee41e3b4b 100644 --- a/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/CollectSignaturesFlow.kt @@ -3,8 +3,6 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.isFulfilledBy -import net.corda.core.utilities.toBase58String -import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.node.ServiceHub import net.corda.core.transactions.SignedTransaction @@ -57,21 +55,25 @@ import java.security.PublicKey * val stx = subFlow(CollectSignaturesFlow(ptx)) * * @param partiallySignedTx Transaction to collect the remaining signatures for + * @param sessionsToCollectFrom A session for every party we need to collect a signature from. Must be an exact match. * @param myOptionalKeys set of keys in the transaction which are owned by this node. This includes keys used on commands, not * just in the states. If null, the default well known identity of the node is used. */ // TODO: AbstractStateReplacementFlow needs updating to use this flow. class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: SignedTransaction, + val sessionsToCollectFrom: Collection, val myOptionalKeys: Iterable?, override val progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : FlowLogic() { - @JvmOverloads constructor(partiallySignedTx: SignedTransaction, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, null, progressTracker) + @JvmOverloads constructor(partiallySignedTx: SignedTransaction, sessionsToCollectFrom: Collection, progressTracker: ProgressTracker = CollectSignaturesFlow.tracker()) : this(partiallySignedTx, sessionsToCollectFrom, null, progressTracker) companion object { object COLLECTING : ProgressTracker.Step("Collecting signatures from counter-parties.") object VERIFYING : ProgressTracker.Step("Verifying collected signatures.") + @JvmStatic fun tracker() = ProgressTracker(COLLECTING, VERIFYING) // TODO: Make the progress tracker adapt to the number of counter-parties to collect from. + } @Suspendable override fun call(): SignedTransaction { @@ -100,8 +102,15 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si // If the unsigned counter-parties list is empty then we don't need to collect any more signatures here. if (unsigned.isEmpty()) return partiallySignedTx + val partyToKeysMap = serviceHub.groupPublicKeysByWellKnownParty(unsigned) + // Check that we have a session for all parties. No more, no less. + require(sessionsToCollectFrom.map { it.counterparty }.toSet() == partyToKeysMap.keys) { + "The Initiator of CollectSignaturesFlow must pass in exactly the sessions required to sign the transaction." + } // Collect signatures from all counter-parties and append them to the partially signed transaction. - val counterpartySignatures = keysToParties(unsigned).map { collectSignature(it.first, it.second) } + val counterpartySignatures = sessionsToCollectFrom.flatMap { session -> + subFlow(CollectSignatureFlow(partiallySignedTx, session, partyToKeysMap[session.counterparty]!!)) + } val stx = partiallySignedTx + counterpartySignatures // Verify all but the notary's signature if the transaction requires a notary, otherwise verify all signatures. @@ -110,40 +119,38 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si return stx } +} - /** - * Lookup the [Party] object for each [PublicKey] using the [ServiceHub.identityService]. - * - * @return a pair of the well known identity to contact for a signature, and the public key that party should sign - * with (this may belong to a confidential identity). - */ - @Suspendable private fun keysToParties(keys: Collection): List> = keys.map { - val party = serviceHub.identityService.partyFromAnonymous(AnonymousParty(it)) - ?: throw IllegalStateException("Party ${it.toBase58String()} not found on the network.") - Pair(party, it) - } - - // DOCSTART 1 - /** - * Get and check the required signature. - * - * @param counterparty the party to request a signature from. - * @param signingKey the key the party should use to sign the transaction. - */ - @Suspendable private fun collectSignature(counterparty: Party, signingKey: PublicKey): TransactionSignature { +// DOCSTART 1 +/** + * Get and check the required signature. + * + * @param partiallySignedTx the transaction to sign. + * @param session the [FlowSession] to connect to to get the signature. + * @param signingKeys the list of keys the party should use to sign the transaction. + */ +@Suspendable +class CollectSignatureFlow(val partiallySignedTx: SignedTransaction, val session: FlowSession, val signingKeys: List) : FlowLogic>() { + constructor(partiallySignedTx: SignedTransaction, session: FlowSession, vararg signingKeys: PublicKey) : + this(partiallySignedTx, session, listOf(*signingKeys)) + @Suspendable + override fun call(): List { // SendTransactionFlow allows counterparty to access our data to resolve the transaction. - subFlow(SendTransactionFlow(counterparty, partiallySignedTx)) + subFlow(SendTransactionFlow(session, partiallySignedTx)) // Send the key we expect the counterparty to sign with - this is important where they may have several // keys to sign with, as it makes it faster for them to identify the key to sign with, and more straight forward // for us to check we have the expected signature returned. - send(counterparty, signingKey) - return receive(counterparty).unwrap { - require(signingKey.isFulfilledBy(it.by)) { "Not signed by the required signing key." } - it + session.send(signingKeys) + return session.receive>().unwrap { signatures -> + require(signatures.size == signingKeys.size) { "Need signature for each signing key" } + signatures.forEachIndexed { index, signature -> + require(signingKeys[index].isFulfilledBy(signature.by)) { "Not signed by the required signing key." } + } + signatures } } - // DOCEND 1 } +// DOCEND 1 /** * The [SignTransactionFlow] should be called in response to the [CollectSignaturesFlow]. It automates the signing of @@ -159,15 +166,15 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si * - Subclass [SignTransactionFlow] - this can be done inside an existing flow (as shown below) * - Override the [checkTransaction] method to add some custom verification logic * - Call the flow via [FlowLogic.subFlow] - * - The flow returns the fully signed transaction once it has been committed to the ledger + * - The flow returns the transaction signed with the additional signature. * * Example - checking and signing a transaction involving a [net.corda.core.contracts.DummyContract], see * CollectSignaturesFlowTests.kt for further examples: * - * class Responder(val otherParty: Party): FlowLogic() { + * class Responder(val otherPartySession: FlowSession): FlowLogic() { * @Suspendable override fun call(): SignedTransaction { * // [SignTransactionFlow] sub-classed as a singleton object. - * val flow = object : SignTransactionFlow(otherParty) { + * val flow = object : SignTransactionFlow(otherPartySession) { * @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat { * val tx = stx.tx * val magicNumberState = tx.outputs.single().data as DummyContract.MultiOwnerState @@ -182,9 +189,9 @@ class CollectSignaturesFlow @JvmOverloads constructor (val partiallySignedTx: Si * } * } * - * @param otherParty The counter-party which is providing you a transaction to sign. + * @param otherSideSession The session which is providing you a transaction to sign. */ -abstract class SignTransactionFlow(val otherParty: Party, +abstract class SignTransactionFlow(val otherSideSession: FlowSession, override val progressTracker: ProgressTracker = SignTransactionFlow.tracker()) : FlowLogic() { companion object { @@ -192,23 +199,24 @@ abstract class SignTransactionFlow(val otherParty: Party, object VERIFYING : ProgressTracker.Step("Verifying transaction proposal.") object SIGNING : ProgressTracker.Step("Signing transaction proposal.") + @JvmStatic fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING) } @Suspendable override fun call(): SignedTransaction { progressTracker.currentStep = RECEIVING // Receive transaction and resolve dependencies, check sufficient signatures is disabled as we don't have all signatures. - val stx = subFlow(ReceiveTransactionFlow(otherParty, checkSufficientSignatures = false)) + val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false)) // Receive the signing key that the party requesting the signature expects us to sign with. Having this provided // means we only have to check we own that one key, rather than matching all keys in the transaction against all // keys we own. - val signingKey = receive(otherParty).unwrap { + val signingKeys = otherSideSession.receive>().unwrap { keys -> // TODO: We should have a faster way of verifying we own a single key - serviceHub.keyManagementService.filterMyKeys(listOf(it)).single() + serviceHub.keyManagementService.filterMyKeys(keys) } progressTracker.currentStep = VERIFYING // Check that the Responder actually needs to sign. - checkMySignatureRequired(stx, signingKey) + checkMySignaturesRequired(stx, signingKeys) // Check the signatures which have already been provided. Usually the Initiators and possibly an Oracle's. checkSignatures(stx) stx.tx.toLedgerTransaction(serviceHub).verify() @@ -223,18 +231,19 @@ abstract class SignTransactionFlow(val otherParty: Party, } // Sign and send back our signature to the Initiator. progressTracker.currentStep = SIGNING - val mySignature = serviceHub.createSignature(stx, signingKey) - send(otherParty, mySignature) + val mySignatures = signingKeys.map { key -> + serviceHub.createSignature(stx, key) + } + otherSideSession.send(mySignatures) - // Return the fully signed transaction once it has been committed. - return waitForLedgerCommit(stx.id) + // Return the additionally signed transaction. + return stx + mySignatures } @Suspendable private fun checkSignatures(stx: SignedTransaction) { - val signingIdentities = stx.sigs.map(TransactionSignature::by).mapNotNull(serviceHub.identityService::partyFromKey) - val signingWellKnownIdentities = signingIdentities.mapNotNull(serviceHub.identityService::partyFromAnonymous) - require(otherParty in signingWellKnownIdentities) { - "The Initiator of CollectSignaturesFlow must have signed the transaction. Found ${signingWellKnownIdentities}, expected ${otherParty}" + val signingWellKnownIdentities = serviceHub.groupPublicKeysByWellKnownParty(stx.sigs.map(TransactionSignature::by)) + require(otherSideSession.counterparty in signingWellKnownIdentities) { + "The Initiator of CollectSignaturesFlow must have signed the transaction. Found ${signingWellKnownIdentities}, expected ${otherSideSession}" } val signed = stx.sigs.map { it.by } val allSigners = stx.tx.requiredSigningKeys @@ -266,9 +275,9 @@ abstract class SignTransactionFlow(val otherParty: Party, @Throws(FlowException::class) abstract protected fun checkTransaction(stx: SignedTransaction) - @Suspendable private fun checkMySignatureRequired(stx: SignedTransaction, signingKey: PublicKey) { - require(signingKey in stx.tx.requiredSigningKeys) { - "Party is not a participant for any of the input states of transaction ${stx.id}" + @Suspendable private fun checkMySignaturesRequired(stx: SignedTransaction, signingKeys: Iterable) { + require(signingKeys.all { it in stx.tx.requiredSigningKeys }) { + "A signature was requested for a key that isn't part of the required signing keys for transaction ${stx.id}" } } } diff --git a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt index b1e32b4be4..ec1c6a307c 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt @@ -2,7 +2,6 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* -import net.corda.core.identity.Party import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder @@ -87,13 +86,13 @@ object ContractUpgradeFlow { // TODO: We need a much faster way of finding our key in the transaction val myKey = serviceHub.keyManagementService.filterMyKeys(participantKeys).single() val stx = serviceHub.signInitialTransaction(baseTx, myKey) - return AbstractStateReplacementFlow.UpgradeTx(stx, participantKeys, myKey) + return AbstractStateReplacementFlow.UpgradeTx(stx) } } @StartableByRPC @InitiatedBy(ContractUpgradeFlow.Initiator::class) - class Acceptor(otherSide: Party) : AbstractStateReplacementFlow.Acceptor>>(otherSide) { + class Acceptor(otherSide: FlowSession) : AbstractStateReplacementFlow.Acceptor>>(otherSide) { companion object { @JvmStatic @@ -133,7 +132,7 @@ object ContractUpgradeFlow { val proposedTx = stx.tx val expectedTx = ContractUpgradeFlow.Initiator.assembleBareTx(oldStateAndRef, proposal.modification, proposedTx.privacySalt).toWireTransaction() requireThat { - "The instigator is one of the participants" using (otherSide in oldStateAndRef.state.data.participants) + "The instigator is one of the participants" using (initiatingSession.counterparty in oldStateAndRef.state.data.participants) "The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" using (proposal.modification.name == authorisedUpgrade) "The proposed tx matches the expected tx for this upgrade" using (proposedTx == expectedTx) } diff --git a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt index 847475ae75..cc5c1962d6 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FinalityFlow.kt @@ -1,46 +1,35 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable -import net.corda.core.contracts.ContractState -import net.corda.core.contracts.StateRef -import net.corda.core.contracts.TransactionState import net.corda.core.crypto.isFulfilledBy -import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party -import net.corda.core.internal.ResolveTransactionsFlow -import net.corda.core.node.ServiceHub import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.NonEmptySet import net.corda.core.utilities.ProgressTracker -import net.corda.core.utilities.toNonEmptySet /** - * Verifies the given transactions, then sends them to the named notary. If the notary agrees that the transactions - * are acceptable then they are from that point onwards committed to the ledger, and will be written through to the - * vault. Additionally they will be distributed to the parties reflected in the participants list of the states. + * Verifies the given transaction, then sends it to the named notary. If the notary agrees that the transaction + * is acceptable then it is from that point onwards committed to the ledger, and will be written through to the + * vault. Additionally it will be distributed to the parties reflected in the participants list of the states. * - * The transactions will be topologically sorted before commitment to ensure that dependencies are committed before - * dependers, so you don't need to do this yourself. + * The transaction is expected to have already been resolved: if its dependencies are not available in local + * storage, verification will fail. It must have signatures from all necessary parties other than the notary. * - * The transactions are expected to have already been resolved: if their dependencies are not available in local - * storage or within the given set, verification will fail. They must have signatures from all necessary parties - * other than the notary. + * If specified, the extra recipients are sent the given transaction. The base set of parties to inform are calculated + * from the contract-given set of participants. * - * If specified, the extra recipients are sent all the given transactions. The base set of parties to inform of each - * transaction are calculated on a per transaction basis from the contract-given set of participants. + * The flow returns the same transaction but with the additional signatures from the notary. * - * The flow returns the same transactions, in the same order, with the additional signatures. - * - * @param transactions What to commit. + * @param transaction What to commit. * @param extraRecipients A list of additional participants to inform of the transaction. */ -open class FinalityFlow(val transactions: Iterable, +@InitiatingFlow +class FinalityFlow(val transaction: SignedTransaction, private val extraRecipients: Set, - override val progressTracker: ProgressTracker) : FlowLogic>() { - constructor(transaction: SignedTransaction, extraParticipants: Set) : this(listOf(transaction), extraParticipants, tracker()) - constructor(transaction: SignedTransaction) : this(listOf(transaction), emptySet(), tracker()) - constructor(transaction: SignedTransaction, progressTracker: ProgressTracker) : this(listOf(transaction), emptySet(), progressTracker) + override val progressTracker: ProgressTracker) : FlowLogic() { + constructor(transaction: SignedTransaction, extraParticipants: Set) : this(transaction, extraParticipants, tracker()) + constructor(transaction: SignedTransaction) : this(transaction, emptySet(), tracker()) + constructor(transaction: SignedTransaction, progressTracker: ProgressTracker) : this(transaction, emptySet(), progressTracker) companion object { object NOTARISING : ProgressTracker.Step("Requesting signature by notary service") { @@ -49,52 +38,41 @@ open class FinalityFlow(val transactions: Iterable, object BROADCASTING : ProgressTracker.Step("Broadcasting transaction to participants") - // TODO: Make all tracker() methods @JvmStatic + @JvmStatic fun tracker() = ProgressTracker(NOTARISING, BROADCASTING) } @Suspendable @Throws(NotaryException::class) - override fun call(): List { + override fun call(): SignedTransaction { // Note: this method is carefully broken up to minimize the amount of data reachable from the stack at // the point where subFlow is invoked, as that minimizes the checkpointing work to be done. // // Lookup the resolved transactions and use them to map each signed transaction to the list of participants. // Then send to the notary if needed, record locally and distribute. + val parties = getPartiesToSend(verifyTx()) progressTracker.currentStep = NOTARISING - val notarisedTxns: List>> = resolveDependenciesOf(transactions) - .map { (stx, ltx) -> Pair(notariseAndRecord(stx), lookupParties(ltx)) } + val notarised = notariseAndRecord() // Each transaction has its own set of recipients, but extra recipients get them all. progressTracker.currentStep = BROADCASTING - for ((stx, parties) in notarisedTxns) { - val participants = (parties + extraRecipients).filter { !serviceHub.myInfo.isLegalIdentity(it) }.toSet() - if (participants.isNotEmpty()) { - broadcastTransaction(stx, participants.toNonEmptySet()) + for (party in parties) { + if (!serviceHub.myInfo.isLegalIdentity(party)) { + val session = initiateFlow(party) + subFlow(SendTransactionFlow(session, notarised)) } } - return notarisedTxns.map { it.first } - } - /** - * Broadcast a transaction to the participants. By default calls [BroadcastTransactionFlow], however can be - * overridden for more complex transaction delivery protocols (for example where not all parties know each other). - * - * @param participants the participants to send the transaction to. This is expected to include extra participants - * and exclude the local node. - */ - @Suspendable - open protected fun broadcastTransaction(stx: SignedTransaction, participants: NonEmptySet) { - subFlow(BroadcastTransactionFlow(stx, participants)) + return notarised } @Suspendable - private fun notariseAndRecord(stx: SignedTransaction): SignedTransaction { - val notarised = if (needsNotarySignature(stx)) { - val notarySignatures = subFlow(NotaryFlow.Client(stx)) - stx + notarySignatures + private fun notariseAndRecord(): SignedTransaction { + val notarised = if (needsNotarySignature(transaction)) { + val notarySignatures = subFlow(NotaryFlow.Client(transaction)) + transaction + notarySignatures } else { - stx + transaction } serviceHub.recordTransactions(notarised) return notarised @@ -112,47 +90,17 @@ open class FinalityFlow(val transactions: Iterable, return !(notaryKey?.isFulfilledBy(signers) ?: false) } - /** - * Resolve the parties involved in a transaction. - * - * The default implementation throws an exception if an unknown party is encountered. - */ - open protected fun lookupParties(ltx: LedgerTransaction): Set { - // Calculate who is meant to see the results based on the participants involved. - return extractParticipants(ltx).map { - serviceHub.identityService.partyFromAnonymous(it) - ?: throw IllegalArgumentException("Could not resolve well known identity of participant $it") - }.toSet() + private fun getPartiesToSend(ltx: LedgerTransaction): Set { + val participants = ltx.outputStates.flatMap { it.participants } + ltx.inputStates.flatMap { it.participants } + return serviceHub.groupAbstractPartyByWellKnownParty(participants).keys + extraRecipients } - /** - * Helper function to extract all participants from a ledger transaction. Intended to help implement [lookupParties] - * overriding functions. - */ - protected fun extractParticipants(ltx: LedgerTransaction): List { - return ltx.outputStates.flatMap { it.participants } + ltx.inputStates.flatMap { it.participants } - } - - private fun resolveDependenciesOf(signedTransactions: Iterable): List> { - // Make sure the dependencies come before the dependers. - val sorted = ResolveTransactionsFlow.topologicalSort(signedTransactions.toList()) - // Build a ServiceHub that consults the argument list as well as what's in local tx storage so uncommitted - // transactions can depend on each other. - val augmentedLookup = object : ServiceHub by serviceHub { - val hashToTx = sorted.associateBy { it.id } - override fun loadState(stateRef: StateRef): TransactionState<*> { - val provided: TransactionState? = hashToTx[stateRef.txhash]?.let { it.tx.outputs[stateRef.index] } - return provided ?: super.loadState(stateRef) - } - } - // Load and verify each transaction. - return sorted.map { stx -> - val notary = stx.tx.notary - // The notary signature(s) are allowed to be missing but no others. - if (notary != null) stx.verifySignaturesExcept(notary.owningKey) else stx.verifyRequiredSignatures() - val ltx = stx.toLedgerTransaction(augmentedLookup, false) - ltx.verify() - stx to ltx - } + private fun verifyTx(): LedgerTransaction { + val notary = transaction.tx.notary + // The notary signature(s) are allowed to be missing but no others. + if (notary != null) transaction.verifySignaturesExcept(notary.owningKey) else transaction.verifyRequiredSignatures() + val ltx = transaction.toLedgerTransaction(serviceHub, false) + ltx.verify() + return ltx } } diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowException.kt b/core/src/main/kotlin/net/corda/core/flows/FlowException.kt index 4e20320883..33251020f8 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowException.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowException.kt @@ -7,7 +7,7 @@ import net.corda.core.CordaRuntimeException /** * Exception which can be thrown by a [FlowLogic] at any point in its logic to unexpectedly bring it to a permanent end. * The exception will propagate to all counterparty flows and will be thrown on their end the next time they wait on a - * [FlowLogic.receive] or [FlowLogic.sendAndReceive]. Any flow which no longer needs to do a receive, or has already ended, + * [FlowSession.receive] or [FlowSession.sendAndReceive]. Any flow which no longer needs to do a receive, or has already ended, * will not receive the exception (if this is required then have them wait for a confirmation message). * * [FlowException] (or a subclass) can be a valid expected response from a flow, particularly ones which act as a service. diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt b/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt index 91269be2d3..2137b5ee03 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowLogic.kt @@ -137,11 +137,17 @@ abstract class FlowLogic { internal inline fun sendAndReceiveWithRetry(otherParty: Party, payload: Any): UntrustworthyData { return stateMachine.sendAndReceive(R::class.java, otherParty, payload, flowUsedForSessions, retrySend = true) } + @Suspendable internal fun FlowSession.sendAndReceiveWithRetry(receiveType: Class, payload: Any): UntrustworthyData { return stateMachine.sendAndReceive(receiveType, counterparty, payload, flowUsedForSessions, retrySend = true) } + @Suspendable + internal inline fun FlowSession.sendAndReceiveWithRetry(payload: Any): UntrustworthyData { + return stateMachine.sendAndReceive(R::class.java, counterparty, payload, flowUsedForSessions, retrySend = true) + } + /** * Suspends until the specified [otherParty] sends us a message of type [R]. * diff --git a/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt b/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt index e3423bd302..9c2e5425d6 100644 --- a/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt +++ b/core/src/main/kotlin/net/corda/core/flows/FlowSession.kt @@ -23,12 +23,12 @@ import net.corda.core.utilities.UntrustworthyData * * If it's an InitiatedBy flow: * - * Change the constructor to take an initiatingSession: FlowSession instead of a counterparty: Party + * Change the constructor to take an otherSideSession: FlowSession instead of a counterparty: Party * Then look for usages of the deprecated functions and change them to use the FlowSession * For example: * send(counterparty, something) * will become - * initiatingSession.send(something) + * otherSideSession.send(something) */ abstract class FlowSession { abstract val counterparty: Party diff --git a/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt deleted file mode 100644 index 16c792266c..0000000000 --- a/core/src/main/kotlin/net/corda/core/flows/ManualFinalityFlow.kt +++ /dev/null @@ -1,20 +0,0 @@ -package net.corda.core.flows - -import net.corda.core.identity.Party -import net.corda.core.transactions.LedgerTransaction -import net.corda.core.transactions.SignedTransaction -import net.corda.core.utilities.ProgressTracker - -/** - * Alternative finality flow which only does not attempt to take participants from the transaction, but instead all - * participating parties must be provided manually. - * - * @param transactions What to commit. - * @param recipients List of participants to inform of the transaction. - */ -class ManualFinalityFlow(transactions: Iterable, - recipients: Set, - progressTracker: ProgressTracker) : FinalityFlow(transactions, recipients, progressTracker) { - constructor(transaction: SignedTransaction, extraParticipants: Set) : this(listOf(transaction), extraParticipants, tracker()) - override fun lookupParties(ltx: LedgerTransaction): Set = emptySet() -} diff --git a/core/src/main/kotlin/net/corda/core/flows/NotaryChangeFlow.kt b/core/src/main/kotlin/net/corda/core/flows/NotaryChangeFlow.kt index a861ad8f84..26525204aa 100644 --- a/core/src/main/kotlin/net/corda/core/flows/NotaryChangeFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/NotaryChangeFlow.kt @@ -43,7 +43,7 @@ class NotaryChangeFlow( val mySignature = serviceHub.keyManagementService.sign(signableData, myKey) val stx = SignedTransaction(tx, listOf(mySignature)) - return AbstractStateReplacementFlow.UpgradeTx(stx, participantKeys, myKey) + return AbstractStateReplacementFlow.UpgradeTx(stx) } /** Resolves the encumbrance state chain for the given [state] */ diff --git a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt index e2a2ba1f62..f738df62be 100644 --- a/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/NotaryFlow.kt @@ -65,16 +65,17 @@ class NotaryFlow { } val response = try { + val session = initiateFlow(notaryParty) if (serviceHub.networkMapCache.isValidatingNotary(notaryParty)) { - subFlow(SendTransactionWithRetry(notaryParty, stx)) - receive>(notaryParty) + subFlow(SendTransactionWithRetry(session, stx)) + session.receive>() } else { val tx: Any = if (stx.isNotaryChangeTransaction()) { stx.notaryChangeTx } else { stx.buildFilteredTransaction(Predicate { it is StateRef || it is TimeWindow || it == notaryParty }) } - sendAndReceiveWithRetry(notaryParty, tx) + session.sendAndReceiveWithRetry(tx) } } catch (e: NotaryException) { if (e.error is NotaryError.Conflict) { @@ -99,10 +100,10 @@ class NotaryFlow { * The [SendTransactionWithRetry] flow is equivalent to [SendTransactionFlow] but using [sendAndReceiveWithRetry] * instead of [sendAndReceive], [SendTransactionWithRetry] is intended to be use by the notary client only. */ - private class SendTransactionWithRetry(otherSide: Party, stx: SignedTransaction) : SendTransactionFlow(otherSide, stx) { + private class SendTransactionWithRetry(otherSideSession: FlowSession, stx: SignedTransaction) : SendTransactionFlow(otherSideSession, stx) { @Suspendable - override fun sendPayloadAndReceiveDataRequest(otherSide: Party, payload: Any): UntrustworthyData { - return sendAndReceiveWithRetry(otherSide, payload) + override fun sendPayloadAndReceiveDataRequest(otherSideSession: FlowSession, payload: Any): UntrustworthyData { + return otherSideSession.sendAndReceiveWithRetry(payload) } } @@ -115,14 +116,14 @@ class NotaryFlow { * Additional transaction validation logic can be added when implementing [receiveAndVerifyTx]. */ // See AbstractStateReplacementFlow.Acceptor for why it's Void? - abstract class Service(val otherSide: Party, val service: TrustedAuthorityNotaryService) : FlowLogic() { + abstract class Service(val otherSideSession: FlowSession, val service: TrustedAuthorityNotaryService) : FlowLogic() { @Suspendable override fun call(): Void? { val (id, inputs, timeWindow, notary) = receiveAndVerifyTx() checkNotary(notary) service.validateTimeWindow(timeWindow) - service.commitInputStates(inputs, id, otherSide) + service.commitInputStates(inputs, id, otherSideSession.counterparty) signAndSendResponse(id) return null } @@ -144,7 +145,7 @@ class NotaryFlow { @Suspendable private fun signAndSendResponse(txId: SecureHash) { val signature = service.sign(txId) - send(otherSide, listOf(signature)) + otherSideSession.send(listOf(signature)) } } } diff --git a/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt index 48504034d7..35f17c64ea 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ReceiveTransactionFlow.kt @@ -2,7 +2,6 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* -import net.corda.core.identity.Party import net.corda.core.internal.ResolveTransactionsFlow import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.unwrap @@ -11,18 +10,26 @@ import java.security.SignatureException /** * The [ReceiveTransactionFlow] should be called in response to the [SendTransactionFlow]. * - * This flow is a combination of [receive], resolve and [SignedTransaction.verify]. This flow will receive the [SignedTransaction] - * and perform the resolution back-and-forth required to check the dependencies and download any missing attachments. - * The flow will return the [SignedTransaction] after it is resolved and then verified using [SignedTransaction.verify]. + * This flow is a combination of [FlowSession.receive], resolve and [SignedTransaction.verify]. This flow will receive the + * [SignedTransaction] and perform the resolution back-and-forth required to check the dependencies and download any missing + * attachments. The flow will return the [SignedTransaction] after it is resolved and then verified using [SignedTransaction.verify]. + * + * @param otherSideSession session to the other side which is calling [SendTransactionFlow]. + * @param checkSufficientSignatures if true checks all required signatures are present. See [SignedTransaction.verify]. */ -class ReceiveTransactionFlow -@JvmOverloads -constructor(private val otherParty: Party, private val checkSufficientSignatures: Boolean = true) : FlowLogic() { +class ReceiveTransactionFlow(private val otherSideSession: FlowSession, + private val checkSufficientSignatures: Boolean) : FlowLogic() { + /** Receives a [SignedTransaction] from [otherSideSession], verifies it and then records it in the vault. */ + constructor(otherSideSession: FlowSession) : this(otherSideSession, true) + @Suspendable - @Throws(SignatureException::class, AttachmentResolutionException::class, TransactionResolutionException::class, TransactionVerificationException::class) + @Throws(SignatureException::class, + AttachmentResolutionException::class, + TransactionResolutionException::class, + TransactionVerificationException::class) override fun call(): SignedTransaction { - return receive(otherParty).unwrap { - subFlow(ResolveTransactionsFlow(it, otherParty)) + return otherSideSession.receive().unwrap { + subFlow(ResolveTransactionsFlow(it, otherSideSession)) it.verify(serviceHub, checkSufficientSignatures) it } @@ -32,16 +39,16 @@ constructor(private val otherParty: Party, private val checkSufficientSignatures /** * The [ReceiveStateAndRefFlow] should be called in response to the [SendStateAndRefFlow]. * - * This flow is a combination of [receive] and resolve. This flow will receive a list of [StateAndRef] + * This flow is a combination of [FlowSession.receive] and resolve. This flow will receive a list of [StateAndRef] * and perform the resolution back-and-forth required to check the dependencies. * The flow will return the list of [StateAndRef] after it is resolved. */ // @JvmSuppressWildcards is used to suppress wildcards in return type when calling `subFlow(new ReceiveStateAndRef(otherParty))` in java. -class ReceiveStateAndRefFlow(private val otherParty: Party) : FlowLogic<@JvmSuppressWildcards List>>() { +class ReceiveStateAndRefFlow(private val otherSideSession: FlowSession) : FlowLogic<@JvmSuppressWildcards List>>() { @Suspendable override fun call(): List> { - return receive>>(otherParty).unwrap { - subFlow(ResolveTransactionsFlow(it.map { it.ref.txhash }.toSet(), otherParty)) + return otherSideSession.receive>>().unwrap { + subFlow(ResolveTransactionsFlow(it.map { it.ref.txhash }.toSet(), otherSideSession)) it } } diff --git a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt index 12cc8592d0..9352d3e178 100644 --- a/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/SendTransactionFlow.kt @@ -2,7 +2,6 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.StateAndRef -import net.corda.core.identity.Party import net.corda.core.internal.FetchDataFlow import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.unwrap @@ -14,9 +13,9 @@ import net.corda.core.utilities.unwrap * to check the dependencies and download any missing attachments. * * @param otherSide the target party. - * @param stx the [SignedTransaction] being sent to the [otherSide]. + * @param stx the [SignedTransaction] being sent to the [otherSideSession]. */ -open class SendTransactionFlow(otherSide: Party, stx: SignedTransaction) : DataVendingFlow(otherSide, stx) +open class SendTransactionFlow(otherSide: FlowSession, stx: SignedTransaction) : DataVendingFlow(otherSide, stx) /** * The [SendStateAndRefFlow] should be used to send a list of input [StateAndRef] to another peer that wishes to verify @@ -24,14 +23,14 @@ open class SendTransactionFlow(otherSide: Party, stx: SignedTransaction) : DataV * at the right point in the conversation to receive the input state and ref and perform the resolution back-and-forth * required to check the dependencies. * - * @param otherSide the target party. - * @param stateAndRefs the list of [StateAndRef] being sent to the [otherSide]. + * @param otherSideSession the target session. + * @param stateAndRefs the list of [StateAndRef] being sent to the [otherSideSession]. */ -open class SendStateAndRefFlow(otherSide: Party, stateAndRefs: List>) : DataVendingFlow(otherSide, stateAndRefs) +open class SendStateAndRefFlow(otherSideSession: FlowSession, stateAndRefs: List>) : DataVendingFlow(otherSideSession, stateAndRefs) -sealed class DataVendingFlow(val otherSide: Party, val payload: Any) : FlowLogic() { +sealed class DataVendingFlow(val otherSideSession: FlowSession, val payload: Any) : FlowLogic() { @Suspendable - protected open fun sendPayloadAndReceiveDataRequest(otherSide: Party, payload: Any) = sendAndReceive(otherSide, payload) + protected open fun sendPayloadAndReceiveDataRequest(otherSideSession: FlowSession, payload: Any) = otherSideSession.sendAndReceive(payload) @Suspendable protected open fun verifyDataRequest(dataRequest: FetchDataFlow.Request.Data) { @@ -42,11 +41,11 @@ sealed class DataVendingFlow(val otherSide: Party, val payload: Any) : FlowLogic override fun call(): Void? { // The first payload will be the transaction data, subsequent payload will be the transaction/attachment data. var payload = payload - // This loop will receive [FetchDataFlow.Request] continuously until the `otherSide` has all the data they need - // to resolve the transaction, a [FetchDataFlow.EndRequest] will be sent from the `otherSide` to indicate end of + // This loop will receive [FetchDataFlow.Request] continuously until the `otherSideSession` has all the data they need + // to resolve the transaction, a [FetchDataFlow.EndRequest] will be sent from the `otherSideSession` to indicate end of // data request. while (true) { - val dataRequest = sendPayloadAndReceiveDataRequest(otherSide, payload).unwrap { request -> + val dataRequest = sendPayloadAndReceiveDataRequest(otherSideSession, payload).unwrap { request -> when (request) { is FetchDataFlow.Request.Data -> { // Security TODO: Check for abnormally large or malformed data requests diff --git a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt index ce95ee9838..0789c535ba 100644 --- a/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt +++ b/core/src/main/kotlin/net/corda/core/internal/FetchDataFlow.kt @@ -7,7 +7,7 @@ import net.corda.core.crypto.SecureHash import net.corda.core.crypto.sha256 import net.corda.core.flows.FlowException import net.corda.core.flows.FlowLogic -import net.corda.core.identity.Party +import net.corda.core.flows.FlowSession import net.corda.core.internal.FetchDataFlow.DownloadedVsRequestedDataMismatch import net.corda.core.internal.FetchDataFlow.HashNotFound import net.corda.core.serialization.CordaSerializable @@ -38,7 +38,7 @@ import java.util.* */ sealed class FetchDataFlow( protected val requests: Set, - protected val otherSide: Party, + protected val otherSideSession: FlowSession, protected val dataType: DataType) : FlowLogic>() { @CordaSerializable @@ -72,7 +72,7 @@ sealed class FetchDataFlow( return if (toFetch.isEmpty()) { Result(fromDisk, emptyList()) } else { - logger.info("Requesting ${toFetch.size} dependency(s) for verification from ${otherSide.name}") + logger.info("Requesting ${toFetch.size} dependency(s) for verification from ${otherSideSession.counterparty.name}") // TODO: Support "large message" response streaming so response sizes are not limited by RAM. // We can then switch to requesting items in large batches to minimise the latency penalty. @@ -85,11 +85,11 @@ sealed class FetchDataFlow( for (hash in toFetch) { // We skip the validation here (with unwrap { it }) because we will do it below in validateFetchResponse. // The only thing checked is the object type. It is a protocol violation to send results out of order. - maybeItems += sendAndReceive>(otherSide, Request.Data(NonEmptySet.of(hash), dataType)).unwrap { it } + maybeItems += otherSideSession.sendAndReceive>(Request.Data(NonEmptySet.of(hash), dataType)).unwrap { it } } // Check for a buggy/malicious peer answering with something that we didn't ask for. val downloaded = validateFetchResponse(UntrustworthyData(maybeItems), toFetch) - logger.info("Fetched ${downloaded.size} elements from ${otherSide.name}") + logger.info("Fetched ${downloaded.size} elements from ${otherSideSession.counterparty.name}") maybeWriteToDisk(downloaded) Result(fromDisk, downloaded) } @@ -140,7 +140,7 @@ sealed class FetchDataFlow( * attachments are saved to local storage automatically. */ class FetchAttachmentsFlow(requests: Set, - otherSide: Party) : FetchDataFlow(requests, otherSide, DataType.ATTACHMENT) { + otherSide: FlowSession) : FetchDataFlow(requests, otherSide, DataType.ATTACHMENT) { override fun load(txid: SecureHash): Attachment? = serviceHub.attachments.openAttachment(txid) @@ -171,7 +171,7 @@ class FetchAttachmentsFlow(requests: Set, * results in a [FetchDataFlow.HashNotFound] exception. Note that returned transactions are not inserted into * the database, because it's up to the caller to actually verify the transactions are valid. */ -class FetchTransactionsFlow(requests: Set, otherSide: Party) : +class FetchTransactionsFlow(requests: Set, otherSide: FlowSession) : FetchDataFlow(requests, otherSide, DataType.TRANSACTION) { override fun load(txid: SecureHash): SignedTransaction? = serviceHub.validatedTransactions.getTransaction(txid) diff --git a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt index d9761906fe..cbb80eb2ae 100644 --- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt @@ -272,3 +272,5 @@ annotation class VisibleForTesting @Suppress("UNCHECKED_CAST") fun uncheckedCast(obj: T) = obj as U + +fun Iterable>.toMultiMap(): Map> = this.groupBy({ it.first }) { it.second } \ No newline at end of file diff --git a/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt b/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt index e776b0efce..f297fc7c5b 100644 --- a/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt +++ b/core/src/main/kotlin/net/corda/core/internal/ResolveTransactionsFlow.kt @@ -3,7 +3,7 @@ package net.corda.core.internal import co.paralleluniverse.fibers.Suspendable import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic -import net.corda.core.identity.Party +import net.corda.core.flows.FlowSession import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.exactAdd @@ -17,14 +17,14 @@ import java.util.* * @return a list of verified [SignedTransaction] objects, in a depth-first order. */ class ResolveTransactionsFlow(private val txHashes: Set, - private val otherSide: Party) : FlowLogic>() { + private val otherSide: FlowSession) : FlowLogic>() { /** * Resolves and validates the dependencies of the specified [signedTransaction]. Fetches the attachments, but does * *not* validate or store the [signedTransaction] itself. * * @return a list of verified [SignedTransaction] objects, in a depth-first order. */ - constructor(signedTransaction: SignedTransaction, otherSide: Party) : this(dependencyIDs(signedTransaction), otherSide) { + constructor(signedTransaction: SignedTransaction, otherSide: FlowSession) : this(dependencyIDs(signedTransaction), otherSide) { this.signedTransaction = signedTransaction } companion object { @@ -82,7 +82,7 @@ class ResolveTransactionsFlow(private val txHashes: Set, // Start fetching data. val newTxns = downloadDependencies(txHashes) fetchMissingAttachments(signedTransaction?.let { newTxns + it } ?: newTxns) - send(otherSide, FetchDataFlow.Request.End) + otherSide.send(FetchDataFlow.Request.End) // Finish fetching data. val result = topologicalSort(newTxns) diff --git a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt index 725e7ce44a..7860c687e0 100644 --- a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt @@ -5,8 +5,10 @@ import net.corda.core.crypto.Crypto import net.corda.core.crypto.SignableData import net.corda.core.crypto.SignatureMetadata import net.corda.core.crypto.TransactionSignature +import net.corda.core.identity.AbstractParty +import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate +import net.corda.core.internal.toMultiMap import net.corda.core.node.services.* import net.corda.core.serialization.SerializeAsToken import net.corda.core.transactions.FilteredTransaction @@ -269,4 +271,75 @@ interface ServiceHub : ServicesForResolution { * @return A new [Connection] */ fun jdbcSession(): Connection + + /** + * Group each [PublicKey] by the well known party using the [ServiceHub.identityService], in preparation for + * creating [FlowSession]s, for example. + * + * @param publicKeys the [PublicKey]s to group. + * @param ignoreUnrecognisedParties if this is false, throw an exception if some of the [PublicKey]s cannot be mapped + * to a [Party]. + * @return a map of well known [Party] to associated [PublicKey]s. + */ + @Throws(IllegalArgumentException::class) + fun groupPublicKeysByWellKnownParty(publicKeys: Collection, ignoreUnrecognisedParties: Boolean): Map> = + groupAbstractPartyByWellKnownParty(publicKeys.map { AnonymousParty(it) }, ignoreUnrecognisedParties).mapValues { it.value.map { it.owningKey } } + + /** + * Group each [PublicKey] by the well known party using the [ServiceHub.identityService], in preparation for + * creating [FlowSession]s, for example. Throw an exception if some of the [PublicKey]s cannot be mapped + * to a [Party]. + * + * @param publicKeys the [PublicKey]s to group. + * @return a map of well known [Party] to associated [PublicKey]s. + */ + // Cannot use @JvmOverloads in interface + @Throws(IllegalArgumentException::class) + fun groupPublicKeysByWellKnownParty(publicKeys: Collection): Map> = groupPublicKeysByWellKnownParty(publicKeys, false) + + /** + * Group each [AbstractParty] by the well known party using the [ServiceHub.identityService], in preparation for + * creating [FlowSession]s, for example. + * + * @param parties the [AbstractParty]s to group. + * @param ignoreUnrecognisedParties if this is false, throw an exception if some of the [AbstractParty]s cannot be mapped + * to a [Party]. + * @return a map of well known [Party] to associated [AbstractParty]s. + */ + @Throws(IllegalArgumentException::class) + fun groupAbstractPartyByWellKnownParty(parties: Collection, ignoreUnrecognisedParties: Boolean): Map> { + val partyToPublicKey: Iterable> = parties.mapNotNull { + (identityService.partyFromAnonymous(it) ?: if (ignoreUnrecognisedParties) return@mapNotNull null else throw IllegalArgumentException("Could not find Party for $it")) to it + } + return partyToPublicKey.toMultiMap() + } + + /** + * Group each [AbstractParty] by the well known party using the [ServiceHub.identityService], in preparation for + * creating [FlowSession]s, for example. Throw an exception if some of the [AbstractParty]s cannot be mapped + * to a [Party]. + * + * @param parties the [AbstractParty]s to group. + * @return a map of well known [Party] to associated [AbstractParty]s. + */ + // Cannot use @JvmOverloads in interface + @Throws(IllegalArgumentException::class) + fun groupAbstractPartyByWellKnownParty(parties: Collection): Map> { + return groupAbstractPartyByWellKnownParty(parties, false) + } + + /** + * Remove this node from a map of well known [Party]s. + * + * @return a new copy of the map, with the well known [Party] for this node removed. + */ + fun excludeMe(map: Map): Map = map.filterKeys { !myInfo.isLegalIdentity(it) } + + /** + * Remove the [Party] associated with the notary of a [SignedTransaction] from the a map of [Party]s. It is a no-op + * if the notary is null. + * + * @return a new copy of the map, with the well known [Party] for the notary removed. + */ + fun excludeNotary(map: Map, stx: SignedTransaction): Map = map.filterKeys { it != stx.notary } } diff --git a/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt b/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt index c5a4b6449e..71e24c506d 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/NotaryService.kt @@ -3,10 +3,7 @@ package net.corda.core.node.services import net.corda.core.contracts.StateRef import net.corda.core.contracts.TimeWindow import net.corda.core.crypto.* -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.NotaryError -import net.corda.core.flows.NotaryException -import net.corda.core.flows.NotaryFlow +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.node.ServiceHub import net.corda.core.serialization.SingletonSerializeAsToken @@ -24,9 +21,9 @@ abstract class NotaryService : SingletonSerializeAsToken() { /** * Produces a notary service flow which has the corresponding sends and receives as [NotaryFlow.Client]. - * @param otherParty client [Party] making the request + * @param otherPartySession client [Party] making the request */ - abstract fun createServiceFlow(otherParty: Party): FlowLogic + abstract fun createServiceFlow(otherPartySession: FlowSession): FlowLogic } /** diff --git a/core/src/main/kotlin/net/corda/core/transactions/TransactionWithSignatures.kt b/core/src/main/kotlin/net/corda/core/transactions/TransactionWithSignatures.kt index 5bc5f3ce0c..ab25d68064 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/TransactionWithSignatures.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/TransactionWithSignatures.kt @@ -42,7 +42,7 @@ interface TransactionWithSignatures : NamedByHash { fun verifySignaturesExcept(vararg allowedToBeMissing: PublicKey) { checkSignaturesAreValid() - val needed = getMissingSignatures() - allowedToBeMissing + val needed = getMissingSigners() - allowedToBeMissing if (needed.isNotEmpty()) throw SignaturesMissingException(needed.toNonEmptySet(), getKeyDescriptions(needed), id) } @@ -71,7 +71,10 @@ interface TransactionWithSignatures : NamedByHash { */ fun getKeyDescriptions(keys: Set): List - private fun getMissingSignatures(): Set { + /** + * Return the [PublicKey]s for which we still need signatures. + */ + fun getMissingSigners(): Set { val sigKeys = sigs.map { it.by }.toSet() // TODO Problem is that we can get single PublicKey wrapped as CompositeKey in allowedToBeMissing/mustSign // equals on CompositeKey won't catch this case (do we want to single PublicKey be equal to the same key wrapped in CompositeKey with threshold 1?) diff --git a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java index 406cbc30ec..01855fb5e3 100644 --- a/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java +++ b/core/src/test/java/net/corda/core/flows/FlowsInJavaTest.java @@ -80,8 +80,9 @@ public class FlowsInJavaTest { @Suspendable @Override public String call() throws FlowException { - return receive(String.class, otherParty).unwrap(data -> { - send(otherParty, "Something"); + FlowSession session = initiateFlow(otherParty); + return session.receive(String.class).unwrap(data -> { + session.send("Something"); return data; }); } @@ -89,16 +90,16 @@ public class FlowsInJavaTest { @InitiatedBy(SendInUnwrapFlow.class) private static class SendHelloAndThenReceive extends FlowLogic { - private final Party otherParty; + private final FlowSession otherSide; - private SendHelloAndThenReceive(Party otherParty) { - this.otherParty = otherParty; + private SendHelloAndThenReceive(FlowSession otherParty) { + this.otherSide = otherParty; } @Suspendable @Override public String call() throws FlowException { - return sendAndReceive(String.class, otherParty, "Hello").unwrap(data -> data); + return otherSide.sendAndReceive(String.class, "Hello").unwrap(data -> data); } } @@ -115,7 +116,8 @@ public class FlowsInJavaTest { @Suspendable @Override public Void call() throws FlowException { - receive(Primitives.unwrap(receiveType), otherParty); + FlowSession session = initiateFlow(otherParty); + session.receive(Primitives.unwrap(receiveType)); return null; } } diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt index e1511eaa77..735798118c 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -162,12 +162,15 @@ class AttachmentTests { @InitiatingFlow private class InitiatingFetchAttachmentsFlow(val otherSide: Party, val hashes: Set) : FlowLogic>() { @Suspendable - override fun call(): FetchDataFlow.Result = subFlow(FetchAttachmentsFlow(hashes, otherSide)) + override fun call(): FetchDataFlow.Result { + val session = initiateFlow(otherSide) + return subFlow(FetchAttachmentsFlow(hashes, session)) + } } @InitiatedBy(InitiatingFetchAttachmentsFlow::class) - private class FetchAttachmentsResponse(val otherSide: Party) : FlowLogic() { + private class FetchAttachmentsResponse(val otherSideSession: FlowSession) : FlowLogic() { @Suspendable - override fun call() = subFlow(TestDataVendingFlow(otherSide)) + override fun call() = subFlow(TestDataVendingFlow(otherSideSession)) } } diff --git a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt index 540a8a3546..34a7bf5887 100644 --- a/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/CollectSignaturesFlowTests.kt @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Command import net.corda.core.contracts.StateAndContract import net.corda.core.contracts.requireThat -import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder @@ -31,7 +30,6 @@ class CollectSignaturesFlowTests { lateinit var b: StartedNode lateinit var c: StartedNode lateinit var notary: Party - val services = MockServices() @Before fun setup() { @@ -61,12 +59,13 @@ class CollectSignaturesFlowTests { // "collectSignaturesFlow" and "SignTransactionFlow" can be used in practise. object TestFlow { @InitiatingFlow - class Initiator(val state: DummyContract.MultiOwnerState, val otherParty: Party) : FlowLogic() { + class Initiator(private val state: DummyContract.MultiOwnerState, private val otherParty: Party) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - send(otherParty, state) + val session = initiateFlow(otherParty) + session.send(state) - val flow = object : SignTransactionFlow(otherParty) { + val flow = object : SignTransactionFlow(session) { @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat { val tx = stx.tx val ltx = tx.toLedgerTransaction(serviceHub) @@ -83,19 +82,19 @@ class CollectSignaturesFlowTests { } @InitiatedBy(TestFlow.Initiator::class) - class Responder(val otherParty: Party, val identities: Map) : FlowLogic() { + class Responder(private val initiatingSession: FlowSession) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - val state = receive(otherParty).unwrap { it } + val state = initiatingSession.receive().unwrap { it } val notary = serviceHub.getDefaultNotary() val myInputKeys = state.participants.map { it.owningKey } - val myKeys = myInputKeys + (identities[ourIdentity] ?: ourIdentity).owningKey val command = Command(DummyContract.Commands.Create(), myInputKeys) val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) val ptx = serviceHub.signInitialTransaction(builder) - val stx = subFlow(CollectSignaturesFlow(ptx, myKeys)) - return subFlow(FinalityFlow(stx)).single() + val signature = subFlow(CollectSignatureFlow(ptx, initiatingSession, initiatingSession.counterparty.owningKey)) + val stx = ptx + signature + return subFlow(FinalityFlow(stx)) } } } @@ -105,7 +104,7 @@ class CollectSignaturesFlowTests { // receiving off the wire. object TestFlowTwo { @InitiatingFlow - class Initiator(val state: DummyContract.MultiOwnerState) : FlowLogic() { + class Initiator(private val state: DummyContract.MultiOwnerState) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { val notary = serviceHub.getDefaultNotary() @@ -113,15 +112,16 @@ class CollectSignaturesFlowTests { val command = Command(DummyContract.Commands.Create(), myInputKeys) val builder = TransactionBuilder(notary).withItems(StateAndContract(state, DUMMY_PROGRAM_ID), command) val ptx = serviceHub.signInitialTransaction(builder) - val stx = subFlow(CollectSignaturesFlow(ptx, myInputKeys)) - return subFlow(FinalityFlow(stx)).single() + val sessions = serviceHub.excludeMe(serviceHub.groupAbstractPartyByWellKnownParty(state.owners)).map { initiateFlow(it.key) } + val stx = subFlow(CollectSignaturesFlow(ptx, sessions, myInputKeys)) + return subFlow(FinalityFlow(stx)) } } @InitiatedBy(TestFlowTwo.Initiator::class) - class Responder(val otherParty: Party) : FlowLogic() { - @Suspendable override fun call(): SignedTransaction { - val flow = object : SignTransactionFlow(otherParty) { + class Responder(private val otherSideSession: FlowSession) : FlowLogic() { + @Suspendable override fun call() { + val signFlow = object : SignTransactionFlow(otherSideSession) { @Suspendable override fun checkTransaction(stx: SignedTransaction) = requireThat { val tx = stx.tx val ltx = tx.toLedgerTransaction(serviceHub) @@ -132,9 +132,8 @@ class CollectSignaturesFlowTests { } } - val stx = subFlow(flow) - - return waitForLedgerCommit(stx.id) + val stx = subFlow(signFlow) + waitForLedgerCommit(stx.id) } } } @@ -164,7 +163,7 @@ class CollectSignaturesFlowTests { fun `no need to collect any signatures`() { val onePartyDummyContract = DummyContract.generateInitial(1337, notary, a.info.chooseIdentity().ref(1)) val ptx = a.services.signInitialTransaction(onePartyDummyContract) - val flow = a.services.startFlow(CollectSignaturesFlow(ptx)) + val flow = a.services.startFlow(CollectSignaturesFlow(ptx, emptySet())) mockNet.runNetwork() val result = flow.resultFuture.getOrThrow() result.verifyRequiredSignatures() @@ -177,7 +176,7 @@ class CollectSignaturesFlowTests { val onePartyDummyContract = DummyContract.generateInitial(1337, notary, a.info.chooseIdentity().ref(1)) val miniCorpServices = MockServices(MINI_CORP_KEY) val ptx = miniCorpServices.signInitialTransaction(onePartyDummyContract) - val flow = a.services.startFlow(CollectSignaturesFlow(ptx)) + val flow = a.services.startFlow(CollectSignaturesFlow(ptx, emptySet())) mockNet.runNetwork() assertFailsWith("The Initiator of CollectSignaturesFlow must have signed the transaction.") { flow.resultFuture.getOrThrow() @@ -192,7 +191,7 @@ class CollectSignaturesFlowTests { b.info.chooseIdentity().ref(3)) val signedByA = a.services.signInitialTransaction(twoPartyDummyContract) val signedByBoth = b.services.addSignature(signedByA) - val flow = a.services.startFlow(CollectSignaturesFlow(signedByBoth)) + val flow = a.services.startFlow(CollectSignaturesFlow(signedByBoth, emptySet())) mockNet.runNetwork() val result = flow.resultFuture.getOrThrow() println(result.tx) diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index 69a2d06d79..edc9dd0df0 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -21,15 +21,10 @@ import net.corda.node.internal.CordaRPCOpsImpl import net.corda.node.internal.StartedNode import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.nodeapi.User -import net.corda.testing.RPCDriverExposedDSLInterface -import net.corda.testing.chooseIdentity +import net.corda.testing.* import net.corda.testing.contracts.DummyContract import net.corda.testing.contracts.DummyContractV2 -import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork -import net.corda.testing.rpcDriver -import net.corda.testing.rpcTestUser -import net.corda.testing.startRpcClient import org.junit.After import org.junit.Before import org.junit.Test @@ -63,7 +58,6 @@ class ContractUpgradeFlowTest { b.database.transaction { b.services.identityService.verifyAndRegisterIdentity(nodeIdentity) } - } @After @@ -78,7 +72,7 @@ class ContractUpgradeFlowTest { val signedByA = a.services.signInitialTransaction(twoPartyDummyContract) val stx = b.services.addSignature(signedByA) - a.services.startFlow(FinalityFlow(stx, setOf(a.info.chooseIdentity(), b.info.chooseIdentity()))) + a.services.startFlow(FinalityFlow(stx, setOf(b.info.chooseIdentity()))) mockNet.runNetwork() val atx = a.database.transaction { a.services.validatedTransactions.getTransaction(stx.id) } @@ -157,7 +151,7 @@ class ContractUpgradeFlowTest { )) val rpcA = startProxy(a, user) val rpcB = startProxy(b, user) - val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(a.info.chooseIdentity(), b.info.chooseIdentity())) + val handle = rpcA.startFlow(::FinalityInvoker, stx, setOf(b.info.chooseIdentity())) mockNet.runNetwork() handle.returnValue.getOrThrow() @@ -257,9 +251,9 @@ class ContractUpgradeFlowTest { } @StartableByRPC - class FinalityInvoker(val transaction: SignedTransaction, - val extraRecipients: Set) : FlowLogic>() { + class FinalityInvoker(private val transaction: SignedTransaction, + private val extraRecipients: Set) : FlowLogic() { @Suspendable - override fun call(): List = subFlow(FinalityFlow(transaction, extraRecipients)) + override fun call(): SignedTransaction = subFlow(FinalityFlow(transaction, extraRecipients)) } } diff --git a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt index 48e7df3537..929a65fb90 100644 --- a/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/FinalityFlowTests.kt @@ -1,14 +1,13 @@ package net.corda.core.flows -import net.corda.core.contracts.Amount -import net.corda.core.contracts.Issued import net.corda.core.identity.Party import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow -import net.corda.finance.GBP +import net.corda.finance.POUNDS import net.corda.finance.contracts.asset.Cash -import net.corda.testing.ALICE +import net.corda.finance.issuedBy import net.corda.node.internal.StartedNode +import net.corda.testing.ALICE import net.corda.testing.chooseIdentity import net.corda.testing.getDefaultNotary import net.corda.testing.node.MockNetwork @@ -44,14 +43,13 @@ class FinalityFlowTests { @Test fun `finalise a simple transaction`() { - val amount = Amount(1000, Issued(nodeA.info.chooseIdentity().ref(0), GBP)) + val amount = 1000.POUNDS.issuedBy(nodeA.info.chooseIdentity().ref(0)) val builder = TransactionBuilder(notary) Cash().generateIssue(builder, amount, nodeB.info.chooseIdentity(), notary) val stx = nodeA.services.signInitialTransaction(builder) val flow = nodeA.services.startFlow(FinalityFlow(stx)) mockNet.runNetwork() - val result = flow.resultFuture.getOrThrow() - val notarisedTx = result.single() + val notarisedTx = flow.resultFuture.getOrThrow() notarisedTx.verifyRequiredSignatures() val transactionSeenByB = nodeB.services.database.transaction { nodeB.services.validatedTransactions.getTransaction(notarisedTx.id) @@ -61,7 +59,7 @@ class FinalityFlowTests { @Test fun `reject a transaction with unknown parties`() { - val amount = Amount(1000, Issued(nodeA.info.chooseIdentity().ref(0), GBP)) + val amount = 1000.POUNDS.issuedBy(nodeA.info.chooseIdentity().ref(0)) val fakeIdentity = ALICE // Alice isn't part of this network, so node A won't recognise them val builder = TransactionBuilder(notary) Cash().generateIssue(builder, amount, fakeIdentity, notary) diff --git a/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt b/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt deleted file mode 100644 index 88505ebbfc..0000000000 --- a/core/src/test/kotlin/net/corda/core/flows/ManualFinalityFlowTests.kt +++ /dev/null @@ -1,67 +0,0 @@ -package net.corda.core.flows - -import net.corda.core.contracts.Amount -import net.corda.core.contracts.Issued -import net.corda.core.identity.Party -import net.corda.core.transactions.TransactionBuilder -import net.corda.core.utilities.getOrThrow -import net.corda.finance.GBP -import net.corda.finance.contracts.asset.Cash -import net.corda.node.internal.StartedNode -import net.corda.testing.chooseIdentity -import net.corda.testing.getDefaultNotary -import net.corda.testing.node.MockNetwork -import net.corda.testing.node.MockServices -import org.junit.After -import org.junit.Before -import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertNull - -class ManualFinalityFlowTests { - lateinit var mockNet: MockNetwork - lateinit var nodeA: StartedNode - lateinit var nodeB: StartedNode - lateinit var nodeC: StartedNode - lateinit var notary: Party - val services = MockServices() - - @Before - fun setup() { - mockNet = MockNetwork() - val nodes = mockNet.createSomeNodes(3) - nodeA = nodes.partyNodes[0] - nodeB = nodes.partyNodes[1] - nodeC = nodes.partyNodes[2] - mockNet.runNetwork() - nodeA.internals.ensureRegistered() - notary = nodeA.services.getDefaultNotary() - } - - @After - fun tearDown() { - mockNet.stopNodes() - } - - @Test - fun `finalise a simple transaction`() { - val amount = Amount(1000, Issued(nodeA.info.chooseIdentity().ref(0), GBP)) - val builder = TransactionBuilder(notary) - Cash().generateIssue(builder, amount, nodeB.info.chooseIdentity(), notary) - val stx = nodeA.services.signInitialTransaction(builder) - val flow = nodeA.services.startFlow(ManualFinalityFlow(stx, setOf(nodeC.info.chooseIdentity()))) - mockNet.runNetwork() - val result = flow.resultFuture.getOrThrow() - val notarisedTx = result.single() - notarisedTx.verifyRequiredSignatures() - // We override the participants, so node C will get a copy despite not being involved, and B won't - val transactionSeenByB = nodeB.services.database.transaction { - nodeB.services.validatedTransactions.getTransaction(notarisedTx.id) - } - assertNull(transactionSeenByB) - val transactionSeenByC = nodeC.services.database.transaction { - nodeC.services.validatedTransactions.getTransaction(notarisedTx.id) - } - assertEquals(notarisedTx, transactionSeenByC) - } -} \ No newline at end of file diff --git a/core/src/test/kotlin/net/corda/core/flows/TestDataVendingFlow.kt b/core/src/test/kotlin/net/corda/core/flows/TestDataVendingFlow.kt index 5c53890038..aa2f698c89 100644 --- a/core/src/test/kotlin/net/corda/core/flows/TestDataVendingFlow.kt +++ b/core/src/test/kotlin/net/corda/core/flows/TestDataVendingFlow.kt @@ -1,19 +1,18 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable -import net.corda.core.identity.Party import net.corda.core.internal.FetchDataFlow import net.corda.core.utilities.UntrustworthyData // Flow to start data vending without sending transaction. For testing only. -class TestDataVendingFlow(otherSide: Party) : SendStateAndRefFlow(otherSide, emptyList()) { +class TestDataVendingFlow(otherSideSession: FlowSession) : SendStateAndRefFlow(otherSideSession, emptyList()) { @Suspendable - override fun sendPayloadAndReceiveDataRequest(otherSide: Party, payload: Any): UntrustworthyData { + override fun sendPayloadAndReceiveDataRequest(otherSideSession: FlowSession, payload: Any): UntrustworthyData { return if (payload is List<*> && payload.isEmpty()) { // Hack to not send the first message. - receive(otherSide) + otherSideSession.receive() } else { - super.sendPayloadAndReceiveDataRequest(otherSide, payload) + super.sendPayloadAndReceiveDataRequest(this.otherSideSession, payload) } } } \ No newline at end of file diff --git a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt index dc752b1da0..5a3594b6de 100644 --- a/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/ResolveTransactionsFlowTest.kt @@ -2,10 +2,7 @@ package net.corda.core.internal import co.paralleluniverse.fibers.Suspendable import net.corda.core.crypto.SecureHash -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.TestDataVendingFlow +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.getOrThrow @@ -195,20 +192,22 @@ class ResolveTransactionsFlowTest { // DOCEND 2 @InitiatingFlow - private class TestFlow(private val resolveTransactionsFlow: ResolveTransactionsFlow, private val txCountLimit: Int? = null) : FlowLogic>() { - constructor(txHashes: Set, otherSide: Party, txCountLimit: Int? = null) : this(ResolveTransactionsFlow(txHashes, otherSide), txCountLimit = txCountLimit) - constructor(stx: SignedTransaction, otherSide: Party) : this(ResolveTransactionsFlow(stx, otherSide)) + private class TestFlow(val otherSide: Party, private val resolveTransactionsFlowFactory: (FlowSession) -> ResolveTransactionsFlow, private val txCountLimit: Int? = null) : FlowLogic>() { + constructor(txHashes: Set, otherSide: Party, txCountLimit: Int? = null) : this(otherSide, { ResolveTransactionsFlow(txHashes, it) }, txCountLimit = txCountLimit) + constructor(stx: SignedTransaction, otherSide: Party) : this(otherSide, { ResolveTransactionsFlow(stx, it) }) @Suspendable override fun call(): List { + val session = initiateFlow(otherSide) + val resolveTransactionsFlow = resolveTransactionsFlowFactory(session) txCountLimit?.let { resolveTransactionsFlow.transactionCountLimit = it } return subFlow(resolveTransactionsFlow) } } @InitiatedBy(TestFlow::class) - private class TestResponseFlow(val otherSide: Party) : FlowLogic() { + private class TestResponseFlow(val otherSideSession: FlowSession) : FlowLogic() { @Suspendable - override fun call() = subFlow(TestDataVendingFlow(otherSide)) + override fun call() = subFlow(TestDataVendingFlow(otherSideSession)) } } diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index f935671300..0dc98505dc 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Attachment import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.TestDataVendingFlow import net.corda.core.identity.Party @@ -82,14 +83,14 @@ class AttachmentSerializationTest { mockNet.stopNodes() } - private class ServerLogic(private val client: Party, private val sendData: Boolean) : FlowLogic() { + private class ServerLogic(private val clientSession: FlowSession, private val sendData: Boolean) : FlowLogic() { @Suspendable override fun call() { if (sendData) { - subFlow(TestDataVendingFlow(client)) + subFlow(TestDataVendingFlow(clientSession)) } - receive(client).unwrap { assertEquals("ping one", it) } - sendAndReceive(client, "pong").unwrap { assertEquals("ping two", it) } + clientSession.receive().unwrap { assertEquals("ping one", it) } + clientSession.sendAndReceive("pong").unwrap { assertEquals("ping two", it) } } } @@ -100,9 +101,9 @@ class AttachmentSerializationTest { internal val server = server.info.chooseIdentity() @Suspendable - internal fun communicate() { - sendAndReceive(server, "ping one").unwrap { assertEquals("pong", it) } - send(server, "ping two") + internal fun communicate(serverSession: FlowSession) { + serverSession.sendAndReceive("ping one").unwrap { assertEquals("pong", it) } + serverSession.send("ping two") } @Suspendable @@ -121,7 +122,8 @@ class AttachmentSerializationTest { @Suspendable override fun getAttachmentContent(): String { val customAttachment = CustomAttachment(attachmentId, customContent) - communicate() + val session = initiateFlow(server) + communicate(session) return customAttachment.customContent } } @@ -130,7 +132,8 @@ class AttachmentSerializationTest { @Suspendable override fun getAttachmentContent(): String { val localAttachment = serviceHub.attachments.openAttachment(attachmentId)!! - communicate() + val session = initiateFlow(server) + communicate(session) return localAttachment.extractContent() } } @@ -138,9 +141,10 @@ class AttachmentSerializationTest { private class FetchAttachmentLogic(server: StartedNode<*>, private val attachmentId: SecureHash) : ClientLogic(server) { @Suspendable override fun getAttachmentContent(): String { - val (downloadedAttachment) = subFlow(FetchAttachmentsFlow(setOf(attachmentId), server)).downloaded - send(server, FetchDataFlow.Request.End) - communicate() + val serverSession = initiateFlow(server) + val (downloadedAttachment) = subFlow(FetchAttachmentsFlow(setOf(attachmentId), serverSession)).downloaded + serverSession.send(FetchDataFlow.Request.End) + communicate(serverSession) return downloadedAttachment.extractContent() } } @@ -148,7 +152,7 @@ class AttachmentSerializationTest { private fun launchFlow(clientLogic: ClientLogic, rounds: Int, sendData: Boolean = false) { server.internals.internalRegisterFlowFactory( ClientLogic::class.java, - InitiatedFlowFactory.Core { ServerLogic(it.counterparty, sendData) }, + InitiatedFlowFactory.Core { ServerLogic(it, sendData) }, ServerLogic::class.java, track = false) client.services.startFlow(clientLogic) diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index 8838e86368..a5cbf809dc 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -23,7 +23,7 @@ class IntegrationTestingTutorial { @Test fun `alice bob cash exchange example`() { // START 1 - driver { + driver(extraCordappPackagesToScan = listOf("net.corda.finance")) { val aliceUser = User("aliceUser", "testPassword1", permissions = setOf( startFlowPermission(), startFlowPermission() diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java index a4e0228066..1b84610ca9 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java @@ -2,7 +2,6 @@ package net.corda.docs; import co.paralleluniverse.fibers.Suspendable; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; import net.corda.core.contracts.*; import net.corda.core.crypto.SecureHash; import net.corda.core.crypto.TransactionSignature; @@ -29,6 +28,7 @@ import java.security.GeneralSecurityException; import java.security.PublicKey; import java.time.Duration; import java.time.Instant; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -37,6 +37,7 @@ import static net.corda.testing.TestConstants.getALICE_KEY; // We group our two flows inside a singleton object to indicate that they work // together. +@SuppressWarnings("unused") public class FlowCookbookJava { // ``InitiatorFlow`` is our first flow, and will communicate with // ``ResponderFlow``, below. @@ -80,14 +81,14 @@ public class FlowCookbookJava { // subflow's progress steps in our flow's progress tracker. @Override public ProgressTracker childProgressTracker() { - return CollectSignaturesFlow.Companion.tracker(); + return CollectSignaturesFlow.tracker(); } }; private static final Step VERIFYING_SIGS = new Step("Verifying a transaction's signatures."); private static final Step FINALISATION = new Step("Finalising a transaction.") { @Override public ProgressTracker childProgressTracker() { - return FinalityFlow.Companion.tracker(); + return FinalityFlow.tracker(); } }; @@ -154,7 +155,8 @@ public class FlowCookbookJava { // registered to respond to this flow, and has a corresponding // ``receive`` call. // DOCSTART 4 - send(counterparty, new Object()); + FlowSession counterpartySession = initiateFlow(counterparty); + counterpartySession.send(new Object()); // DOCEND 4 // We can wait to receive arbitrary data of a specific type from a @@ -177,7 +179,7 @@ public class FlowCookbookJava { // be what it appears to be! We must unwrap the // ``UntrustworthyData`` using a lambda. // DOCSTART 5 - UntrustworthyData packet1 = receive(Integer.class, counterparty); + UntrustworthyData packet1 = counterpartySession.receive(Integer.class); Integer integer = packet1.unwrap(data -> { // Perform checking on the object received. // T O D O: Check the received object. @@ -191,7 +193,7 @@ public class FlowCookbookJava { // data sent doesn't need to match the type of the data received // back. // DOCSTART 7 - UntrustworthyData packet2 = sendAndReceive(Boolean.class, counterparty, "You can send and receive any class!"); + UntrustworthyData packet2 = counterpartySession.sendAndReceive(Boolean.class, "You can send and receive any class!"); Boolean bool = packet2.unwrap(data -> { // Perform checking on the object received. // T O D O: Check the received object. @@ -204,8 +206,9 @@ public class FlowCookbookJava { // counterparty. A flow can send messages to as many parties as it // likes, and each party can invoke a different response flow. // DOCSTART 6 - send(regulator, new Object()); - UntrustworthyData packet3 = receive(Object.class, regulator); + FlowSession regulatorSession = initiateFlow(regulator); + regulatorSession.send(new Object()); + UntrustworthyData packet3 = regulatorSession.receive(Object.class); // DOCEND 6 /*------------------------------------ @@ -395,10 +398,10 @@ public class FlowCookbookJava { // for data request until the transaction is resolved and verified // on the other side: // DOCSTART 12 - subFlow(new SendTransactionFlow(counterparty, twiceSignedTx)); + subFlow(new SendTransactionFlow(counterpartySession, twiceSignedTx)); // Optional request verification to further restrict data access. - subFlow(new SendTransactionFlow(counterparty, twiceSignedTx) { + subFlow(new SendTransactionFlow(counterpartySession, twiceSignedTx) { @Override protected void verifyDataRequest(@NotNull FetchDataFlow.Request.Data dataRequest) { // Extra request verification. @@ -408,17 +411,17 @@ public class FlowCookbookJava { // We can receive the transaction using ``ReceiveTransactionFlow``, // which will automatically download all the dependencies and verify - // the transaction + // the transaction and then record in our vault // DOCSTART 13 - SignedTransaction verifiedTransaction = subFlow(new ReceiveTransactionFlow(counterparty)); + SignedTransaction verifiedTransaction = subFlow(new ReceiveTransactionFlow(counterpartySession)); // DOCEND 13 // We can also send and receive a `StateAndRef` dependency chain and automatically resolve its dependencies. // DOCSTART 14 - subFlow(new SendStateAndRefFlow(counterparty, dummyStates)); + subFlow(new SendStateAndRefFlow(counterpartySession, dummyStates)); // On the receive side ... - List> resolvedStateAndRef = subFlow(new ReceiveStateAndRefFlow(counterparty)); + List> resolvedStateAndRef = subFlow(new ReceiveStateAndRefFlow(counterpartySession)); // DOCEND 14 try { @@ -475,7 +478,7 @@ public class FlowCookbookJava { // other required signers using ``CollectSignaturesFlow``. // The responder flow will need to call ``SignTransactionFlow``. // DOCSTART 15 - SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(twiceSignedTx, SIGS_GATHERING.childProgressTracker())); + SignedTransaction fullySignedTx = subFlow(new CollectSignaturesFlow(twiceSignedTx, Collections.emptySet(), SIGS_GATHERING.childProgressTracker())); // DOCEND 15 /*------------------------ @@ -517,13 +520,13 @@ public class FlowCookbookJava { // We notarise the transaction and get it recorded in the vault of // the participants of all the transaction's states. // DOCSTART 9 - SignedTransaction notarisedTx1 = subFlow(new FinalityFlow(fullySignedTx, FINALISATION.childProgressTracker())).get(0); + SignedTransaction notarisedTx1 = subFlow(new FinalityFlow(fullySignedTx, FINALISATION.childProgressTracker())); // DOCEND 9 // We can also choose to send it to additional parties who aren't one // of the state's participants. // DOCSTART 10 - Set additionalParties = ImmutableSet.of(regulator); - SignedTransaction notarisedTx2 = subFlow(new FinalityFlow(ImmutableList.of(fullySignedTx), additionalParties, FINALISATION.childProgressTracker())).get(0); + Set additionalParties = Collections.singleton(regulator); + SignedTransaction notarisedTx2 = subFlow(new FinalityFlow(fullySignedTx, additionalParties, FINALISATION.childProgressTracker())); // DOCEND 10 return null; @@ -540,10 +543,10 @@ public class FlowCookbookJava { @InitiatedBy(InitiatorFlow.class) public static class ResponderFlow extends FlowLogic { - private final Party counterparty; + private final FlowSession counterpartySession; - public ResponderFlow(Party counterparty) { - this.counterparty = counterparty; + public ResponderFlow(FlowSession counterpartySession) { + this.counterpartySession = counterpartySession; } private static final Step RECEIVING_AND_SENDING_DATA = new Step("Sending data between parties."); @@ -575,9 +578,9 @@ public class FlowCookbookJava { // ``Boolean`` instance back // Our side of the flow must mirror these calls. // DOCSTART 8 - Object obj = receive(Object.class, counterparty).unwrap(data -> data); - String string = sendAndReceive(String.class, counterparty, 99).unwrap(data -> data); - send(counterparty, true); + Object obj = counterpartySession.receive(Object.class).unwrap(data -> data); + String string = counterpartySession.sendAndReceive(String.class, 99).unwrap(data -> data); + counterpartySession.send(true); // DOCEND 8 /*----------------------------------------- @@ -590,8 +593,8 @@ public class FlowCookbookJava { // ``SignTransactionFlow`` subclass. // DOCSTART 16 class SignTxFlow extends SignTransactionFlow { - private SignTxFlow(Party otherParty, ProgressTracker progressTracker) { - super(otherParty, progressTracker); + private SignTxFlow(FlowSession otherSession, ProgressTracker progressTracker) { + super(otherSession, progressTracker); } @Override @@ -605,7 +608,7 @@ public class FlowCookbookJava { } } - subFlow(new SignTxFlow(counterparty, SignTransactionFlow.Companion.tracker())); + subFlow(new SignTxFlow(counterpartySession, SignTransactionFlow.tracker())); // DOCEND 16 /*------------------------------ diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt index 170b945d10..3f56cb0a56 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomNotaryTutorial.kt @@ -3,7 +3,6 @@ package net.corda.docs import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.TransactionVerificationException import net.corda.core.flows.* -import net.corda.core.identity.Party import net.corda.core.node.ServiceHub import net.corda.core.node.services.CordaService import net.corda.core.node.services.TimeWindowChecker @@ -19,7 +18,7 @@ class MyCustomValidatingNotaryService(override val services: ServiceHub, overrid override val timeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider = PersistentUniquenessProvider() - override fun createServiceFlow(otherParty: Party): FlowLogic = MyValidatingNotaryFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic = MyValidatingNotaryFlow(otherPartySession, this) override fun start() {} override fun stop() {} @@ -27,7 +26,7 @@ class MyCustomValidatingNotaryService(override val services: ServiceHub, overrid // END 1 // START 2 -class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotaryService) : NotaryFlow.Service(otherSide, service) { +class MyValidatingNotaryFlow(otherSide: FlowSession, service: MyCustomValidatingNotaryService) : NotaryFlow.Service(otherSide, service) { /** * The received transaction is checked for contract-validity, for which the caller also has to to reveal the whole * transaction dependency chain. @@ -35,7 +34,7 @@ class MyValidatingNotaryFlow(otherSide: Party, service: MyCustomValidatingNotary @Suspendable override fun receiveAndVerifyTx(): TransactionParts { try { - val stx = subFlow(ReceiveTransactionFlow(otherSide, checkSufficientSignatures = false)) + val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false)) checkNotary(stx.notary) checkSignatures(stx) val wtx = stx.tx diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt index 0a5c060d21..47a5ca00a0 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/CustomVaultQuery.kt @@ -2,10 +2,7 @@ package net.corda.docs import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Amount -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.StartableByRPC +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.node.ServiceHub import net.corda.core.node.services.CordaService @@ -85,12 +82,12 @@ object TopupIssuerFlow { @Throws(CashException::class) override fun call(): List { val topupRequest = TopupRequest(issueToParty, issueToPartyRef, notaryParty) - return sendAndReceive>(issuerBankParty, topupRequest).unwrap { it } + return initiateFlow(issuerBankParty).sendAndReceive>(topupRequest).unwrap { it } } } @InitiatedBy(TopupIssuanceRequester::class) - class TopupIssuer(val otherParty: Party) : FlowLogic>() { + class TopupIssuer(val otherPartySession: FlowSession) : FlowLogic>() { companion object { object AWAITING_REQUEST : ProgressTracker.Step("Awaiting issuance request") object ISSUING : ProgressTracker.Step("Issuing asset") @@ -107,7 +104,7 @@ object TopupIssuerFlow { @Throws(CashException::class) override fun call(): List { progressTracker.currentStep = AWAITING_REQUEST - val topupRequest = receive(otherParty).unwrap { + val topupRequest = otherPartySession.receive().unwrap { it } @@ -122,7 +119,7 @@ object TopupIssuerFlow { return@map txn.stx } - send(otherParty, txns) + otherPartySession.send(txns) return txns } // DOCEND TopupIssuer diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt index ac13f8ac66..f16983a6c8 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt @@ -16,8 +16,11 @@ import net.corda.core.node.services.vault.QueryCriteria.VaultQueryCriteria import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.SignedTransaction import net.corda.core.transactions.TransactionBuilder -import net.corda.core.utilities.* +import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker.Step +import net.corda.core.utilities.UntrustworthyData +import net.corda.core.utilities.seconds +import net.corda.core.utilities.unwrap import net.corda.finance.contracts.asset.Cash import net.corda.testing.ALICE_PUBKEY import net.corda.testing.contracts.DUMMY_PROGRAM_ID @@ -39,7 +42,7 @@ object FlowCookbook { @StartableByRPC // Every flow must subclass ``FlowLogic``. The generic indicates the // flow's return type. - class InitiatorFlow(val arg1: Boolean, val arg2: Int, val counterparty: Party, val regulator: Party) : FlowLogic() { + class InitiatorFlow(val arg1: Boolean, val arg2: Int, private val counterparty: Party, val regulator: Party) : FlowLogic() { /**--------------------------------- * WIRING UP THE PROGRESS TRACKER * @@ -135,7 +138,8 @@ object FlowCookbook { // registered to respond to this flow, and has a corresponding // ``receive`` call. // DOCSTART 4 - send(counterparty, Any()) + val counterpartySession = initiateFlow(counterparty) + counterpartySession.send(Any()) // DOCEND 4 // We can wait to receive arbitrary data of a specific type from a @@ -158,7 +162,7 @@ object FlowCookbook { // be what it appears to be! We must unwrap the // ``UntrustworthyData`` using a lambda. // DOCSTART 5 - val packet1: UntrustworthyData = receive(counterparty) + val packet1: UntrustworthyData = counterpartySession.receive() val int: Int = packet1.unwrap { data -> // Perform checking on the object received. // T O D O: Check the received object. @@ -172,7 +176,7 @@ object FlowCookbook { // data sent doesn't need to match the type of the data received // back. // DOCSTART 7 - val packet2: UntrustworthyData = sendAndReceive(counterparty, "You can send and receive any class!") + val packet2: UntrustworthyData = counterpartySession.sendAndReceive("You can send and receive any class!") val boolean: Boolean = packet2.unwrap { data -> // Perform checking on the object received. // T O D O: Check the received object. @@ -185,8 +189,9 @@ object FlowCookbook { // counterparty. A flow can send messages to as many parties as it // likes, and each party can invoke a different response flow. // DOCSTART 6 - send(regulator, Any()) - val packet3: UntrustworthyData = receive(regulator) + val regulatorSession = initiateFlow(regulator) + regulatorSession.send(Any()) + val packet3: UntrustworthyData = regulatorSession.receive() // DOCEND 6 /**----------------------------------- @@ -378,10 +383,10 @@ object FlowCookbook { // for data request until the transaction is resolved and verified // on the other side: // DOCSTART 12 - subFlow(SendTransactionFlow(counterparty, twiceSignedTx)) + subFlow(SendTransactionFlow(counterpartySession, twiceSignedTx)) // Optional request verification to further restrict data access. - subFlow(object : SendTransactionFlow(counterparty, twiceSignedTx) { + subFlow(object : SendTransactionFlow(counterpartySession, twiceSignedTx) { override fun verifyDataRequest(dataRequest: FetchDataFlow.Request.Data) { // Extra request verification. } @@ -392,16 +397,16 @@ object FlowCookbook { // which will automatically download all the dependencies and verify // the transaction // DOCSTART 13 - val verifiedTransaction = subFlow(ReceiveTransactionFlow(counterparty)) + val verifiedTransaction = subFlow(ReceiveTransactionFlow(counterpartySession)) // DOCEND 13 // We can also send and receive a `StateAndRef` dependency chain // and automatically resolve its dependencies. // DOCSTART 14 - subFlow(SendStateAndRefFlow(counterparty, dummyStates)) + subFlow(SendStateAndRefFlow(counterpartySession, dummyStates)) // On the receive side ... - val resolvedStateAndRef = subFlow(ReceiveStateAndRefFlow(counterparty)) + val resolvedStateAndRef = subFlow(ReceiveStateAndRefFlow(counterpartySession)) // DOCEND 14 // We can now verify the transaction to ensure that it satisfies @@ -452,7 +457,7 @@ object FlowCookbook { // other required signers using ``CollectSignaturesFlow``. // The responder flow will need to call ``SignTransactionFlow``. // DOCSTART 15 - val fullySignedTx: SignedTransaction = subFlow(CollectSignaturesFlow(twiceSignedTx, SIGS_GATHERING.childProgressTracker())) + val fullySignedTx: SignedTransaction = subFlow(CollectSignaturesFlow(twiceSignedTx, emptySet(), SIGS_GATHERING.childProgressTracker())) // DOCEND 15 /**----------------------- @@ -488,13 +493,13 @@ object FlowCookbook { // We notarise the transaction and get it recorded in the vault of // the participants of all the transaction's states. // DOCSTART 9 - val notarisedTx1: SignedTransaction = subFlow(FinalityFlow(fullySignedTx, FINALISATION.childProgressTracker())).single() + val notarisedTx1: SignedTransaction = subFlow(FinalityFlow(fullySignedTx, FINALISATION.childProgressTracker())) // DOCEND 9 // We can also choose to send it to additional parties who aren't one // of the state's participants. // DOCSTART 10 val additionalParties: Set = setOf(regulator) - val notarisedTx2: SignedTransaction = subFlow(FinalityFlow(listOf(fullySignedTx), additionalParties, FINALISATION.childProgressTracker())).single() + val notarisedTx2: SignedTransaction = subFlow(FinalityFlow(fullySignedTx, additionalParties, FINALISATION.childProgressTracker())) // DOCEND 10 } } @@ -507,7 +512,7 @@ object FlowCookbook { // Each node also has several flow pairs registered by default - see // ``AbstractNode.installCoreFlows``. @InitiatedBy(InitiatorFlow::class) - class ResponderFlow(val counterparty: Party) : FlowLogic() { + class ResponderFlow(val counterpartySession: FlowSession) : FlowLogic() { companion object { object RECEIVING_AND_SENDING_DATA : Step("Sending data between parties.") @@ -541,9 +546,9 @@ object FlowCookbook { // ``Boolean`` instance back // Our side of the flow must mirror these calls. // DOCSTART 8 - val any: Any = receive(counterparty).unwrap { data -> data } - val string: String = sendAndReceive(counterparty, 99).unwrap { data -> data } - send(counterparty, true) + val any: Any = counterpartySession.receive().unwrap { data -> data } + val string: String = counterpartySession.sendAndReceive(99).unwrap { data -> data } + counterpartySession.send(true) // DOCEND 8 /**---------------------------------------- @@ -555,7 +560,7 @@ object FlowCookbook { // ``CollectSignaturesFlow``. It does so my invoking its own // ``SignTransactionFlow`` subclass. // DOCSTART 16 - val signTransactionFlow: SignTransactionFlow = object : SignTransactionFlow(counterparty) { + val signTransactionFlow: SignTransactionFlow = object : SignTransactionFlow(counterpartySession) { override fun checkTransaction(stx: SignedTransaction) = requireThat { // Any additional checking we see fit... val outputState = stx.tx.outputsOfType().single() diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt index aa0fa394fa..6ccc807d6a 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FxTransactionBuildTutorial.kt @@ -50,7 +50,7 @@ private fun gatherOurInputs(serviceHub: ServiceHub, val eligibleStates = serviceHub.vaultService.tryLockFungibleStatesForSpending(lockId, fullCriteria, amountRequired.withoutIssuer(), Cash.State::class.java) check(eligibleStates.isNotEmpty()) { "Insufficient funds" } - val amount = eligibleStates.fold(0L) { tot, x -> tot + x.state.data.amount.quantity } + val amount = eligibleStates.fold(0L) { tot, (state) -> tot + state.data.amount.quantity } val change = amount - amountRequired.quantity return Pair(eligibleStates, change) @@ -87,25 +87,25 @@ private fun prepareOurInputsAndOutputs(serviceHub: ServiceHub, lockId: UUID, req // A flow representing creating a transaction that // carries out exchange of cash assets. @InitiatingFlow -class ForeignExchangeFlow(val tradeId: String, - val baseCurrencyAmount: Amount>, - val quoteCurrencyAmount: Amount>, - val baseCurrencyBuyer: Party, - val baseCurrencySeller: Party) : FlowLogic() { +class ForeignExchangeFlow(private val tradeId: String, + private val baseCurrencyAmount: Amount>, + private val quoteCurrencyAmount: Amount>, + private val counterparty: Party, + private val weAreBaseCurrencySeller: Boolean) : FlowLogic() { @Suspendable override fun call(): SecureHash { // Select correct sides of the Fx exchange to query for. // Specifically we own the assets we wish to sell. // Also prepare the other side query - val (localRequest, remoteRequest) = if (serviceHub.myInfo.isLegalIdentity(baseCurrencySeller)) { - val local = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer) - val remote = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller) + val (localRequest, remoteRequest) = if (weAreBaseCurrencySeller) { + val local = FxRequest(tradeId, baseCurrencyAmount, ourIdentity, counterparty) + val remote = FxRequest(tradeId, quoteCurrencyAmount, counterparty, ourIdentity) Pair(local, remote) - } else if (serviceHub.myInfo.isLegalIdentity(baseCurrencyBuyer)) { - val local = FxRequest(tradeId, quoteCurrencyAmount, baseCurrencyBuyer, baseCurrencySeller) - val remote = FxRequest(tradeId, baseCurrencyAmount, baseCurrencySeller, baseCurrencyBuyer) + } else { + val local = FxRequest(tradeId, quoteCurrencyAmount, ourIdentity, counterparty) + val remote = FxRequest(tradeId, baseCurrencyAmount, counterparty, ourIdentity) Pair(local, remote) - } else throw IllegalArgumentException("Our identity must be one of the parties in the trade.") + } // Call the helper method to identify suitable inputs and make the outputs val (ourInputStates, ourOutputStates) = prepareOurInputsAndOutputs(serviceHub, runId.uuid, localRequest) @@ -117,9 +117,10 @@ class ForeignExchangeFlow(val tradeId: String, // Send the request to the counterparty to verify and call their version of prepareOurInputsAndOutputs // Then they can return their candidate states - send(remoteRequestWithNotary.owner, remoteRequestWithNotary) - val theirInputStates = subFlow(ReceiveStateAndRefFlow(remoteRequestWithNotary.owner)) - val theirOutputStates = receive>(remoteRequestWithNotary.owner).unwrap { + val counterpartySession = initiateFlow(counterparty) + counterpartySession.send(remoteRequestWithNotary) + val theirInputStates = subFlow(ReceiveStateAndRefFlow(counterpartySession)) + val theirOutputStates = counterpartySession.receive>().unwrap { require(theirInputStates.all { it.state.notary == notary }) { "notary of remote states must be same as for our states" } @@ -144,9 +145,9 @@ class ForeignExchangeFlow(val tradeId: String, val signedTransaction = buildTradeProposal(ourInputStates, ourOutputStates, theirInputStates, theirOutputStates) // pass transaction details to the counterparty to revalidate and confirm with a signature - // Allow otherParty to access our data to resolve the transaction. - subFlow(SendTransactionFlow(remoteRequestWithNotary.owner, signedTransaction)) - val allPartySignedTx = receive(remoteRequestWithNotary.owner).unwrap { + // Allow counterparty to access our data to resolve the transaction. + subFlow(SendTransactionFlow(counterpartySession, signedTransaction)) + val allPartySignedTx = counterpartySession.receive().unwrap { val withNewSignature = signedTransaction + it // check all signatures are present except the notary withNewSignature.verifySignaturesExcept(withNewSignature.tx.notary!!.owningKey) @@ -160,7 +161,7 @@ class ForeignExchangeFlow(val tradeId: String, } // Initiate the standard protocol to notarise and distribute to the involved parties. - subFlow(FinalityFlow(allPartySignedTx, setOf(baseCurrencyBuyer, baseCurrencySeller))) + subFlow(FinalityFlow(allPartySignedTx, setOf(counterparty))) return allPartySignedTx.id } @@ -195,11 +196,11 @@ class ForeignExchangeFlow(val tradeId: String, } @InitiatedBy(ForeignExchangeFlow::class) -class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic() { +class ForeignExchangeRemoteFlow(private val source: FlowSession) : FlowLogic() { @Suspendable override fun call() { // Initial receive from remote party - val request = receive(source).unwrap { + val request = source.receive().unwrap { // We would need to check that this is a known trade ID here! // Also that the amounts and source are correct with the trade details. // In a production system there would be other Corda contracts tracking @@ -209,7 +210,7 @@ class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic() { require(serviceHub.myInfo.isLegalIdentity(it.owner)) { "Request does not include the correct counterparty" } - require(source == it.counterparty) { + require(source.counterparty == it.counterparty) { "Request does not include the correct counterparty" } it // return validated request @@ -224,18 +225,13 @@ class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic() { // Send back our proposed states and await the full transaction to verify val ourKey = serviceHub.keyManagementService.filterMyKeys(ourInputState.flatMap { it.state.data.participants }.map { it.owningKey }).single() - // SendStateAndRefFlow allows otherParty to access our transaction data to resolve the transaction. + // SendStateAndRefFlow allows counterparty to access our transaction data to resolve the transaction. subFlow(SendStateAndRefFlow(source, ourInputState)) - send(source, ourOutputState) + source.send(ourOutputState) val proposedTrade = subFlow(ReceiveTransactionFlow(source, checkSufficientSignatures = false)).let { val wtx = it.tx // check all signatures are present except our own and the notary it.verifySignaturesExcept(ourKey, wtx.notary!!.owningKey) - - // This verifies that the transaction is contract-valid, even though it is missing signatures. - // In a full solution there would be states tracking the trade request which - // would be included in the transaction and enforce the amounts and tradeId - wtx.toLedgerTransaction(serviceHub).verify() it // return the SignedTransaction } @@ -243,7 +239,7 @@ class ForeignExchangeRemoteFlow(private val source: Party) : FlowLogic() { val ourSignature = serviceHub.createSignature(proposedTrade, ourKey) // send the other side our signature. - send(source, ourSignature) + source.send(ourSignature) // N.B. The FinalityProtocol will be responsible for Notarising the SignedTransaction // and broadcasting the result to us. } diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt index b95f6a99ac..2532577f9a 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/WorkflowTransactionBuildTutorial.kt @@ -3,10 +3,7 @@ package net.corda.docs import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* import net.corda.core.crypto.TransactionSignature -import net.corda.core.flows.FinalityFlow -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow +import net.corda.core.flows.* import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.node.services.queryBy @@ -110,7 +107,7 @@ class SubmitTradeApprovalFlow(private val tradeId: String, // We can automatically sign as there is no untrusted data. val signedTx = serviceHub.signInitialTransaction(tx) // Notarise and distribute. - subFlow(FinalityFlow(signedTx, setOf(ourIdentity, counterparty))) + subFlow(FinalityFlow(signedTx, setOf(counterparty))) // Return the initial state return signedTx.tx.outRef(0) } @@ -175,7 +172,8 @@ class SubmitCompletionFlow(private val ref: StateRef, private val verdict: Workf val selfSignedTx = serviceHub.signInitialTransaction(tx) //DOCEND 2 // Send the signed transaction to the originator and await their signature to confirm - val allPartySignedTx = sendAndReceive(newState.source, selfSignedTx).unwrap { + val session = initiateFlow(newState.source) + val allPartySignedTx = session.sendAndReceive(selfSignedTx).unwrap { // Add their signature to our unmodified transaction. To check they signed the same tx. val agreedTx = selfSignedTx + it // Receive back their signature and confirm that it is for an unmodified transaction @@ -189,7 +187,7 @@ class SubmitCompletionFlow(private val ref: StateRef, private val verdict: Workf } // DOCSTART 4 // Notarise and distribute the completed transaction. - subFlow(FinalityFlow(allPartySignedTx, setOf(latestRecord.state.data.source, latestRecord.state.data.counterparty))) + subFlow(FinalityFlow(allPartySignedTx, setOf(newState.source))) // DOCEND 4 // Return back the details of the completed state/transaction. return allPartySignedTx.tx.outRef(0) @@ -202,12 +200,12 @@ class SubmitCompletionFlow(private val ref: StateRef, private val verdict: Workf * transaction to the ledger. */ @InitiatedBy(SubmitCompletionFlow::class) -class RecordCompletionFlow(private val source: Party) : FlowLogic() { +class RecordCompletionFlow(private val sourceSession: FlowSession) : FlowLogic() { @Suspendable override fun call() { // DOCSTART 3 // First we receive the verdict transaction signed by their single key - val completeTx = receive(source).unwrap { + val completeTx = sourceSession.receive().unwrap { // Check the transaction is signed apart from our own key and the notary it.verifySignaturesExcept(ourIdentity.owningKey, it.tx.notary!!.owningKey) // Check the transaction data is correctly formed @@ -223,7 +221,7 @@ class RecordCompletionFlow(private val source: Party) : FlowLogic() { require(serviceHub.myInfo.isLegalIdentity(state.state.data.source)) { "Proposal not one of our original proposals" } - require(state.state.data.counterparty == source) { + require(state.state.data.counterparty == sourceSession.counterparty) { "Proposal not for sent from correct source" } it @@ -232,7 +230,7 @@ class RecordCompletionFlow(private val source: Party) : FlowLogic() { // Having verified the SignedTransaction passed to us we can sign it too val ourSignature = serviceHub.createSignature(completeTx) // Send our signature to the other party. - send(source, ourSignature) + sourceSession.send(ourSignature) // N.B. The FinalityProtocol will be responsible for Notarising the SignedTransaction // and broadcasting the result to us. } diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt index fc84e71509..c3b56f34a1 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt @@ -7,11 +7,11 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.* import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow -import net.corda.node.internal.StartedNode import net.corda.finance.schemas.CashSchemaV1 -import net.corda.nodeapi.ServiceInfo +import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity @@ -76,8 +76,8 @@ class FxTransactionBuildTutorialTest { val doIt = nodeA.services.startFlow(ForeignExchangeFlow("trade1", POUNDS(100).issuedBy(nodeB.info.chooseIdentity().ref(0x01)), DOLLARS(200).issuedBy(nodeA.info.chooseIdentity().ref(0x01)), - nodeA.info.chooseIdentity(), - nodeB.info.chooseIdentity())) + nodeB.info.chooseIdentity(), + weAreBaseCurrencySeller = false)) // wait for the flow to finish and the vault updates to be done doIt.resultFuture.getOrThrow() // Get the balances when the vault updates diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt index 604b63f676..85cb11b422 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt @@ -9,9 +9,9 @@ import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.toFuture import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity diff --git a/finance/src/main/kotlin/net/corda/finance/flows/AbstractCashFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/AbstractCashFlow.kt index f86a3c52d0..e1579fef90 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/AbstractCashFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/AbstractCashFlow.kt @@ -27,9 +27,9 @@ abstract class AbstractCashFlow(override val progressTracker: ProgressTra } @Suspendable - protected fun finaliseTx(participants: Set, tx: SignedTransaction, message: String) { + protected fun finaliseTx(tx: SignedTransaction, extraParticipants: Set, message: String): SignedTransaction { try { - subFlow(FinalityFlow(tx, participants)) + return subFlow(FinalityFlow(tx, extraParticipants)) } catch (e: NotaryException) { throw CashException(message, e) } diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt index 4ba83b2645..63bb087726 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt @@ -44,9 +44,10 @@ class CashExitFlow(private val amount: Amount, @Throws(CashException::class) override fun call(): AbstractCashFlow.Result { progressTracker.currentStep = GENERATING_TX - val builder = TransactionBuilder(notary = null as Party?) + val builder = TransactionBuilder(notary = null) val issuer = ourIdentity.ref(issuerRef) - val exitStates = CashSelection.getInstance { serviceHub.jdbcSession().metaData } + val exitStates = CashSelection + .getInstance { serviceHub.jdbcSession().metaData } .unconsumedCashStatesForSpending(serviceHub, amount, setOf(issuer.party), builder.notary, builder.lockId, setOf(issuer.reference)) val signers = try { Cash().generateExit( @@ -72,8 +73,8 @@ class CashExitFlow(private val amount: Amount, // Commit the transaction progressTracker.currentStep = FINALISING_TX - finaliseTx(participants, tx, "Unable to notarise exit") - return Result(tx, null) + val notarised = finaliseTx(tx, participants, "Unable to notarise exit") + return Result(notarised, null) } @CordaSerializable diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt index 2072a0f214..56f071783a 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashIssueFlow.kt @@ -2,7 +2,6 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Amount -import net.corda.core.flows.FinalityFlow import net.corda.core.flows.StartableByRPC import net.corda.core.identity.Party import net.corda.core.serialization.CordaSerializable @@ -43,7 +42,8 @@ class CashIssueFlow(private val amount: Amount, progressTracker.currentStep = SIGNING_TX val tx = serviceHub.signInitialTransaction(builder, signers) progressTracker.currentStep = FINALISING_TX - val notarised = subFlow(FinalityFlow(tx)).single() + // There is no one to send the tx to as we're the only participants + val notarised = finaliseTx(tx, emptySet(), "Unable to notarise issue") return Result(notarised, ourIdentity) } diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt index 38623c23d2..8f6402a799 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashPaymentFlow.kt @@ -45,7 +45,7 @@ open class CashPaymentFlow( } val anonymousRecipient = txIdentities[recipient] ?: recipient progressTracker.currentStep = GENERATING_TX - val builder = TransactionBuilder(null as Party?) + val builder = TransactionBuilder(notary = null) // TODO: Have some way of restricting this to states the caller controls val (spendTX, keysForSigning) = try { Cash.generateSpend(serviceHub, @@ -61,10 +61,13 @@ open class CashPaymentFlow( val tx = serviceHub.signInitialTransaction(spendTX, keysForSigning) progressTracker.currentStep = FINALISING_TX - finaliseTx(setOf(recipient), tx, "Unable to notarise spend") - return Result(tx, anonymousRecipient) + val notarised = finaliseTx(tx, setOf(recipient), "Unable to notarise spend") + return Result(notarised, anonymousRecipient) } @CordaSerializable - class PaymentRequest(amount: Amount, val recipient: Party, val anonymous: Boolean, val issuerConstraint: Set = emptySet()) : AbstractRequest(amount) -} \ No newline at end of file + class PaymentRequest(amount: Amount, + val recipient: Party, + val anonymous: Boolean, + val issuerConstraint: Set = emptySet()) : AbstractRequest(amount) +} diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index 9aeb2bd755..8398bb37c5 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -3,12 +3,8 @@ package net.corda.finance.flows import co.paralleluniverse.fibers.Suspendable import net.corda.confidential.SwapIdentitiesFlow import net.corda.core.contracts.requireThat -import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature -import net.corda.core.flows.CollectSignaturesFlow -import net.corda.core.flows.FinalityFlow -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.SignTransactionFlow +import net.corda.core.flows.* import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.serialization.CordaSerializable @@ -50,38 +46,38 @@ object TwoPartyDealFlow { abstract val payload: Any abstract val notaryParty: Party - abstract val otherParty: Party + abstract val otherSideSession: FlowSession - @Suspendable override fun call(): SignedTransaction { + @Suspendable + override fun call(): SignedTransaction { progressTracker.currentStep = GENERATING_ID - val txIdentities = subFlow(SwapIdentitiesFlow(otherParty)) + val txIdentities = subFlow(SwapIdentitiesFlow(otherSideSession.counterparty)) val anonymousMe = txIdentities[ourIdentity] ?: ourIdentity.anonymise() - val anonymousCounterparty = txIdentities[otherParty] ?: otherParty.anonymise() + val anonymousCounterparty = txIdentities[otherSideSession.counterparty] ?: otherSideSession.counterparty.anonymise() progressTracker.currentStep = SENDING_PROPOSAL // Make the first message we'll send to kick off the flow. val hello = Handshake(payload, anonymousMe, anonymousCounterparty) // Wait for the FinalityFlow to finish on the other side and return the tx when it's available. - send(otherParty, hello) + otherSideSession.send(hello) - val signTransactionFlow = object : SignTransactionFlow(otherParty) { + val signTransactionFlow = object : SignTransactionFlow(otherSideSession) { override fun checkTransaction(stx: SignedTransaction) = checkProposal(stx) } - subFlow(signTransactionFlow) + val txId = subFlow(signTransactionFlow).id - val txHash = receive(otherParty).unwrap { it } - - return waitForLedgerCommit(txHash) + return waitForLedgerCommit(txId) } - @Suspendable abstract fun checkProposal(stx: SignedTransaction) + @Suspendable + abstract fun checkProposal(stx: SignedTransaction) } /** * Abstracted bilateral deal flow participant that is recipient of initial communication. */ abstract class Secondary(override val progressTracker: ProgressTracker = Secondary.tracker(), - val regulators: List = emptyList()) : FlowLogic() { + val regulators: Set = emptySet()) : FlowLogic() { companion object { object RECEIVING : ProgressTracker.Step("Waiting for deal info.") @@ -89,13 +85,11 @@ object TwoPartyDealFlow { object SIGNING : ProgressTracker.Step("Generating and signing transaction proposal.") object COLLECTING_SIGNATURES : ProgressTracker.Step("Collecting signatures from other parties.") object RECORDING : ProgressTracker.Step("Recording completed transaction.") - object COPYING_TO_REGULATOR : ProgressTracker.Step("Copying regulator.") - object COPYING_TO_COUNTERPARTY : ProgressTracker.Step("Copying counterparty.") - fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING, COLLECTING_SIGNATURES, RECORDING, COPYING_TO_REGULATOR, COPYING_TO_COUNTERPARTY) + fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING, COLLECTING_SIGNATURES, RECORDING) } - abstract val otherParty: Party + abstract val otherSideSession: FlowSession @Suspendable override fun call(): SignedTransaction { @@ -109,31 +103,24 @@ object TwoPartyDealFlow { serviceHub.signInitialTransaction(utx, additionalSigningPubKeys) } - logger.trace { "Signed proposed transaction." } + logger.trace("Signed proposed transaction.") progressTracker.currentStep = COLLECTING_SIGNATURES + // Get signature of initiating side + val ptxSignedByOtherSide = ptx + subFlow(CollectSignatureFlow(ptx, otherSideSession, otherSideSession.counterparty.owningKey)) + // DOCSTART 1 - val stx = subFlow(CollectSignaturesFlow(ptx, additionalSigningPubKeys)) + // Get signatures of other signers + val sessionsForOtherSigners = serviceHub.excludeNotary(serviceHub.groupPublicKeysByWellKnownParty(ptxSignedByOtherSide.getMissingSigners()), ptxSignedByOtherSide).map { initiateFlow(it.key) } + val stx = subFlow(CollectSignaturesFlow(ptxSignedByOtherSide, sessionsForOtherSigners, additionalSigningPubKeys)) // DOCEND 1 - logger.trace { "Got signatures from other party, verifying ... " } + logger.trace("Got signatures from other party, verifying ... ") progressTracker.currentStep = RECORDING - val ftx = subFlow(FinalityFlow(stx, setOf(otherParty, ourIdentity))).single() - - logger.trace { "Recorded transaction." } - - progressTracker.currentStep = COPYING_TO_REGULATOR - - // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's - // just for demo purposes. - regulators.forEach { send(it, ftx) } - - progressTracker.currentStep = COPYING_TO_COUNTERPARTY - // Send the final transaction hash back to the other party. - // We need this so we don't break the IRS demo and the SIMM Demo. - send(otherParty, ftx.id) + val ftx = subFlow(FinalityFlow(stx, regulators + otherSideSession.counterparty)) + logger.trace("Recorded transaction.") return ftx } @@ -142,14 +129,14 @@ object TwoPartyDealFlow { private fun receiveAndValidateHandshake(): Handshake { progressTracker.currentStep = RECEIVING // Wait for a trade request to come in on our pre-provided session ID. - val handshake = receive>(otherParty) + val handshake = otherSideSession.receive>() progressTracker.currentStep = VERIFYING return handshake.unwrap { // Verify the transaction identities represent the correct parties val wellKnownOtherParty = serviceHub.identityService.partyFromAnonymous(it.primaryIdentity) val wellKnownMe = serviceHub.identityService.partyFromAnonymous(it.secondaryIdentity) - require(wellKnownOtherParty == otherParty) + require(wellKnownOtherParty == otherSideSession.counterparty) require(wellKnownMe == ourIdentity) validateHandshake(it) } @@ -167,7 +154,7 @@ object TwoPartyDealFlow { /** * One side of the flow for inserting a pre-agreed deal. */ - open class Instigator(override val otherParty: Party, + open class Instigator(override val otherSideSession: FlowSession, override val payload: AutoOffer, override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { override val notaryParty: Party get() = payload.notary @@ -180,7 +167,7 @@ object TwoPartyDealFlow { /** * One side of the flow for inserting a pre-agreed deal. */ - open class Acceptor(override val otherParty: Party, + open class Acceptor(override val otherSideSession: FlowSession, override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary() { override fun validateHandshake(handshake: Handshake): Handshake { diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index fd83370c6f..57a862041c 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -55,10 +55,10 @@ object TwoPartyTradeFlow { val payToIdentity: PartyAndCertificate ) - open class Seller(val otherParty: Party, - val assetToSell: StateAndRef, - val price: Amount, - val myParty: PartyAndCertificate, // TODO Left because in tests it's used to pass anonymous party. + open class Seller(private val otherSideSession: FlowSession, + private val assetToSell: StateAndRef, + private val price: Amount, + private val myParty: PartyAndCertificate, // TODO Left because in tests it's used to pass anonymous party. override val progressTracker: ProgressTracker = Seller.tracker()) : FlowLogic() { companion object { @@ -80,22 +80,22 @@ object TwoPartyTradeFlow { val hello = SellerTradeInfo(price, myParty) // What we get back from the other side is a transaction that *might* be valid and acceptable to us, // but we must check it out thoroughly before we sign! - // SendTransactionFlow allows otherParty to access our data to resolve the transaction. - subFlow(SendStateAndRefFlow(otherParty, listOf(assetToSell))) - send(otherParty, hello) + // SendTransactionFlow allows seller to access our data to resolve the transaction. + subFlow(SendStateAndRefFlow(otherSideSession, listOf(assetToSell))) + otherSideSession.send(hello) // Verify and sign the transaction. progressTracker.currentStep = VERIFYING_AND_SIGNING // Sync identities to ensure we know all of the identities involved in the transaction we're about to // be asked to sign - subFlow(IdentitySyncFlow.Receive(otherParty)) + subFlow(IdentitySyncFlow.Receive(otherSideSession)) // DOCSTART 5 - val signTransactionFlow = object : SignTransactionFlow(otherParty, VERIFYING_AND_SIGNING.childProgressTracker()) { + val signTransactionFlow = object : SignTransactionFlow(otherSideSession, VERIFYING_AND_SIGNING.childProgressTracker()) { override fun checkTransaction(stx: SignedTransaction) { // Verify that we know who all the participants in the transaction are - val states: Iterable = (stx.tx.inputs.map { serviceHub.loadState(it).data } + stx.tx.outputs.map { it.data }) + val states: Iterable = stx.tx.inputs.map { serviceHub.loadState(it).data } + stx.tx.outputs.map { it.data } states.forEach { state -> state.participants.forEach { anon -> require(serviceHub.identityService.partyFromAnonymous(anon) != null) { @@ -108,8 +108,11 @@ object TwoPartyTradeFlow { throw FlowException("Transaction is not sending us the right amount of cash") } } - return subFlow(signTransactionFlow) + + val txId = subFlow(signTransactionFlow).id // DOCEND 5 + + return waitForLedgerCommit(txId) } // DOCEND 4 @@ -126,13 +129,13 @@ object TwoPartyTradeFlow { // express flow state machines on top of the messaging layer. } - open class Buyer(private val otherParty: Party, + open class Buyer(private val sellerSession: FlowSession, private val notary: Party, private val acceptablePrice: Amount, private val typeToBuy: Class, private val anonymous: Boolean) : FlowLogic() { - constructor(otherParty: Party, notary: Party, acceptablePrice: Amount, typeToBuy: Class) : - this(otherParty, notary, acceptablePrice, typeToBuy, true) + constructor(otherSideSession: FlowSession, notary: Party, acceptablePrice: Amount, typeToBuy: Class) : + this(otherSideSession, notary, acceptablePrice, typeToBuy, true) // DOCSTART 2 object RECEIVING : ProgressTracker.Step("Waiting for seller trading info") @@ -170,22 +173,23 @@ object TwoPartyTradeFlow { val partSignedTx = serviceHub.signInitialTransaction(ptx, cashSigningPubKeys) // Sync up confidential identities in the transaction with our counterparty - subFlow(IdentitySyncFlow.Send(otherParty, ptx.toWireTransaction())) + subFlow(IdentitySyncFlow.Send(sellerSession, ptx.toWireTransaction())) // Send the signed transaction to the seller, who must then sign it themselves and commit // it to the ledger by sending it to the notary. progressTracker.currentStep = COLLECTING_SIGNATURES - val twiceSignedTx = subFlow(CollectSignaturesFlow(partSignedTx, cashSigningPubKeys, COLLECTING_SIGNATURES.childProgressTracker())) + val sellerSignature = subFlow(CollectSignatureFlow(partSignedTx, sellerSession, sellerSession.counterparty.owningKey)) + val twiceSignedTx = partSignedTx + sellerSignature // Notarise and record the transaction. progressTracker.currentStep = RECORDING - return subFlow(FinalityFlow(twiceSignedTx)).single() + return subFlow(FinalityFlow(twiceSignedTx)) } @Suspendable private fun receiveAndValidateTradeRequest(): Pair, SellerTradeInfo> { - val assetForSale = subFlow(ReceiveStateAndRefFlow(otherParty)).single() - return assetForSale to receive(otherParty).unwrap { + val assetForSale = subFlow(ReceiveStateAndRefFlow(sellerSession)).single() + return assetForSale to sellerSession.receive().unwrap { progressTracker.currentStep = VERIFYING // What is the seller trying to sell us? val asset = assetForSale.state.data @@ -194,12 +198,12 @@ object TwoPartyTradeFlow { // The asset must either be owned by the well known identity of the counterparty, or we must be able to // prove the owner is a confidential identity of the counterparty. val assetForSaleIdentity = serviceHub.identityService.partyFromAnonymous(asset.owner) - require(assetForSaleIdentity == otherParty) + require(assetForSaleIdentity == sellerSession.counterparty) // Register the identity we're about to send payment to. This shouldn't be the same as the asset owner // identity, so that anonymity is enforced. val wellKnownPayToIdentity = serviceHub.identityService.verifyAndRegisterIdentity(it.payToIdentity) - require(wellKnownPayToIdentity?.party == otherParty) { "Well known identity to pay to must match counterparty identity" } + require(wellKnownPayToIdentity?.party == sellerSession.counterparty) { "Well known identity to pay to must match counterparty identity" } if (it.price > acceptablePrice) throw UnacceptablePriceException(it.price) diff --git a/finance/src/test/java/net/corda/finance/flows/AbstractStateReplacementFlowTest.java b/finance/src/test/java/net/corda/finance/flows/AbstractStateReplacementFlowTest.java index 3b78a34881..b753141ac5 100644 --- a/finance/src/test/java/net/corda/finance/flows/AbstractStateReplacementFlowTest.java +++ b/finance/src/test/java/net/corda/finance/flows/AbstractStateReplacementFlowTest.java @@ -1,7 +1,7 @@ package net.corda.finance.flows; import net.corda.core.flows.AbstractStateReplacementFlow; -import net.corda.core.identity.Party; +import net.corda.core.flows.FlowSession; import net.corda.core.transactions.SignedTransaction; import net.corda.core.utilities.ProgressTracker; import org.jetbrains.annotations.NotNull; @@ -11,8 +11,8 @@ public class AbstractStateReplacementFlowTest { // Acceptor used to have a type parameter of Unit which prevented Java code from subclassing it (https://youtrack.jetbrains.com/issue/KT-15964). private static class TestAcceptorCanBeInheritedInJava extends AbstractStateReplacementFlow.Acceptor { - public TestAcceptorCanBeInheritedInJava(@NotNull Party otherSide, @NotNull ProgressTracker progressTracker) { - super(otherSide, progressTracker); + public TestAcceptorCanBeInheritedInJava(@NotNull FlowSession otherSideSession, @NotNull ProgressTracker progressTracker) { + super(otherSideSession, progressTracker); } @Override diff --git a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt index ee215040c6..73d5330b12 100644 --- a/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt +++ b/finance/src/test/kotlin/net/corda/finance/flows/CashPaymentFlowTests.kt @@ -38,10 +38,9 @@ class CashPaymentFlowTests { notaryNode = nodes.notaryNode bankOfCordaNode = nodes.partyNodes[0] bankOfCorda = bankOfCordaNode.info.chooseIdentity() - - mockNet.runNetwork() - notary = bankOfCordaNode.services.getDefaultNotary() + notary = notaryNode.services.getDefaultNotary() val future = bankOfCordaNode.services.startFlow(CashIssueFlow(initialBalance, ref, notary)).resultFuture + mockNet.runNetwork() future.getOrThrow() } diff --git a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt index d6ae803077..a46856b2ce 100644 --- a/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/CordappScanningDriverTest.kt @@ -1,19 +1,16 @@ package net.corda.node import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.StartableByRPC +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.startFlow import net.corda.core.utilities.getOrThrow -import net.corda.testing.ALICE -import net.corda.testing.BOB import net.corda.core.utilities.unwrap import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.nodeapi.User +import net.corda.testing.ALICE +import net.corda.testing.BOB import net.corda.testing.chooseIdentity import net.corda.testing.driver.driver import org.assertj.core.api.Assertions.assertThat @@ -41,15 +38,15 @@ class CordappScanningDriverTest { @InitiatingFlow class ReceiveFlow(val otherParty: Party) :FlowLogic() { @Suspendable - override fun call(): String = receive(otherParty).unwrap { it } + override fun call(): String = initiateFlow(otherParty).receive().unwrap { it } } @InitiatedBy(ReceiveFlow::class) - open class SendClassFlow(val otherParty: Party) : FlowLogic() { + open class SendClassFlow(val otherPartySession: FlowSession) : FlowLogic() { @Suspendable - override fun call() = send(otherParty, javaClass.name) + override fun call() = otherPartySession.send(javaClass.name) } @InitiatedBy(ReceiveFlow::class) - class SendSubClassFlow(otherParty: Party) : SendClassFlow(otherParty) + class SendSubClassFlow(otherPartySession: FlowSession) : SendClassFlow(otherPartySession) } diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/FlowVersioningTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/FlowVersioningTest.kt index 7d56427f5a..a32c1eae59 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/FlowVersioningTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/FlowVersioningTest.kt @@ -2,6 +2,7 @@ package net.corda.node.services.statemachine import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose @@ -32,17 +33,18 @@ class FlowVersioningTest : NodeBasedTest() { @Suspendable override fun call(): Pair { // Execute receive() outside of the Pair constructor to avoid Kotlin/Quasar instrumentation bug. - val alicePlatformVersionAccordingToBob = receive(initiatedParty).unwrap { it } + val session = initiateFlow(initiatedParty) + val alicePlatformVersionAccordingToBob = session.receive().unwrap { it } return Pair( alicePlatformVersionAccordingToBob, - getFlowInfo(initiatedParty).flowVersion + session.getCounterpartyFlowInfo().flowVersion ) } } - private class PretendInitiatedCoreFlow(val initiatingParty: Party) : FlowLogic() { + private class PretendInitiatedCoreFlow(val otherSideSession: FlowSession) : FlowLogic() { @Suspendable - override fun call() = send(initiatingParty, getFlowInfo(initiatingParty).flowVersion) + override fun call() = otherSideSession.send(otherSideSession.getCounterpartyFlowInfo().flowVersion) } } \ No newline at end of file diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index b3358408bd..36cd3a6979 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -3,7 +3,6 @@ package net.corda.node.services.statemachine import co.paralleluniverse.fibers.Suspendable import net.corda.core.crypto.SecureHash import net.corda.core.flows.* -import net.corda.core.identity.Party import net.corda.core.internal.InputStreamAndHash import net.corda.core.messaging.startFlow import net.corda.core.transactions.TransactionBuilder @@ -39,18 +38,19 @@ class LargeTransactionsTest { val stx = serviceHub.signInitialTransaction(tx, ourIdentity.owningKey) // Send to the other side and wait for it to trigger resolution from us. val bob = serviceHub.identityService.partyFromX500Name(BOB.name)!! - subFlow(SendTransactionFlow(bob, stx)) - receive(bob) + val bobSession = initiateFlow(bob) + subFlow(SendTransactionFlow(bobSession, stx)) + bobSession.receive() } } @InitiatedBy(SendLargeTransactionFlow::class) @Suppress("UNUSED") - class ReceiveLargeTransactionFlow(private val counterParty: Party) : FlowLogic() { + class ReceiveLargeTransactionFlow(private val otherSide: FlowSession) : FlowLogic() { @Suspendable override fun call() { - subFlow(ReceiveTransactionFlow(counterParty)) + subFlow(ReceiveTransactionFlow(otherSide)) // Unblock the other side by sending some dummy object (Unit is fine here as it's a singleton). - send(counterParty, Unit) + otherSide.send(Unit) } } diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt index e5dff89f39..9caff3474d 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/MQSecurityTest.kt @@ -3,17 +3,16 @@ package net.corda.services.messaging import co.paralleluniverse.fibers.Suspendable import net.corda.client.rpc.CordaRPCClient import net.corda.core.crypto.generateKeyPair -import net.corda.core.utilities.toBase58String +import net.corda.core.crypto.random63BitValue import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party import net.corda.core.messaging.CordaRPCOps import net.corda.core.utilities.NetworkHostAndPort -import net.corda.core.crypto.random63BitValue import net.corda.core.utilities.getOrThrow -import net.corda.testing.ALICE -import net.corda.testing.BOB +import net.corda.core.utilities.toBase58String import net.corda.core.utilities.unwrap import net.corda.node.internal.Node import net.corda.node.internal.StartedNode @@ -25,6 +24,8 @@ import net.corda.nodeapi.ArtemisMessagingComponent.Companion.PEERS_PREFIX import net.corda.nodeapi.RPCApi import net.corda.nodeapi.User import net.corda.nodeapi.config.SSLConfiguration +import net.corda.testing.ALICE +import net.corda.testing.BOB import net.corda.testing.chooseIdentity import net.corda.testing.configureTestSSL import net.corda.testing.messaging.SimpleMQClient @@ -229,12 +230,12 @@ abstract class MQSecurityTest : NodeBasedTest() { @InitiatingFlow private class SendFlow(val otherParty: Party, val payload: Any) : FlowLogic() { @Suspendable - override fun call() = send(otherParty, payload) + override fun call() = initiateFlow(otherParty).send(payload) } @InitiatedBy(SendFlow::class) - private class ReceiveFlow(val otherParty: Party) : FlowLogic() { + private class ReceiveFlow(val otherPartySession: FlowSession) : FlowLogic() { @Suspendable - override fun call() = receive(otherParty).unwrap { it } + override fun call() = otherPartySession.receive().unwrap { it } } } \ No newline at end of file diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index 045ebcf52f..7073632133 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -18,8 +18,8 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.getOrThrow import net.corda.node.services.FlowPermissions -import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.nodeapi.User import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity @@ -151,6 +151,6 @@ class SendMessageFlow(private val message: Message) : FlowLogic>, flowFactory: (Party) -> FlowLogic<*>) { - log.warn(deprecatedFlowConstructorMessage(clientFlowClass.java)) - installCoreFlowExpectingFlowSession(clientFlowClass, { flowSession -> flowFactory(flowSession.counterparty) }) - } - - @VisibleForTesting - fun installCoreFlowExpectingFlowSession(clientFlowClass: KClass>, flowFactory: (FlowSession) -> FlowLogic<*>) { + fun installCoreFlow(clientFlowClass: KClass>, flowFactory: (FlowSession) -> FlowLogic<*>) { require(clientFlowClass.java.flowVersionAndInitiatingClass.first == 1) { "${InitiatingFlow::class.java.name}.version not applicable for core flows; their version is the node's platform version" } @@ -378,7 +371,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, private fun installCoreFlows() { - installCoreFlow(BroadcastTransactionFlow::class, ::NotifyTransactionHandler) + installCoreFlow(FinalityFlow::class, ::FinalityHandler) installCoreFlow(NotaryChangeFlow::class, ::NotaryChangeHandler) installCoreFlow(ContractUpgradeFlow.Initiator::class, ::Acceptor) installCoreFlow(SwapIdentitiesFlow::class, ::SwapIdentitiesHandler) @@ -407,10 +400,10 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, } private fun makeCordappLoader(): CordappLoader { - val scanPackage = System.getProperty("net.corda.node.cordapp.scan.package") - return if (scanPackage != null) { + val scanPackages = System.getProperty("net.corda.node.cordapp.scan.packages") + return if (scanPackages != null) { check(configuration.devMode) { "Package scanning can only occur in dev mode" } - CordappLoader.createDevMode(scanPackage) + CordappLoader.createDevMode(scanPackages) } else { CordappLoader.createDefault(configuration.baseDirectory) } diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt index d35bbb47a8..77d34308e9 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt @@ -57,19 +57,22 @@ class CordappLoader private constructor(private val cordappJarPaths: List) * @param scanPackage Resolves the JARs that contain scanPackage and use them as the source for * the classpath scanning. */ - fun createDevMode(scanPackage: String): CordappLoader { - val resource = scanPackage.replace('.', '/') - val paths = this::class.java.classLoader.getResources(resource) - .asSequence() - .map { - val uri = if (it.protocol == "jar") { - (it.openConnection() as JarURLConnection).jarFileURL.toURI() - } else { - URI(it.toExternalForm().removeSuffix(resource)) + fun createDevMode(scanPackages: String): CordappLoader { + val paths = scanPackages.split(",").flatMap { scanPackage -> + val resource = scanPackage.replace('.', '/') + this::class.java.classLoader.getResources(resource) + .asSequence() + .map { + val uri = if (it.protocol == "jar") { + (it.openConnection() as JarURLConnection).jarFileURL.toURI() + } else { + URI(it.toExternalForm().removeSuffix(resource)) + } + uri.toURL() } - uri.toURL() - } - .toList() + .toList() + } + return CordappLoader(paths) } diff --git a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt index a63985d653..57b6349dc2 100644 --- a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt +++ b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt @@ -1,10 +1,7 @@ package net.corda.node.services import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.AbstractStateReplacementFlow -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.ReceiveTransactionFlow -import net.corda.core.flows.StateReplacementException +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction @@ -12,15 +9,15 @@ import net.corda.core.transactions.SignedTransaction // includes us in any outside that list. Potentially just if it includes any outside that list at all. // TODO: Do we want to be able to reject specific transactions on more complex rules, for example reject incoming // cash without from unknown parties? -class NotifyTransactionHandler(val otherParty: Party) : FlowLogic() { +class FinalityHandler(private val sender: FlowSession) : FlowLogic() { @Suspendable override fun call() { - val stx = subFlow(ReceiveTransactionFlow(otherParty)) + val stx = subFlow(ReceiveTransactionFlow(sender)) serviceHub.recordTransactions(stx) } } -class NotaryChangeHandler(otherSide: Party) : AbstractStateReplacementFlow.Acceptor(otherSide) { +class NotaryChangeHandler(otherSideSession: FlowSession) : AbstractStateReplacementFlow.Acceptor(otherSideSession) { /** * Check the notary change proposal. * diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowSessionInternal.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowSessionInternal.kt index 58f08dfa63..4f2d1ba5fc 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowSessionInternal.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowSessionInternal.kt @@ -18,7 +18,7 @@ class FlowSessionInternal( val ourSessionId: Long, val initiatingParty: Party?, var state: FlowSessionState, - val retryable: Boolean = false) { + var retryable: Boolean = false) { val receivedMessages = ConcurrentLinkedQueue>() val fiber: FlowStateMachineImpl<*> get() = flow.stateMachine as FlowStateMachineImpl<*> @@ -30,14 +30,19 @@ class FlowSessionInternal( /** * [FlowSessionState] describes the session's state. * - * [Initiating] is pre-handshake. [Initiating.otherParty] at this point holds a [Party] corresponding to either a - * specific peer or a service. + * [Uninitiated] is pre-handshake, where no communication has happened. [Initiating.otherParty] at this point holds a + * [Party] corresponding to either a specific peer or a service. + * [Initiating] is pre-handshake, where the initiating message has been sent. * [Initiated] is post-handshake. At this point [Initiating.otherParty] will have been resolved to a specific peer * [Initiated.peerParty], and the peer's sessionId has been initialised. */ sealed class FlowSessionState { abstract val sendToParty: Party + data class Uninitiated(val otherParty: Party) : FlowSessionState() { + override val sendToParty: Party get() = otherParty + } + /** [otherParty] may be a specific peer or a service party */ data class Initiating(val otherParty: Party) : FlowSessionState() { override val sendToParty: Party get() = otherParty diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index 0a1299b591..4f6b4c3dca 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -164,6 +164,16 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, @Suspendable override fun initiateFlow(otherParty: Party, sessionFlow: FlowLogic<*>): FlowSession { + val sessionKey = Pair(sessionFlow, otherParty) + if (openSessions.containsKey(sessionKey)) { + throw IllegalStateException( + "Attempted to initiateFlow() twice in the same InitiatingFlow $sessionFlow for the same party " + + "$otherParty. This isn't supported in this version of Corda. Alternatively you may " + + "initiate a new flow by calling initiateFlow() in an " + + "@${InitiatingFlow::class.java.simpleName} sub-flow." + ) + } + createNewSession(otherParty, sessionFlow) val flowSession = FlowSessionImpl(otherParty) flowSession.stateMachine = this flowSession.sessionFlow = sessionFlow @@ -186,7 +196,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, logger.debug { "sendAndReceive(${receiveType.name}, $otherParty, ${payload.toString().abbreviate(300)}) ..." } val session = getConfirmedSessionIfPresent(otherParty, sessionFlow) val receivedSessionData: ReceivedSessionMessage = if (session == null) { - val newSession = startNewSession(otherParty, sessionFlow, payload, waitForConfirmation = true, retryable = retrySend) + val newSession = initiateSession(otherParty, sessionFlow, payload, waitForConfirmation = true, retryable = retrySend) // Only do a receive here as the session init has carried the payload receiveInternal(newSession, receiveType) } else { @@ -221,7 +231,7 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, val session = getConfirmedSessionIfPresent(otherParty, sessionFlow) if (session == null) { // Don't send the payload again if it was already piggy-backed on a session init - startNewSession(otherParty, sessionFlow, payload, waitForConfirmation = false) + initiateSession(otherParty, sessionFlow, payload, waitForConfirmation = false) } else { sendInternal(session, createSessionData(session, payload)) } @@ -308,8 +318,8 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, private fun createSessionData(session: FlowSessionInternal, payload: Any): SessionData { val sessionState = session.state val peerSessionId = when (sessionState) { - is FlowSessionState.Initiating -> throw IllegalStateException("We've somehow held onto an unconfirmed session: $session") is FlowSessionState.Initiated -> sessionState.peerSessionId + else -> throw IllegalStateException("We've somehow held onto a non-initiated session: $session") } return SessionData(peerSessionId, payload) } @@ -332,37 +342,53 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, @Suspendable private fun getConfirmedSessionIfPresent(otherParty: Party, sessionFlow: FlowLogic<*>): FlowSessionInternal? { - return openSessions[Pair(sessionFlow, otherParty)]?.apply { - if (state is FlowSessionState.Initiating) { - // Session still initiating, wait for the confirmation - waitForConfirmation() + val session = openSessions[Pair(sessionFlow, otherParty)] ?: return null + return when (session.state) { + is FlowSessionState.Uninitiated -> null + is FlowSessionState.Initiating -> { + session.waitForConfirmation() + session } + is FlowSessionState.Initiated -> session } } @Suspendable private fun getConfirmedSession(otherParty: Party, sessionFlow: FlowLogic<*>): FlowSessionInternal { return getConfirmedSessionIfPresent(otherParty, sessionFlow) ?: - startNewSession(otherParty, sessionFlow, null, waitForConfirmation = true) + initiateSession(otherParty, sessionFlow, null, waitForConfirmation = true) } - /** - * Creates a new session. The provided [otherParty] can be an identity of any advertised service on the network, - * and might be advertised by more than one node. Therefore we first choose a single node that advertises it - * and use its *legal identity* for communication. At the moment a single node can compose its legal identity out of - * multiple public keys, but we **don't support multiple nodes advertising the same legal identity**. - */ - @Suspendable - private fun startNewSession(otherParty: Party, - sessionFlow: FlowLogic<*>, - firstPayload: Any?, - waitForConfirmation: Boolean, - retryable: Boolean = false): FlowSessionInternal { - logger.trace { "Initiating a new session with $otherParty" } - val session = FlowSessionInternal(sessionFlow, random63BitValue(), null, FlowSessionState.Initiating(otherParty), retryable) + private fun createNewSession( + otherParty: Party, + sessionFlow: FlowLogic<*> + ) { + logger.trace { "Creating a new session with $otherParty" } + val session = FlowSessionInternal(sessionFlow, random63BitValue(), null, FlowSessionState.Uninitiated(otherParty)) openSessions[Pair(sessionFlow, otherParty)] = session - val (version, initiatingFlowClass) = sessionFlow.javaClass.flowVersionAndInitiatingClass - val sessionInit = SessionInit(session.ourSessionId, initiatingFlowClass.name, version, sessionFlow.javaClass.appName, firstPayload) + } + + @Suspendable + private fun initiateSession( + otherParty: Party, + sessionFlow: FlowLogic<*>, + firstPayload: Any?, + waitForConfirmation: Boolean, + retryable: Boolean = false + ): FlowSessionInternal { + val session = openSessions[Pair(sessionFlow, otherParty)] + if (session == null) { + throw IllegalStateException("Expected an Uninitiated session for $otherParty") + } + val state = session.state + if (state !is FlowSessionState.Uninitiated) { + throw IllegalStateException("Tried to initiate a session $session, but it's already initiating/initiated") + } + logger.trace { "Initiating a new session with ${state.otherParty}" } + session.state = FlowSessionState.Initiating(state.otherParty) + session.retryable = retryable + val (version, initiatingFlowClass) = session.flow.javaClass.flowVersionAndInitiatingClass + val sessionInit = SessionInit(session.ourSessionId, initiatingFlowClass.name, version, session.flow.javaClass.appName, firstPayload) sendInternal(session, sessionInit) if (waitForConfirmation) { session.waitForConfirmation() diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt index bf98b2ff3a..807bcc9415 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/BFTNonValidatingNotaryService.kt @@ -6,6 +6,7 @@ import net.corda.core.contracts.StateRef import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryError import net.corda.core.flows.NotaryException import net.corda.core.identity.CordaX500Name @@ -71,19 +72,19 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal, fun commitTransaction(tx: Any, otherSide: Party) = client.commitTransaction(tx, otherSide) - override fun createServiceFlow(otherParty: Party): FlowLogic = ServiceFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): FlowLogic = ServiceFlow(otherPartySession, this) - private class ServiceFlow(val otherSide: Party, val service: BFTNonValidatingNotaryService) : FlowLogic() { + private class ServiceFlow(val otherSideSession: FlowSession, val service: BFTNonValidatingNotaryService) : FlowLogic() { @Suspendable override fun call(): Void? { - val stx = receive(otherSide).unwrap { it } + val stx = otherSideSession.receive().unwrap { it } val signatures = commit(stx) - send(otherSide, signatures) + otherSideSession.send(signatures) return null } private fun commit(stx: FilteredTransaction): List { - val response = service.commitTransaction(stx, otherSide) + val response = service.commitTransaction(stx, otherSideSession.counterparty) when (response) { is BFTSMaRt.ClusterResponse.Error -> throw NotaryException(response.error) is BFTSMaRt.ClusterResponse.Signatures -> { diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt index 6ebf61de1e..a12d565d52 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/NonValidatingNotaryFlow.kt @@ -1,16 +1,16 @@ package net.corda.node.services.transactions import co.paralleluniverse.fibers.Suspendable +import net.corda.core.flows.FlowSession import net.corda.core.contracts.ComponentGroupEnum import net.corda.core.flows.NotaryFlow import net.corda.core.flows.TransactionParts -import net.corda.core.identity.Party import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.transactions.FilteredTransaction import net.corda.core.transactions.NotaryChangeWireTransaction import net.corda.core.utilities.unwrap -class NonValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryService) : NotaryFlow.Service(otherSide, service) { +class NonValidatingNotaryFlow(otherSideSession: FlowSession, service: TrustedAuthorityNotaryService) : NotaryFlow.Service(otherSideSession, service) { /** * The received transaction is not checked for contract-validity, as that would require fully * resolving it into a [TransactionForVerification], for which the caller would have to reveal the whole transaction @@ -21,7 +21,7 @@ class NonValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryS */ @Suspendable override fun receiveAndVerifyTx(): TransactionParts { - val parts = receive(otherSide).unwrap { + val parts = otherSideSession.receive().unwrap { when (it) { is FilteredTransaction -> { it.verify() diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt index 850f8182c8..6e0916e3cc 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftNonValidatingNotaryService.kt @@ -1,7 +1,7 @@ package net.corda.node.services.transactions +import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow -import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.node.services.api.ServiceHubInternal @@ -16,7 +16,7 @@ class RaftNonValidatingNotaryService(override val services: ServiceHubInternal, override val timeWindowChecker: TimeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider: RaftUniquenessProvider = RaftUniquenessProvider(services) - override fun createServiceFlow(otherParty: Party): NotaryFlow.Service = NonValidatingNotaryFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): NotaryFlow.Service = NonValidatingNotaryFlow(otherPartySession, this) override fun start() { uniquenessProvider.start() diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt index 26fbd333b3..10da5581fe 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/RaftValidatingNotaryService.kt @@ -1,7 +1,7 @@ package net.corda.node.services.transactions +import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow -import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.node.services.api.ServiceHubInternal @@ -16,7 +16,7 @@ class RaftValidatingNotaryService(override val services: ServiceHubInternal, ove override val timeWindowChecker: TimeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider: RaftUniquenessProvider = RaftUniquenessProvider(services) - override fun createServiceFlow(otherParty: Party): NotaryFlow.Service = ValidatingNotaryFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): NotaryFlow.Service = ValidatingNotaryFlow(otherPartySession, this) override fun start() { uniquenessProvider.start() diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt index 0df32048b3..f27d4e7478 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt @@ -1,7 +1,7 @@ package net.corda.node.services.transactions +import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow -import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.nodeapi.ServiceType @@ -17,7 +17,7 @@ class SimpleNotaryService(override val services: ServiceHubInternal, override va override val timeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider = PersistentUniquenessProvider() - override fun createServiceFlow(otherParty: Party): NotaryFlow.Service = NonValidatingNotaryFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): NotaryFlow.Service = NonValidatingNotaryFlow(otherPartySession, this) override fun start() {} override fun stop() {} diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt index a7ee9f1228..cf871f7f0f 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryFlow.kt @@ -3,7 +3,6 @@ package net.corda.node.services.transactions import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.TransactionVerificationException import net.corda.core.flows.* -import net.corda.core.identity.Party import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.core.transactions.SignedTransaction import java.security.SignatureException @@ -14,7 +13,7 @@ import java.security.SignatureException * has its input states "blocked" by a transaction from another party, and needs to establish whether that transaction was * indeed valid. */ -class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryService) : NotaryFlow.Service(otherSide, service) { +class ValidatingNotaryFlow(otherSideSession: FlowSession, service: TrustedAuthorityNotaryService) : NotaryFlow.Service(otherSideSession, service) { /** * The received transaction is checked for contract-validity, which requires fully resolving it into a * [TransactionForVerification], for which the caller also has to to reveal the whole transaction @@ -23,7 +22,7 @@ class ValidatingNotaryFlow(otherSide: Party, service: TrustedAuthorityNotaryServ @Suspendable override fun receiveAndVerifyTx(): TransactionParts { try { - val stx = subFlow(ReceiveTransactionFlow(otherSide, checkSufficientSignatures = false)) + val stx = subFlow(ReceiveTransactionFlow(otherSideSession, checkSufficientSignatures = false)) val notary = stx.notary checkNotary(notary) checkSignatures(stx) diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt index 76a0c83674..e3f7289393 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt @@ -1,7 +1,7 @@ package net.corda.node.services.transactions +import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow -import net.corda.core.identity.Party import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService import net.corda.nodeapi.ServiceType @@ -17,7 +17,7 @@ class ValidatingNotaryService(override val services: ServiceHubInternal, overrid override val timeWindowChecker = TimeWindowChecker(services.clock) override val uniquenessProvider = PersistentUniquenessProvider() - override fun createServiceFlow(otherParty: Party): NotaryFlow.Service = ValidatingNotaryFlow(otherParty, this) + override fun createServiceFlow(otherPartySession: FlowSession): NotaryFlow.Service = ValidatingNotaryFlow(otherPartySession, this) override fun start() {} override fun stop() {} diff --git a/node/src/smoke-test/kotlin/net/corda/node/CordappSmokeTest.kt b/node/src/smoke-test/kotlin/net/corda/node/CordappSmokeTest.kt index 7a67198558..bd2d072d64 100644 --- a/node/src/smoke-test/kotlin/net/corda/node/CordappSmokeTest.kt +++ b/node/src/smoke-test/kotlin/net/corda/node/CordappSmokeTest.kt @@ -4,7 +4,10 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.* import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.internal.* +import net.corda.core.internal.copyToDirectory +import net.corda.core.internal.createDirectories +import net.corda.core.internal.div +import net.corda.core.internal.list import net.corda.core.messaging.startFlow import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap @@ -68,21 +71,22 @@ class CordappSmokeTest { override fun call(): Pair { // This receive will kick off SendBackInitiatorFlowContext by sending a session-init with our app name. // SendBackInitiatorFlowContext will send back our context using the information from this session-init - val sessionInitContext = receive(otherParty).unwrap { it } + val session = initiateFlow(otherParty) + val sessionInitContext = session.receive().unwrap { it } // This context is taken from the session-confirm message - val sessionConfirmContext = getFlowInfo(otherParty) + val sessionConfirmContext = session.getCounterpartyFlowInfo() return Pair(sessionInitContext, sessionConfirmContext) } } @Suppress("unused") @InitiatedBy(GatherContextsFlow::class) - class SendBackInitiatorFlowContext(private val otherParty: Party) : FlowLogic() { + class SendBackInitiatorFlowContext(private val otherPartySession: FlowSession) : FlowLogic() { @Suspendable override fun call() { // An initiated flow calling getFlowContext on its initiator will get the context from the session-init - val sessionInitContext = getFlowInfo(otherParty) - send(otherParty, sessionInitContext) + val sessionInitContext = otherPartySession.getCounterpartyFlowInfo() + otherPartySession.send(sessionInitContext) } } } diff --git a/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt b/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt index 1ff641e4d4..b239ac01d6 100644 --- a/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt +++ b/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt @@ -1,20 +1,21 @@ package net.corda.node.cordapp import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy -import net.corda.node.internal.cordapp.Cordapp +import net.corda.core.flows.InitiatingFlow import net.corda.node.internal.cordapp.CordappLoader -import org.junit.Assert +import org.assertj.core.api.Assertions.assertThat import org.junit.Test import java.nio.file.Paths -import org.assertj.core.api.Assertions.assertThat +@InitiatingFlow class DummyFlow : FlowLogic() { override fun call() { } } @InitiatedBy(DummyFlow::class) -class LoaderTestFlow : FlowLogic() { +class LoaderTestFlow(unusedSession: FlowSession) : FlowLogic() { override fun call() { } } diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 55afe46acb..74d0d43886 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -4,10 +4,7 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.concurrent.CordaFuture import net.corda.core.contracts.* import net.corda.core.crypto.* -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.StateMachineRunId +import net.corda.core.flows.* import net.corda.core.identity.AbstractParty import net.corda.core.identity.AnonymousParty import net.corda.core.identity.CordaX500Name @@ -562,9 +559,10 @@ class TwoPartyTradeFlowTests { } else { ourIdentityAndCert } - send(buyer, TestTx(notary, price, anonymous)) + val buyerSession = initiateFlow(buyer) + buyerSession.send(TestTx(notary, price, anonymous)) return subFlow(Seller( - buyer, + buyerSession, assetToSell, price, myPartyAndCert)) @@ -572,14 +570,14 @@ class TwoPartyTradeFlowTests { } @InitiatedBy(SellerInitiator::class) - class BuyerAcceptor(private val seller: Party) : FlowLogic() { + class BuyerAcceptor(private val sellerSession: FlowSession) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - val (notary, price, anonymous) = receive(seller).unwrap { + val (notary, price, anonymous) = sellerSession.receive().unwrap { require(serviceHub.networkMapCache.isNotary(it.notaryIdentity)) { "${it.notaryIdentity} is not a notary" } it } - return subFlow(Buyer(seller, notary, price, CommercialPaper.State::class.java, anonymous)) + return subFlow(Buyer(sellerSession, notary, price, CommercialPaper.State::class.java, anonymous)) } } diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index f4b7d79de1..73b9058561 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -4,7 +4,6 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.concurrent.CordaFuture import net.corda.core.contracts.* import net.corda.core.flows.* -import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.node.services.VaultQueryService import net.corda.core.node.services.queryBy @@ -16,10 +15,10 @@ import net.corda.core.node.services.vault.SortAttribute import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.transactions.ValidatingNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID @@ -50,15 +49,15 @@ class ScheduledFlowTests { val processed: Boolean = false, override val linearId: UniqueIdentifier = UniqueIdentifier()) : SchedulableState, LinearState { override fun nextScheduledActivity(thisStateRef: StateRef, flowLogicRefFactory: FlowLogicRefFactory): ScheduledActivity? { - if (!processed) { + return if (!processed) { val logicRef = flowLogicRefFactory.create(ScheduledFlow::class.java, thisStateRef) - return ScheduledActivity(logicRef, creationTime) + ScheduledActivity(logicRef, creationTime) } else { - return null + null } } - override val participants: List = listOf(source, destination) + override val participants: List get() = listOf(source, destination) } class InsertInitialStateFlow(private val destination: Party) : FlowLogic() { @@ -70,7 +69,7 @@ class ScheduledFlowTests { .addOutputState(scheduledState, DUMMY_PROGRAM_ID) .addCommand(dummyCommand(ourIdentity.owningKey)) val tx = serviceHub.signInitialTransaction(builder) - subFlow(FinalityFlow(tx, setOf(ourIdentity))) + subFlow(FinalityFlow(tx)) } } @@ -92,7 +91,7 @@ class ScheduledFlowTests { .addOutputState(newStateOutput, DUMMY_PROGRAM_ID) .addCommand(dummyCommand(ourIdentity.owningKey)) val tx = serviceHub.signInitialTransaction(builder) - subFlow(FinalityFlow(tx, setOf(scheduledState.source, scheduledState.destination))) + subFlow(FinalityFlow(tx, setOf(scheduledState.destination))) } } diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt index 3d2956d069..da94d376aa 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapCacheTest.kt @@ -2,6 +2,7 @@ package net.corda.node.services.network import co.paralleluniverse.fibers.Suspendable import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.CordaX500Name @@ -170,17 +171,18 @@ class PersistentNetworkMapCacheTest : NodeBasedTest() { override fun call(): String { println("SEND FLOW to $otherParty") println("Party key ${otherParty.owningKey.toBase58String()}") - return sendAndReceive(otherParty, "Hi!").unwrap { it } + val session = initiateFlow(otherParty) + return session.sendAndReceive("Hi!").unwrap { it } } } @InitiatedBy(SendFlow::class) - private class SendBackFlow(val otherParty: Party) : FlowLogic() { + private class SendBackFlow(val otherSideSession: FlowSession) : FlowLogic() { @Suspendable override fun call() { - println("SEND BACK FLOW to $otherParty") - println("Party key ${otherParty.owningKey.toBase58String()}") - send(otherParty, "Hello!") + println("SEND BACK FLOW to ${otherSideSession.counterparty}") + println("Party key ${otherSideSession.counterparty.owningKey.toBase58String()}") + otherSideSession.send("Hello!") } } } diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/DataVendingServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/persistence/DataVendingServiceTests.kt deleted file mode 100644 index 84305dab78..0000000000 --- a/node/src/test/kotlin/net/corda/node/services/persistence/DataVendingServiceTests.kt +++ /dev/null @@ -1,116 +0,0 @@ -package net.corda.node.services.persistence - -import co.paralleluniverse.fibers.Suspendable -import net.corda.core.contracts.Amount -import net.corda.core.contracts.Issued -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.SendTransactionFlow -import net.corda.core.identity.Party -import net.corda.core.node.services.queryBy -import net.corda.core.transactions.SignedTransaction -import net.corda.core.transactions.TransactionBuilder -import net.corda.finance.USD -import net.corda.finance.contracts.asset.Cash -import net.corda.node.internal.StartedNode -import net.corda.node.services.NotifyTransactionHandler -import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.MEGA_CORP -import net.corda.testing.chooseIdentity -import net.corda.testing.node.MockNetwork -import org.assertj.core.api.Assertions.assertThat -import org.junit.After -import org.junit.Before -import org.junit.Test -import kotlin.test.assertEquals - -/** - * Tests for the data vending service. - */ -class DataVendingServiceTests { - lateinit var mockNet: MockNetwork - - @Before - fun setup() { - mockNet = MockNetwork() - } - - @After - fun cleanUp() { - mockNet.stopNodes() - } - - @Test - fun `notify of transaction`() { - val nodes = mockNet.createSomeNodes(2) - val vaultServiceNode = nodes.partyNodes[0] - val registerNode = nodes.partyNodes[1] - val beneficiary = vaultServiceNode.info.chooseIdentity() - val deposit = registerNode.info.chooseIdentity().ref(1) - mockNet.runNetwork() - - // Generate an issuance transaction - val ptx = TransactionBuilder(null) - Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) - - // Complete the cash transaction, and then manually relay it - val tx = registerNode.services.signInitialTransaction(ptx) - vaultServiceNode.database.transaction { - assertThat(vaultServiceNode.services.vaultQueryService.queryBy().states.isEmpty()) - - registerNode.sendNotifyTx(tx, vaultServiceNode) - - // Check the transaction is in the receiving node - val actual = vaultServiceNode.services.vaultQueryService.queryBy().states.singleOrNull() - val expected = tx.tx.outRef(0) - assertEquals(expected, actual) - } - } - - /** - * Test that invalid transactions are rejected. - */ - @Test - fun `notify failure`() { - val nodes = mockNet.createSomeNodes(2) - val vaultServiceNode = nodes.partyNodes[0] - val registerNode = nodes.partyNodes[1] - val beneficiary = vaultServiceNode.info.chooseIdentity() - val deposit = MEGA_CORP.ref(1) - mockNet.runNetwork() - - // Generate an issuance transaction - val ptx = TransactionBuilder(DUMMY_NOTARY) - Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY) - - // The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid - val tx = registerNode.services.signInitialTransaction(ptx) - vaultServiceNode.database.transaction { - assertThat(vaultServiceNode.services.vaultQueryService.queryBy().states.isEmpty()) - - registerNode.sendNotifyTx(tx, vaultServiceNode) - - // Check the transaction is not in the receiving node - assertThat(vaultServiceNode.services.vaultQueryService.queryBy().states.isEmpty()) - } - } - - private fun StartedNode<*>.sendNotifyTx(tx: SignedTransaction, walletServiceNode: StartedNode<*>) { - walletServiceNode.internals.registerInitiatedFlow(InitiateNotifyTxFlow::class.java) - services.startFlow(NotifyTxFlow(walletServiceNode.info.chooseIdentity(), tx)) - mockNet.runNetwork() - } - - @InitiatingFlow - private class NotifyTxFlow(val otherParty: Party, val stx: SignedTransaction) : FlowLogic() { - @Suspendable - override fun call() = subFlow(SendTransactionFlow(otherParty, stx)) - } - - @InitiatedBy(NotifyTxFlow::class) - private class InitiateNotifyTxFlow(val otherParty: Party) : FlowLogic() { - @Suspendable - override fun call() = subFlow(NotifyTransactionHandler(otherParty)) - } -} diff --git a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt index 5e9698b68b..d7b90b8880 100644 --- a/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/schema/NodeSchemaServiceTest.kt @@ -37,7 +37,7 @@ class NodeSchemaServiceTest { /** * Note: this test verifies auto-scanning to register identified [MappedSchema] schemas. * By default, Driver uses the caller package for auto-scanning: - * System.setProperty("net.corda.node.cordapp.scan.package", callerPackage) + * System.setProperty("net.corda.node.cordapp.scan.packages", callerPackage) */ @Test fun `auto scanning of custom schemas for testing with Driver`() { diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index a383eb3396..64d6af905e 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -124,7 +124,7 @@ class FlowFrameworkTests { @Test fun `exception while fiber suspended`() { - node2.registerFlowFactory(ReceiveFlow::class) { SendFlow("Hello", it) } + node2.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow("Hello", it) } val flow = ReceiveFlow(node2.info.chooseIdentity()) val fiber = node1.services.startFlow(flow) as FlowStateMachineImpl // Before the flow runs change the suspend action to throw an exception @@ -143,7 +143,7 @@ class FlowFrameworkTests { @Test fun `flow restarted just after receiving payload`() { - node2.registerFlowFactory(SendFlow::class) { ReceiveFlow(it).nonTerminating() } + node2.registerFlowFactory(SendFlow::class) { InitiatedReceiveFlow(it).nonTerminating() } node1.services.startFlow(SendFlow("Hello", node2.info.chooseIdentity())) // We push through just enough messages to get only the payload sent @@ -152,7 +152,7 @@ class FlowFrameworkTests { node2.internals.acceptableLiveFiberCountOnStop = 1 node2.dispose() mockNet.runNetwork() - val restoredFlow = node2.restartAndGetRestoredFlow(node1) + val restoredFlow = node2.restartAndGetRestoredFlow(node1) assertThat(restoredFlow.receivedPayloads[0]).isEqualTo("Hello") } @@ -195,7 +195,7 @@ class FlowFrameworkTests { @Test fun `flow loaded from checkpoint will respond to messages from before start`() { - node1.registerFlowFactory(ReceiveFlow::class) { SendFlow("Hello", it) } + node1.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow("Hello", it) } node2.services.startFlow(ReceiveFlow(node1.info.chooseIdentity()).nonTerminating()) // Prepare checkpointed receive flow // Make sure the add() has finished initial processing. node2.smm.executor.flush() @@ -260,13 +260,13 @@ class FlowFrameworkTests { fun `sending to multiple parties`() { val node3 = mockNet.createNode(node1.network.myAddress) mockNet.runNetwork() - node2.registerFlowFactory(SendFlow::class) { ReceiveFlow(it).nonTerminating() } - node3.registerFlowFactory(SendFlow::class) { ReceiveFlow(it).nonTerminating() } + node2.registerFlowFactory(SendFlow::class) { InitiatedReceiveFlow(it).nonTerminating() } + node3.registerFlowFactory(SendFlow::class) { InitiatedReceiveFlow(it).nonTerminating() } val payload = "Hello World" node1.services.startFlow(SendFlow(payload, node2.info.chooseIdentity(), node3.info.chooseIdentity())) mockNet.runNetwork() - val node2Flow = node2.getSingleFlow().first - val node3Flow = node3.getSingleFlow().first + val node2Flow = node2.getSingleFlow().first + val node3Flow = node3.getSingleFlow().first assertThat(node2Flow.receivedPayloads[0]).isEqualTo(payload) assertThat(node3Flow.receivedPayloads[0]).isEqualTo(payload) @@ -294,8 +294,8 @@ class FlowFrameworkTests { mockNet.runNetwork() val node2Payload = "Test 1" val node3Payload = "Test 2" - node2.registerFlowFactory(ReceiveFlow::class) { SendFlow(node2Payload, it) } - node3.registerFlowFactory(ReceiveFlow::class) { SendFlow(node3Payload, it) } + node2.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow(node2Payload, it) } + node3.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow(node3Payload, it) } val multiReceiveFlow = ReceiveFlow(node2.info.chooseIdentity(), node3.info.chooseIdentity()).nonTerminating() node1.services.startFlow(multiReceiveFlow) node1.internals.acceptableLiveFiberCountOnStop = 1 @@ -420,10 +420,11 @@ class FlowFrameworkTests { @Suspendable override fun call() { // Kick off the flow on the other side ... - send(otherParty, 1) + val session = initiateFlow(otherParty) + session.send(1) // ... then pause this one until it's received the session-end message from the other side receivedOtherFlowEnd.acquire() - sendAndReceive(otherParty, 2) + session.sendAndReceive(2) } } @@ -543,14 +544,14 @@ class FlowFrameworkTests { ) } - private class ConditionalExceptionFlow(val otherParty: Party, val sendPayload: Any) : FlowLogic() { + private class ConditionalExceptionFlow(val otherPartySession: FlowSession, val sendPayload: Any) : FlowLogic() { @Suspendable override fun call() { - val throwException = receive(otherParty).unwrap { it } + val throwException = otherPartySession.receive().unwrap { it } if (throwException) { throw MyFlowException("Throwing exception as requested") } - send(otherParty, sendPayload) + otherPartySession.send(sendPayload) } } @@ -559,7 +560,7 @@ class FlowFrameworkTests { @InitiatingFlow class AskForExceptionFlow(val otherParty: Party, val throwException: Boolean) : FlowLogic() { @Suspendable - override fun call(): String = sendAndReceive(otherParty, throwException).unwrap { it } + override fun call(): String = initiateFlow(otherParty).sendAndReceive(throwException).unwrap { it } } class RetryOnExceptionFlow(val otherParty: Party) : FlowLogic() { @@ -581,7 +582,7 @@ class FlowFrameworkTests { @Test fun `serialisation issue in counterparty`() { - node2.registerFlowFactory(ReceiveFlow::class) { SendFlow(NonSerialisableData(1), it) } + node2.registerFlowFactory(ReceiveFlow::class) { InitiatedSendFlow(NonSerialisableData(1), it) } val result = node1.services.startFlow(ReceiveFlow(node2.info.chooseIdentity())).resultFuture mockNet.runNetwork() assertThatExceptionOfType(UnexpectedFlowEndException::class.java).isThrownBy { @@ -651,7 +652,7 @@ class FlowFrameworkTests { @Test fun `customised client flow`() { - val receiveFlowFuture = node2.registerFlowFactory(SendFlow::class) { ReceiveFlow(it) } + val receiveFlowFuture = node2.registerFlowFactory(SendFlow::class) { InitiatedReceiveFlow(it) } node1.services.startFlow(CustomSendFlow("Hello", node2.info.chooseIdentity())).resultFuture mockNet.runNetwork() assertThat(receiveFlowFuture.getOrThrow().receivedPayloads).containsOnly("Hello") @@ -668,7 +669,7 @@ class FlowFrameworkTests { @Test fun `upgraded initiating flow`() { - node2.registerFlowFactory(UpgradedFlow::class, initiatedFlowVersion = 1) { SendFlow("Old initiated", it) } + node2.registerFlowFactory(UpgradedFlow::class, initiatedFlowVersion = 1) { InitiatedSendFlow("Old initiated", it) } val result = node1.services.startFlow(UpgradedFlow(node2.info.chooseIdentity())).resultFuture mockNet.runNetwork() assertThat(receivedSessionMessages).startsWith( @@ -684,13 +685,13 @@ class FlowFrameworkTests { fun `upgraded initiated flow`() { node2.registerFlowFactory(SendFlow::class, initiatedFlowVersion = 2) { UpgradedFlow(it) } val initiatingFlow = SendFlow("Old initiating", node2.info.chooseIdentity()) - node1.services.startFlow(initiatingFlow) + val flowInfo = node1.services.startFlow(initiatingFlow).resultFuture mockNet.runNetwork() assertThat(receivedSessionMessages).startsWith( node1 sent sessionInit(SendFlow::class, flowVersion = 1, payload = "Old initiating") to node2, node2 sent sessionConfirm(flowVersion = 2) to node1 ) - assertThat(initiatingFlow.getFlowInfo(node2.info.chooseIdentity()).flowVersion).isEqualTo(2) + assertThat(flowInfo.get().flowVersion).isEqualTo(2) } @Test @@ -736,6 +737,23 @@ class FlowFrameworkTests { assertThat(result.getOrThrow()).isEqualTo("HelloHello") } + @Test + fun `double initiateFlow throws`() { + val future = node1.services.startFlow(DoubleInitiatingFlow()).resultFuture + mockNet.runNetwork() + assertThatExceptionOfType(IllegalStateException::class.java) + .isThrownBy { future.getOrThrow() } + .withMessageContaining("Attempted to initiateFlow() twice") + } + + @InitiatingFlow + private class DoubleInitiatingFlow : FlowLogic() { + @Suspendable + override fun call() { + initiateFlow(serviceHub.myInfo.chooseIdentity()) + initiateFlow(serviceHub.myInfo.chooseIdentity()) + } + } //////////////////////////////////////////////////////////////////////////////////////////////////////////// //region Helpers @@ -754,16 +772,7 @@ class FlowFrameworkTests { return smm.findStateMachines(P::class.java).single() } - @Deprecated("Use registerFlowFactoryExpectingFlowSession() instead") private inline fun > StartedNode<*>.registerFlowFactory( - initiatingFlowClass: KClass>, - initiatedFlowVersion: Int = 1, - noinline flowFactory: (Party) -> P): CordaFuture

- { - return registerFlowFactoryExpectingFlowSession(initiatingFlowClass, initiatedFlowVersion, { flowFactory(it.counterparty) }) - } - - private inline fun > StartedNode<*>.registerFlowFactoryExpectingFlowSession( initiatingFlowClass: KClass>, initiatedFlowVersion: Int = 1, noinline flowFactory: (FlowSession) -> P): CordaFuture

@@ -858,13 +867,25 @@ class FlowFrameworkTests { } @InitiatingFlow - private open class SendFlow(val payload: Any, vararg val otherParties: Party) : FlowLogic() { + private open class SendFlow(val payload: Any, vararg val otherParties: Party) : FlowLogic() { init { require(otherParties.isNotEmpty()) } @Suspendable - override fun call() = otherParties.forEach { send(it, payload) } + override fun call(): FlowInfo { + val flowInfos = otherParties.map { + val session = initiateFlow(it) + session.send(payload) + session.getCounterpartyFlowInfo() + }.toList() + return flowInfos.first() + } + } + + private open class InitiatedSendFlow(val payload: Any, val otherPartySession: FlowSession) : FlowLogic() { + @Suspendable + override fun call() = otherPartySession.send(payload) } private interface CustomInterface @@ -890,7 +911,7 @@ class FlowFrameworkTests { @Suspendable override fun call() { progressTracker.currentStep = START_STEP - receivedPayloads = otherParties.map { receive(it).unwrap { it } } + receivedPayloads = otherParties.map { initiateFlow(it).receive().unwrap { it } } progressTracker.currentStep = RECEIVED_STEP if (nonTerminating) { Fiber.park() @@ -903,26 +924,54 @@ class FlowFrameworkTests { } } - @InitiatingFlow - private class SendAndReceiveFlow(val otherParty: Party, val payload: Any) : FlowLogic() { - @Suspendable - override fun call(): Any = sendAndReceive(otherParty, payload).unwrap { it } - } + private class InitiatedReceiveFlow(val otherPartySession: FlowSession) : FlowLogic() { + object START_STEP : ProgressTracker.Step("Starting") + object RECEIVED_STEP : ProgressTracker.Step("Received") + + override val progressTracker: ProgressTracker = ProgressTracker(START_STEP, RECEIVED_STEP) + private var nonTerminating: Boolean = false + @Transient + var receivedPayloads: List = emptyList() - private class InlinedSendFlow(val payload: String, val otherParty: Party) : FlowLogic() { @Suspendable - override fun call() = send(otherParty, payload) + override fun call() { + progressTracker.currentStep = START_STEP + receivedPayloads = listOf(otherPartySession.receive().unwrap { it }) + progressTracker.currentStep = RECEIVED_STEP + if (nonTerminating) { + Fiber.park() + } + } + + fun nonTerminating(): InitiatedReceiveFlow { + nonTerminating = true + return this + } } @InitiatingFlow - private class PingPongFlow(val otherParty: Party, val payload: Long) : FlowLogic() { + private class SendAndReceiveFlow(val otherParty: Party, val payload: Any, val otherPartySession: FlowSession? = null) : FlowLogic() { + constructor(otherPartySession: FlowSession, payload: Any) : this(otherPartySession.counterparty, payload, otherPartySession) + @Suspendable + override fun call(): Any = (otherPartySession ?: initiateFlow(otherParty)).sendAndReceive(payload).unwrap { it } + } + + private class InlinedSendFlow(val payload: String, val otherPartySession: FlowSession) : FlowLogic() { + @Suspendable + override fun call() = otherPartySession.send(payload) + } + + @InitiatingFlow + private class PingPongFlow(val otherParty: Party, val payload: Long, val otherPartySession: FlowSession? = null) : FlowLogic() { + constructor(otherPartySession: FlowSession, payload: Long) : this(otherPartySession.counterparty, payload, otherPartySession) @Transient var receivedPayload: Long? = null @Transient var receivedPayload2: Long? = null @Suspendable override fun call() { - receivedPayload = sendAndReceive(otherParty, payload).unwrap { it } - receivedPayload2 = sendAndReceive(otherParty, payload + 1).unwrap { it } + val session = otherPartySession ?: initiateFlow(otherParty) + receivedPayload = session.sendAndReceive(payload).unwrap { it } + receivedPayload2 = session.sendAndReceive(payload + 1).unwrap { it } } } @@ -950,17 +999,18 @@ class FlowFrameworkTests { class Waiter(val stx: SignedTransaction, val otherParty: Party) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - send(otherParty, stx) + val otherPartySession = initiateFlow(otherParty) + otherPartySession.send(stx) return waitForLedgerCommit(stx.id) } } - class Committer(val otherParty: Party, val throwException: (() -> Exception)? = null) : FlowLogic() { + class Committer(val otherPartySession: FlowSession, val throwException: (() -> Exception)? = null) : FlowLogic() { @Suspendable override fun call(): SignedTransaction { - val stx = receive(otherParty).unwrap { it } + val stx = otherPartySession.receive().unwrap { it } if (throwException != null) throw throwException.invoke() - return subFlow(FinalityFlow(stx, setOf(otherParty))).single() + return subFlow(FinalityFlow(stx, setOf(otherPartySession.counterparty))) } } } @@ -969,7 +1019,8 @@ class FlowFrameworkTests { private class VaultQueryFlow(val stx: SignedTransaction, val otherParty: Party) : FlowLogic>>() { @Suspendable override fun call(): List> { - send(otherParty, stx) + val otherPartySession = initiateFlow(otherParty) + otherPartySession.send(stx) // hold onto reference here to force checkpoint of vaultQueryService and thus // prove it is registered as a tokenizableService in the node val vaultQuerySvc = serviceHub.vaultQueryService @@ -979,27 +1030,29 @@ class FlowFrameworkTests { } @InitiatingFlow(version = 2) - private class UpgradedFlow(val otherParty: Party) : FlowLogic>() { + private class UpgradedFlow(val otherParty: Party, val otherPartySession: FlowSession? = null) : FlowLogic>() { + constructor(otherPartySession: FlowSession) : this(otherPartySession.counterparty, otherPartySession) @Suspendable override fun call(): Pair { - val received = receive(otherParty).unwrap { it } - val otherFlowVersion = getFlowInfo(otherParty).flowVersion + val otherPartySession = this.otherPartySession ?: initiateFlow(otherParty) + val received = otherPartySession.receive().unwrap { it } + val otherFlowVersion = otherPartySession.getCounterpartyFlowInfo().flowVersion return Pair(received, otherFlowVersion) } } - private class SingleInlinedSubFlow(val otherParty: Party) : FlowLogic() { + private class SingleInlinedSubFlow(val otherPartySession: FlowSession) : FlowLogic() { @Suspendable override fun call() { - val payload = receive(otherParty).unwrap { it } - subFlow(InlinedSendFlow(payload + payload, otherParty)) + val payload = otherPartySession.receive().unwrap { it } + subFlow(InlinedSendFlow(payload + payload, otherPartySession)) } } - private class DoubleInlinedSubFlow(val otherParty: Party) : FlowLogic() { + private class DoubleInlinedSubFlow(val otherPartySession: FlowSession) : FlowLogic() { @Suspendable override fun call() { - subFlow(SingleInlinedSubFlow(otherParty)) + subFlow(SingleInlinedSubFlow(otherPartySession)) } } diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt index 76dbece304..630255cd71 100644 --- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt +++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt @@ -106,7 +106,9 @@ private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash. } @StartableByRPC -class AttachmentDemoFlow(val otherSide: Party, val notary: Party, val hash: SecureHash.SHA256) : FlowLogic() { +class AttachmentDemoFlow(private val otherSide: Party, + private val notary: Party, + private val attachId: SecureHash.SHA256) : FlowLogic() { object SIGNING : ProgressTracker.Step("Signing transaction") @@ -116,16 +118,16 @@ class AttachmentDemoFlow(val otherSide: Party, val notary: Party, val hash: Secu override fun call(): SignedTransaction { // Create a trivial transaction with an output that describes the attachment, and the attachment itself val ptx = TransactionBuilder(notary) - .addOutputState(AttachmentContract.State(hash), ATTACHMENT_PROGRAM_ID) + .addOutputState(AttachmentContract.State(attachId), ATTACHMENT_PROGRAM_ID) .addCommand(AttachmentContract.Command, ourIdentity.owningKey) - .addAttachment(hash) + .addAttachment(attachId) progressTracker.currentStep = SIGNING // Send the transaction to the other recipient val stx = serviceHub.signInitialTransaction(ptx) - return subFlow(FinalityFlow(stx, setOf(otherSide))).single() + return subFlow(FinalityFlow(stx, setOf(otherSide))) } } diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt index f477701a0b..b7d931d99d 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt @@ -13,7 +13,7 @@ import kotlin.test.assertTrue class BankOfCordaHttpAPITest { @Test fun `issuer flow via Http`() { - driver(dsl = { + driver(extraCordappPackagesToScan = listOf("net.corda.finance"), dsl = { val bigCorpNodeFuture = startNode(providedName = BIGCORP_LEGAL_NAME) val nodeBankOfCordaFuture = startNode(providedName = BOC.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val (nodeBankOfCorda) = listOf(nodeBankOfCordaFuture, bigCorpNodeFuture).map { it.getOrThrow() } diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index 34c659fa58..fdd53846ff 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -18,7 +18,7 @@ import org.junit.Test class BankOfCordaRPCClientTest { @Test fun `issuer flow via RPC`() { - driver(dsl = { + driver(extraCordappPackagesToScan = listOf("net.corda.finance"), dsl = { val bocManager = User("bocManager", "password1", permissions = setOf( startFlowPermission())) val bigCorpCFO = User("bigCorpCFO", "password2", permissions = emptySet()) diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt index ddf3d488ee..a28d299d24 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/api/NodeInterestRates.kt @@ -4,11 +4,7 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Command import net.corda.core.crypto.MerkleTreeException import net.corda.core.crypto.TransactionSignature -import net.corda.core.flows.FlowException -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.StartableByRPC -import net.corda.core.identity.Party +import net.corda.core.flows.* import net.corda.core.internal.ThreadBox import net.corda.core.node.ServiceHub import net.corda.core.node.services.CordaService @@ -46,17 +42,17 @@ import kotlin.collections.set object NodeInterestRates { // DOCSTART 2 @InitiatedBy(RatesFixFlow.FixSignFlow::class) - class FixSignHandler(private val otherParty: Party) : FlowLogic() { + class FixSignHandler(private val otherPartySession: FlowSession) : FlowLogic() { @Suspendable override fun call() { - val request = receive(otherParty).unwrap { it } + val request = otherPartySession.receive().unwrap { it } val oracle = serviceHub.cordaService(Oracle::class.java) - send(otherParty, oracle.sign(request.ftx)) + otherPartySession.send(oracle.sign(request.ftx)) } } @InitiatedBy(RatesFixFlow.FixQueryFlow::class) - class FixQueryHandler(private val otherParty: Party) : FlowLogic() { + class FixQueryHandler(private val otherPartySession: FlowSession) : FlowLogic() { object RECEIVED : ProgressTracker.Step("Received fix request") object SENDING : ProgressTracker.Step("Sending fix response") @@ -64,12 +60,12 @@ object NodeInterestRates { @Suspendable override fun call() { - val request = receive(otherParty).unwrap { it } + val request = otherPartySession.receive().unwrap { it } progressTracker.currentStep = RECEIVED val oracle = serviceHub.cordaService(Oracle::class.java) val answers = oracle.query(request.queries) progressTracker.currentStep = SENDING - send(otherParty, answers) + otherPartySession.send(answers) } } // DOCEND 2 diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt index f57bb5f14e..4e2f09331a 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/AutoOfferFlow.kt @@ -1,12 +1,7 @@ package net.corda.irs.flows import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.StartableByRPC -import net.corda.core.identity.AbstractParty -import net.corda.core.identity.Party +import net.corda.core.flows.* import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.ProgressTracker import net.corda.finance.contracts.DealState @@ -50,22 +45,19 @@ object AutoOfferFlow { require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } val notary = serviceHub.networkMapCache.notaryIdentities.first() // TODO We should pass the notary as a parameter to the flow, not leave it to random choice. // need to pick which ever party is not us - val otherParty = notUs(dealToBeOffered.participants).map { serviceHub.identityService.partyFromAnonymous(it) }.requireNoNulls().single() + val otherParty = serviceHub.excludeMe(serviceHub.groupAbstractPartyByWellKnownParty(dealToBeOffered.participants)).keys.single() progressTracker.currentStep = DEALING + val session = initiateFlow(otherParty) val instigator = Instigator( - otherParty, + session, AutoOffer(notary, dealToBeOffered), progressTracker.getChildProgressTracker(DEALING)!! ) val stx = subFlow(instigator) return stx } - - private fun notUs(parties: List): List { - return parties.filter { ourIdentity != it } - } } @InitiatedBy(Requester::class) - class AutoOfferAcceptor(otherParty: Party) : Acceptor(otherParty) + class AutoOfferAcceptor(otherSideSession: FlowSession) : Acceptor(otherSideSession) } diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt index f020df2552..e44cc055cc 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt @@ -3,10 +3,7 @@ package net.corda.irs.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* import net.corda.core.crypto.TransactionSignature -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.SchedulableFlow +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.node.NodeInfo import net.corda.core.serialization.CordaSerializable @@ -28,7 +25,7 @@ object FixingFlow { * who does what in the flow. */ @InitiatedBy(FixingRoleDecider::class) - class Fixer(override val otherParty: Party) : TwoPartyDealFlow.Secondary() { + class Fixer(override val otherSideSession: FlowSession) : TwoPartyDealFlow.Secondary() { private lateinit var txState: TransactionState<*> private lateinit var deal: FixableDealState @@ -91,7 +88,7 @@ object FixingFlow { * is just the "side" of the flow run by the party with the floating leg as a way of deciding who * does what in the flow. */ - class Floater(override val otherParty: Party, + class Floater(override val otherSideSession: FlowSession, override val payload: FixingSession, override val progressTracker: ProgressTracker = TwoPartyDealFlow.Primary.tracker()) : TwoPartyDealFlow.Primary() { @Suppress("UNCHECKED_CAST") @@ -141,7 +138,8 @@ object FixingFlow { val fixing = FixingSession(ref, fixableDeal.oracle) val counterparty = serviceHub.identityService.partyFromAnonymous(parties[1]) ?: throw IllegalStateException("Cannot resolve floater party") // Start the Floater which will then kick-off the Fixer - subFlow(Floater(counterparty, fixing)) + val session = initiateFlow(counterparty) + subFlow(Floater(session, fixing)) } } } diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt index 9276444df7..b4646ff7be 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/RatesFixFlow.kt @@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable import net.corda.core.crypto.TransactionSignature import net.corda.core.crypto.isFulfilledBy import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party import net.corda.core.serialization.CordaSerializable @@ -97,8 +98,9 @@ open class RatesFixFlow(protected val tx: TransactionBuilder, class FixQueryFlow(val fixOf: FixOf, val oracle: Party) : FlowLogic() { @Suspendable override fun call(): Fix { + val oracleSession = initiateFlow(oracle) // TODO: add deadline to receive - val resp = sendAndReceive>(oracle, QueryRequest(listOf(fixOf))) + val resp = oracleSession.sendAndReceive>(QueryRequest(listOf(fixOf))) return resp.unwrap { val fix = it.first() @@ -114,9 +116,10 @@ open class RatesFixFlow(protected val tx: TransactionBuilder, val partialMerkleTx: FilteredTransaction) : FlowLogic() { @Suspendable override fun call(): TransactionSignature { - val resp = sendAndReceive(oracle, SignRequest(partialMerkleTx)) + val oracleSession = initiateFlow(oracle) + val resp = oracleSession.sendAndReceive(SignRequest(partialMerkleTx)) return resp.unwrap { sig -> - check(oracle.owningKey.isFulfilledBy(listOf(sig.by))) + check(oracleSession.counterparty.owningKey.isFulfilledBy(listOf(sig.by))) tx.toWireTransaction().checkSignature(sig) sig } diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt index 92f0bc52f8..1e36a3bc86 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/flows/UpdateBusinessDayFlow.kt @@ -6,6 +6,8 @@ import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.StartableByRPC import net.corda.core.identity.Party +import net.corda.core.flows.* +import net.corda.core.node.NodeInfo import net.corda.core.serialization.CordaSerializable import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.unwrap @@ -21,10 +23,10 @@ object UpdateBusinessDayFlow { data class UpdateBusinessDayMessage(val date: LocalDate) @InitiatedBy(Broadcast::class) - private class UpdateBusinessDayHandler(val otherParty: Party) : FlowLogic() { + private class UpdateBusinessDayHandler(val otherPartySession: FlowSession) : FlowLogic() { @Suspendable override fun call() { - val message = receive(otherParty).unwrap { it } + val message = otherPartySession.receive().unwrap { it } (serviceHub.clock as TestClock).updateDate(message.date) } } @@ -63,7 +65,7 @@ object UpdateBusinessDayFlow { @Suspendable private fun doNextRecipient(recipient: Party) { - send(recipient, UpdateBusinessDayMessage(date)) + initiateFlow(recipient).send(UpdateBusinessDayMessage(date)) } } } \ No newline at end of file diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt index 6e3c665303..4642412d9b 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/IRSSimulation.kt @@ -6,6 +6,7 @@ import com.fasterxml.jackson.module.kotlin.readValue import net.corda.client.jackson.JacksonSupport import net.corda.core.contracts.StateAndRef import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy import net.corda.core.flows.InitiatingFlow import net.corda.core.identity.Party @@ -143,11 +144,14 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten class StartDealFlow(val otherParty: Party, val payload: AutoOffer) : FlowLogic() { @Suspendable - override fun call(): SignedTransaction = subFlow(Instigator(otherParty, payload)) + override fun call(): SignedTransaction { + val session = initiateFlow(otherParty) + return subFlow(Instigator(session, payload)) + } } @InitiatedBy(StartDealFlow::class) - class AcceptDealFlow(otherParty: Party) : Acceptor(otherParty) + class AcceptDealFlow(otherSession: FlowSession) : Acceptor(otherSession) val acceptDealFlows: Observable = node2.internals.registerInitiatedFlow(AcceptDealFlow::class.java) diff --git a/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt b/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt index bb843910e1..8d9f7284d4 100644 --- a/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt +++ b/samples/network-visualiser/src/test/kotlin/net/corda/netmap/simulation/IRSSimulationTest.kt @@ -11,7 +11,9 @@ class IRSSimulationTest { LogHelper.setLevel("+messages") // FIXME: Don't manipulate static state in tests. val sim = IRSSimulation(false, false, null) val future = sim.start() - while (!future.isDone) sim.iterate() + while (!future.isDone) { + sim.iterate() + } future.getOrThrow() } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt index d3816e680e..0856383a0d 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/IRSTradeFlow.kt @@ -1,10 +1,7 @@ package net.corda.vega.flows import co.paralleluniverse.fibers.Suspendable -import net.corda.core.flows.FlowLogic -import net.corda.core.flows.InitiatedBy -import net.corda.core.flows.InitiatingFlow -import net.corda.core.flows.StartableByRPC +import net.corda.core.flows.* import net.corda.core.identity.Party import net.corda.core.serialization.CordaSerializable import net.corda.core.transactions.SignedTransaction @@ -33,28 +30,29 @@ object IRSTradeFlow { val offer = IRSState(swap, buyer, seller) logger.info("Handshake finished, sending IRS trade offer message") - val otherPartyAgreeFlag = sendAndReceive(otherParty, OfferMessage(notary, offer)).unwrap { it } + val session = initiateFlow(otherParty) + val otherPartyAgreeFlag = session.sendAndReceive(OfferMessage(notary, offer)).unwrap { it } require(otherPartyAgreeFlag) return subFlow(TwoPartyDealFlow.Instigator( - otherParty, + session, TwoPartyDealFlow.AutoOffer(notary, offer))) } } @InitiatedBy(Requester::class) - class Receiver(private val replyToParty: Party) : FlowLogic() { + class Receiver(private val replyToSession: FlowSession) : FlowLogic() { @Suspendable override fun call() { logger.info("IRSTradeFlow receiver started") logger.info("Handshake finished, awaiting IRS trade offer") - val offer = receive(replyToParty).unwrap { it } + val offer = replyToSession.receive().unwrap { it } // Automatically agree - in reality we'd vet the offer message require(serviceHub.networkMapCache.notaryIdentities.contains(offer.notary)) - send(replyToParty, true) - subFlow(TwoPartyDealFlow.Acceptor(replyToParty)) + replyToSession.send(true) + subFlow(TwoPartyDealFlow.Acceptor(replyToSession)) } } } diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index b5c9c5ca79..852777bdfe 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -12,6 +12,7 @@ import net.corda.core.contracts.StateAndRef import net.corda.core.contracts.StateRef import net.corda.core.flows.* import net.corda.core.flows.AbstractStateReplacementFlow.Proposal +import net.corda.core.identity.AbstractParty import net.corda.core.identity.Party import net.corda.core.node.services.queryBy import net.corda.core.node.services.vault.QueryCriteria.LinearStateQueryCriteria @@ -57,6 +58,7 @@ object SimmFlow { : FlowLogic>() { constructor(otherParty: Party, valuationDate: LocalDate) : this(otherParty, valuationDate, null) lateinit var notary: Party + lateinit var otherPartySession: FlowSession @Suspendable override fun call(): RevisionedState { @@ -68,6 +70,7 @@ object SimmFlow { val trades = serviceHub.vaultQueryService.queryBy(criteria).states val portfolio = Portfolio(trades, valuationDate) + otherPartySession = initiateFlow(otherParty) if (existing == null) { agreePortfolio(portfolio) } else { @@ -86,18 +89,24 @@ object SimmFlow { val parties = Pair(ourIdentity, otherParty) val portfolioState = PortfolioState(portfolio.refs, parties, valuationDate) - send(otherParty, OfferMessage(notary, portfolioState, existing?.ref, valuationDate)) + otherPartySession.send(OfferMessage(notary, portfolioState, existing?.ref, valuationDate)) logger.info("Awaiting two party deal acceptor") - subFlow(TwoPartyDealFlow.Acceptor(otherParty)) + subFlow(TwoPartyDealFlow.Acceptor(otherPartySession)) } @Suspendable private fun updatePortfolio(portfolio: Portfolio, stateAndRef: StateAndRef) { // Receive is a hack to ensure other side is ready - sendAndReceive(otherParty, OfferMessage(notary, stateAndRef.state.data, existing?.ref, valuationDate)) + otherPartySession.sendAndReceive(OfferMessage(notary, stateAndRef.state.data, existing?.ref, valuationDate)) logger.info("Updating portfolio") val update = PortfolioState.Update(portfolio = portfolio.refs) - subFlow(StateRevisionFlow.Requester(stateAndRef, update)) + subFlow(StateRevisionFlowRequester(otherPartySession, stateAndRef, update)) + } + + private class StateRevisionFlowRequester(val session: FlowSession, stateAndRef: StateAndRef>, update: T) : StateRevisionFlow.Requester(stateAndRef, update) { + override fun getParticipantSessions(): List>> { + return listOf(session to listOf(session.counterparty)) + } } @Suspendable @@ -110,7 +119,7 @@ object SimmFlow { require(valuer != null) { "Valuer party must be known to this node" } val valuation = agreeValuation(portfolio, valuationDate, valuer!!) val update = PortfolioState.Update(valuation = valuation) - return subFlow(StateRevisionFlow.Requester(stateRef, update)).state.data + return subFlow(StateRevisionFlowRequester(otherPartySession, stateRef, update)).state.data } @Suspendable @@ -165,7 +174,7 @@ object SimmFlow { // TODO: In the real world, this would be tolerance aware for different types @Suspendable private inline fun agree(data: T): Boolean { - val valid = receive(otherParty).unwrap { + val valid = otherPartySession.receive().unwrap { logger.trace("Comparing --> $it") logger.trace("with -------> $data") if (it is InitialMarginTriple && data is InitialMarginTriple) { @@ -175,7 +184,7 @@ object SimmFlow { } } logger.trace("valid is $valid") - send(otherParty, valid) + otherPartySession.send(valid) return valid } } @@ -184,16 +193,16 @@ object SimmFlow { * Receives and validates a portfolio and comes to consensus over the portfolio initial margin using SIMM. */ @InitiatedBy(Requester::class) - class Receiver(val replyToParty: Party) : FlowLogic() { + class Receiver(val replyToSession: FlowSession) : FlowLogic() { lateinit var offer: OfferMessage @Suspendable override fun call() { - val criteria = LinearStateQueryCriteria(participants = listOf(replyToParty)) + val criteria = LinearStateQueryCriteria(participants = listOf(replyToSession.counterparty)) val trades = serviceHub.vaultQueryService.queryBy(criteria).states val portfolio = Portfolio(trades) logger.info("SimmFlow receiver started") - offer = receive(replyToParty).unwrap { it } + offer = replyToSession.receive().unwrap { it } if (offer.stateRef == null) { agreePortfolio(portfolio) } else { @@ -205,8 +214,8 @@ object SimmFlow { @Suspendable private fun agree(data: Any): Boolean { - send(replyToParty, data) - return receive(replyToParty).unwrap { it } + replyToSession.send(data) + return replyToSession.receive().unwrap { it } } /** @@ -287,17 +296,17 @@ object SimmFlow { require(offer.dealBeingOffered.portfolio == portfolio.refs) val seller = TwoPartyDealFlow.Instigator( - replyToParty, + replyToSession, TwoPartyDealFlow.AutoOffer(offer.notary, offer.dealBeingOffered)) - logger.info("Starting two party deal initiator with: ${replyToParty.name}") + logger.info("Starting two party deal initiator with: ${replyToSession.counterparty.name}") return subFlow(seller) } @Suspendable private fun updatePortfolio(portfolio: Portfolio) { logger.info("Handshake finished, awaiting Simm update") - send(replyToParty, Ack) // Hack to state that this party is ready. - subFlow(object : StateRevisionFlow.Receiver(replyToParty) { + replyToSession.send(Ack) // Hack to state that this party is ready. + subFlow(object : StateRevisionFlow.Receiver(replyToSession) { override fun verifyProposal(stx:SignedTransaction, proposal: Proposal) { super.verifyProposal(stx, proposal) if (proposal.modification.portfolio != portfolio.refs) throw StateReplacementException() @@ -310,7 +319,7 @@ object SimmFlow { val portfolio = serviceHub.vaultQueryService.queryBy(VaultQueryCriteria(stateRefs = stateRef.state.data.portfolio)).states.toPortfolio() val valuer = serviceHub.identityService.partyFromAnonymous(stateRef.state.data.valuer) ?: throw IllegalStateException("Unknown valuer party ${stateRef.state.data.valuer}") val valuation = agreeValuation(portfolio, offer.valuationDate, valuer) - subFlow(object : StateRevisionFlow.Receiver(replyToParty) { + subFlow(object : StateRevisionFlow.Receiver(replyToSession) { override fun verifyProposal(stx: SignedTransaction, proposal: Proposal) { super.verifyProposal(stx, proposal) if (proposal.modification.valuation != valuation) throw StateReplacementException() diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt index 10b2d4ee58..49918f85c3 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/StateRevisionFlow.kt @@ -3,8 +3,8 @@ package net.corda.vega.flows import net.corda.core.contracts.PrivacySalt import net.corda.core.contracts.StateAndRef import net.corda.core.flows.AbstractStateReplacementFlow +import net.corda.core.flows.FlowSession import net.corda.core.flows.StateReplacementException -import net.corda.core.identity.Party import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.seconds import net.corda.vega.contracts.RevisionedState @@ -14,7 +14,7 @@ import net.corda.vega.contracts.RevisionedState * on the update between two parties. */ object StateRevisionFlow { - class Requester(curStateRef: StateAndRef>, + open class Requester(curStateRef: StateAndRef>, updatedData: T) : AbstractStateReplacementFlow.Instigator, RevisionedState, T>(curStateRef, updatedData) { override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx { val state = originalState.state.data @@ -22,16 +22,12 @@ object StateRevisionFlow { tx.setTimeWindow(serviceHub.clock.instant(), 30.seconds) val privacySalt = PrivacySalt() tx.setPrivacySalt(privacySalt) - val stx = serviceHub.signInitialTransaction(tx) - val participantKeys = state.participants.map { it.owningKey } - // TODO: We need a much faster way of finding our key in the transaction - val myKey = serviceHub.keyManagementService.filterMyKeys(participantKeys).single() - return AbstractStateReplacementFlow.UpgradeTx(stx, participantKeys, myKey) + return AbstractStateReplacementFlow.UpgradeTx(stx) } } - open class Receiver(otherParty: Party) : AbstractStateReplacementFlow.Acceptor(otherParty) { + open class Receiver(initiatingSession: FlowSession) : AbstractStateReplacementFlow.Acceptor(initiatingSession) { override fun verifyProposal(stx: SignedTransaction, proposal: AbstractStateReplacementFlow.Proposal) { val proposedTx = stx.tx val state = proposal.stateRef diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 68900d95fe..329e144b2b 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -9,14 +9,10 @@ import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CommercialPaperSchemaV1 import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService +import net.corda.nodeapi.ServiceInfo import net.corda.nodeapi.User -import net.corda.testing.BOC -import net.corda.testing.DUMMY_BANK_A -import net.corda.testing.DUMMY_BANK_B -import net.corda.testing.DUMMY_NOTARY -import net.corda.testing.chooseIdentity +import net.corda.testing.* import net.corda.testing.driver.poll import net.corda.testing.node.NodeBasedTest import net.corda.traderdemo.flow.BuyerFlow diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt index 2c4cffbaf8..70cee50154 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/BuyerFlow.kt @@ -3,6 +3,7 @@ package net.corda.traderdemo.flow import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.Amount import net.corda.core.flows.FlowLogic +import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatedBy import net.corda.core.identity.Party import net.corda.core.internal.Emoji @@ -16,7 +17,7 @@ import net.corda.traderdemo.TransactionGraphSearch import java.util.* @InitiatedBy(SellerFlow::class) -class BuyerFlow(val otherParty: Party) : FlowLogic() { +class BuyerFlow(private val otherSideSession: FlowSession) : FlowLogic() { object STARTING_BUY : ProgressTracker.Step("Seller connected, purchasing commercial paper asset") @@ -27,11 +28,11 @@ class BuyerFlow(val otherParty: Party) : FlowLogic() { progressTracker.currentStep = STARTING_BUY // Receive the offered amount and automatically agree to it (in reality this would be a longer negotiation) - val amount = receive>(otherParty).unwrap { it } + val amount = otherSideSession.receive>().unwrap { it } require(serviceHub.networkMapCache.notaryIdentities.isNotEmpty()) { "No notary nodes registered" } val notary: Party = serviceHub.networkMapCache.notaryIdentities.first() val buyer = TwoPartyTradeFlow.Buyer( - otherParty, + otherSideSession, notary, amount, CommercialPaper.State::class.java) diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt index f89aafd091..297f033ca1 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/CommercialPaperIssueFlow.kt @@ -54,7 +54,7 @@ class CommercialPaperIssueFlow(private val amount: Amount, // Sign it as ourselves. val stx = serviceHub.signInitialTransaction(tx) - subFlow(FinalityFlow(stx)).single() + subFlow(FinalityFlow(stx)) } // Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works. @@ -62,10 +62,9 @@ class CommercialPaperIssueFlow(private val amount: Amount, val builder = TransactionBuilder(notary) CommercialPaper().generateMove(builder, issuance.tx.outRef(0), recipient) val stx = serviceHub.signInitialTransaction(builder) - subFlow(FinalityFlow(stx)).single() + subFlow(FinalityFlow(stx)) } return move } - } diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt index f0f5f91bcb..890885227f 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/flow/SellerFlow.kt @@ -45,9 +45,10 @@ class SellerFlow(private val otherParty: Party, progressTracker.currentStep = TRADING // Send the offered amount. - send(otherParty, amount) + val session = initiateFlow(otherParty) + session.send(amount) val seller = TwoPartyTradeFlow.Seller( - otherParty, + session, commercialPaper, amount, cpOwner, diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt index dd5c6c081a..0420e61b54 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/RPCDriver.kt @@ -225,6 +225,7 @@ fun rpcDriver( initialiseSerialization: Boolean = true, networkMapStartStrategy: NetworkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = false), startNodesInProcess: Boolean = false, + extraCordappPackagesToScan: List = emptyList(), dsl: RPCDriverExposedDSLInterface.() -> A ) = genericDriver( driverDsl = RPCDriverDSL( @@ -236,7 +237,8 @@ fun rpcDriver( useTestClock = useTestClock, networkMapStartStrategy = networkMapStartStrategy, isDebug = isDebug, - startNodesInProcess = startNodesInProcess + startNodesInProcess = startNodesInProcess, + extraCordappPackagesToScan = extraCordappPackagesToScan ) ), coerce = { it }, diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index e9522358e1..6b1484e260 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -310,6 +310,7 @@ fun driver( initialiseSerialization: Boolean = defaultParameters.initialiseSerialization, networkMapStartStrategy: NetworkMapStartStrategy = defaultParameters.networkMapStartStrategy, startNodesInProcess: Boolean = defaultParameters.startNodesInProcess, + extraCordappPackagesToScan: List = defaultParameters.extraCordappPackagesToScan, dsl: DriverDSLExposedInterface.() -> A ): A { return genericDriver( @@ -319,9 +320,10 @@ fun driver( systemProperties = systemProperties, driverDirectory = driverDirectory.toAbsolutePath(), useTestClock = useTestClock, + isDebug = isDebug, networkMapStartStrategy = networkMapStartStrategy, startNodesInProcess = startNodesInProcess, - isDebug = isDebug + extraCordappPackagesToScan = extraCordappPackagesToScan ), coerce = { it }, dsl = dsl, @@ -355,7 +357,8 @@ data class DriverParameters( val useTestClock: Boolean = false, val initialiseSerialization: Boolean = true, val networkMapStartStrategy: NetworkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = true), - val startNodesInProcess: Boolean = false + val startNodesInProcess: Boolean = false, + val extraCordappPackagesToScan: List = emptyList() ) { fun setIsDebug(isDebug: Boolean) = copy(isDebug = isDebug) fun setDriverDirectory(driverDirectory: Path) = copy(driverDirectory = driverDirectory) @@ -366,6 +369,7 @@ data class DriverParameters( fun setInitialiseSerialization(initialiseSerialization: Boolean) = copy(initialiseSerialization = initialiseSerialization) fun setNetworkMapStartStrategy(networkMapStartStrategy: NetworkMapStartStrategy) = copy(networkMapStartStrategy = networkMapStartStrategy) fun setStartNodesInProcess(startNodesInProcess: Boolean) = copy(startNodesInProcess = startNodesInProcess) + fun setExtraCordappPackagesToScan(extraCordappPackagesToScan: List) = copy(extraCordappPackagesToScan = extraCordappPackagesToScan) } /** @@ -579,14 +583,15 @@ class DriverDSL( val useTestClock: Boolean, val isDebug: Boolean, val networkMapStartStrategy: NetworkMapStartStrategy, - val startNodesInProcess: Boolean + val startNodesInProcess: Boolean, + val extraCordappPackagesToScan: List ) : DriverDSLInternalInterface { private val dedicatedNetworkMapAddress = portAllocation.nextHostAndPort() private var _executorService: ScheduledExecutorService? = null val executorService get() = _executorService!! private var _shutdownManager: ShutdownManager? = null override val shutdownManager get() = _shutdownManager!! - private val callerPackage = getCallerPackage() + private val packagesToScanString = (extraCordappPackagesToScan + getCallerPackage()).joinToString(",") class State { val processes = ArrayList>() @@ -786,7 +791,7 @@ class DriverDSL( _executorService = Executors.newScheduledThreadPool(2, ThreadFactoryBuilder().setNameFormat("driver-pool-thread-%d").build()) _shutdownManager = ShutdownManager(executorService) // We set this property so that in-process nodes find cordapps. Out-of-process nodes need this passed in when started. - System.setProperty("net.corda.node.cordapp.scan.package", callerPackage) + System.setProperty("net.corda.node.cordapp.scan.packages", packagesToScanString) if (networkMapStartStrategy.startDedicated) { startDedicatedNetworkMapService().andForget(log) // Allow it to start concurrently with other nodes. } @@ -840,7 +845,7 @@ class DriverDSL( } } else { val debugPort = if (isDebug) debugPortAllocation.nextPort() else null - val processFuture = startOutOfProcessNode(executorService, nodeConfiguration, config, quasarJarPath, debugPort, systemProperties, callerPackage) + val processFuture = startOutOfProcessNode(executorService, nodeConfiguration, config, quasarJarPath, debugPort, systemProperties, packagesToScanString) registerProcess(processFuture) return processFuture.flatMap { process -> val processDeathFuture = poll(executorService, "process death") { @@ -904,7 +909,7 @@ class DriverDSL( quasarJarPath: String, debugPort: Int?, overriddenSystemProperties: Map, - callerPackage: String + packagesToScanString: String ): CordaFuture { val processFuture = executorService.fork { log.info("Starting out-of-process Node ${nodeConf.myLegalName.organisation}") @@ -914,7 +919,7 @@ class DriverDSL( val systemProperties = overriddenSystemProperties + mapOf( "name" to nodeConf.myLegalName, "visualvm.display.name" to "corda-${nodeConf.myLegalName}", - "net.corda.node.cordapp.scan.package" to callerPackage, + "net.corda.node.cordapp.scan.packages" to packagesToScanString, "java.io.tmpdir" to System.getProperty("java.io.tmpdir") // Inherit from parent process ) // See experimental/quasar-hook/README.md for how to generate. diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt index fd18c1abcf..00fa22724f 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierDriver.kt @@ -76,6 +76,7 @@ fun verifierDriver( useTestClock: Boolean = false, networkMapStartStrategy: NetworkMapStartStrategy = NetworkMapStartStrategy.Dedicated(startAutomatically = false), startNodesInProcess: Boolean = false, + extraCordappPackagesToScan: List = emptyList(), dsl: VerifierExposedDSLInterface.() -> A ) = genericDriver( driverDsl = VerifierDriverDSL( @@ -87,7 +88,8 @@ fun verifierDriver( useTestClock = useTestClock, networkMapStartStrategy = networkMapStartStrategy, isDebug = isDebug, - startNodesInProcess = startNodesInProcess + startNodesInProcess = startNodesInProcess, + extraCordappPackagesToScan = extraCordappPackagesToScan ) ), coerce = { it }, From 80b3411fa56ad73d4ed41de3c0c326af52f80f17 Mon Sep 17 00:00:00 2001 From: Patrick Kuo Date: Thu, 21 Sep 2017 13:27:05 +0100 Subject: [PATCH 026/230] Explorer advertising service fix (#1576) * WIP added a helper method to convert ObservableValue to ObservableList (cherry picked from commit 75306aa) * Fix for cash explorer after advertising service removal (cherry picked from commit 59d0278) * remove unused changes * address PR issues * fixup after rebase * fix CashState name rendering issue added flow permission to gradle config --- .../client/jfx/model/NetworkIdentityModel.kt | 15 ++++--- .../client/jfx/utils/ObservableUtilities.kt | 2 +- .../corda/finance/flows/CashConfigDataFlow.kt | 40 +++++++++++++++++++ .../statemachine/FlowStateMachineImpl.kt | 6 ++- samples/bank-of-corda-demo/build.gradle | 1 + .../net/corda/explorer/ExplorerSimulation.kt | 15 ++++--- .../net/corda/explorer/model/IssuerModel.kt | 29 +++++--------- .../explorer/model/ReportingCurrencyModel.kt | 3 +- .../net/corda/explorer/views/Network.kt | 14 +++++-- .../net/corda/explorer/views/Settings.kt | 3 +- .../corda/explorer/views/TransactionViewer.kt | 9 ++--- .../views/cordapps/cash/NewTransaction.kt | 16 +++----- .../net/corda/explorer/views/Network.fxml | 2 +- 13 files changed, 97 insertions(+), 58 deletions(-) create mode 100644 finance/src/main/kotlin/net/corda/finance/flows/CashConfigDataFlow.kt diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt index c17a9f5140..7f5e23babf 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt @@ -5,19 +5,20 @@ import com.google.common.cache.CacheLoader import javafx.beans.value.ObservableValue import javafx.collections.FXCollections import javafx.collections.ObservableList +import net.corda.client.jfx.utils.filterNotNull import net.corda.client.jfx.utils.fold import net.corda.client.jfx.utils.map import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache.MapChange +import net.corda.nodeapi.ServiceType import java.security.PublicKey class NetworkIdentityModel { private val networkIdentityObservable by observable(NodeMonitorModel::networkMap) - val networkIdentities: ObservableList = + private val networkIdentities: ObservableList = networkIdentityObservable.fold(FXCollections.observableArrayList()) { list, update -> list.removeIf { when (update) { @@ -32,13 +33,15 @@ class NetworkIdentityModel { private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable) private val identityCache = CacheBuilder.newBuilder() - .build>(CacheLoader.from { - publicKey -> + .build>(CacheLoader.from { publicKey -> publicKey?.let { rpcProxy.map { it?.nodeInfoFromParty(AnonymousParty(publicKey)) } } }) - val notaries: ObservableList = FXCollections.observableList(rpcProxy.value?.notaryIdentities()) - val notaryNodes: ObservableList = FXCollections.observableList(notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }) + val notaries: ObservableList = networkIdentities.map { + it.legalIdentitiesAndCerts.find { it.name.commonName?.let { ServiceType.parse(it).isNotary() } ?: false } + }.map { it?.party }.filterNotNull() + + val notaryNodes: ObservableList = notaries.map { rpcProxy.value?.nodeInfoFromParty(it) }.filterNotNull() val parties: ObservableList = networkIdentities.filtered { it.legalIdentities.all { it !in notaries } } val myIdentity = rpcProxy.map { it?.nodeInfo()?.legalIdentitiesAndCerts?.first()?.party } diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt index 83cb40bf70..10ae4aeff6 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/utils/ObservableUtilities.kt @@ -353,4 +353,4 @@ fun DataFeed, Vault.Update>.toFXListOfState */ fun DataFeed, Vault.Update>.toFXListOfStates(): ObservableList { return toFXListOfStateRefs().map { it.state.data } -} \ No newline at end of file +} diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashConfigDataFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashConfigDataFlow.kt new file mode 100644 index 0000000000..59d50403ca --- /dev/null +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashConfigDataFlow.kt @@ -0,0 +1,40 @@ +package net.corda.finance.flows + +import co.paralleluniverse.fibers.Suspendable +import net.corda.core.flows.FlowException +import net.corda.core.flows.FlowLogic +import net.corda.core.flows.StartableByRPC +import net.corda.core.serialization.CordaSerializable +import net.corda.finance.CHF +import net.corda.finance.EUR +import net.corda.finance.GBP +import net.corda.finance.USD +import java.util.* + +/** + * Flow to obtain cash cordapp app configuration. + */ +@StartableByRPC +class CashConfigDataFlow : FlowLogic() { + companion object { + private val supportedCurrencies = listOf(USD, GBP, CHF, EUR) + } + + @Suspendable + override fun call(): CashConfiguration { + val issuableCurrencies = supportedCurrencies.mapNotNull { + try { + // Currently it uses checkFlowPermission to determine the list of issuable currency as a temporary hack. + // TODO: get the config from proper configuration source. + checkFlowPermission("corda.issuer.$it", emptyMap()) + it + } catch (e: FlowException) { + null + } + } + return CashConfiguration(issuableCurrencies, supportedCurrencies) + } +} + +@CordaSerializable +data class CashConfiguration(val issuableCurrencies: List, val supportedCurrencies: List) diff --git a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt index 4f6b4c3dca..1556ef31c3 100644 --- a/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt +++ b/node/src/main/kotlin/net/corda/node/services/statemachine/FlowStateMachineImpl.kt @@ -23,6 +23,7 @@ import net.corda.core.utilities.* import net.corda.node.services.api.FlowAppAuditEvent import net.corda.node.services.api.FlowPermissionAuditEvent import net.corda.node.services.api.ServiceHubInternal +import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.statemachine.FlowSessionState.Initiating import net.corda.node.utilities.CordaPersistence import net.corda.node.utilities.DatabaseTransaction @@ -260,7 +261,10 @@ class FlowStateMachineImpl(override val id: StateMachineRunId, // TODO Dummy implementation of access to application specific permission controls and audit logging override fun checkFlowPermission(permissionName: String, extraAuditData: Map) { - val permissionGranted = true // TODO define permission control service on ServiceHubInternal and actually check authorization. + // This is a hack to allow cash app access list of permitted issuer currency. + // TODO: replace this with cordapp configuration. + val config = serviceHub.configuration as? FullNodeConfiguration + val permissionGranted = config?.extraAdvertisedServiceIds?.contains(permissionName) ?: true val checkPermissionEvent = FlowPermissionAuditEvent( serviceHub.clock.instant(), flowInitiator, diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index edebb866ba..1ecf9f160a 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -69,6 +69,7 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { ['username' : "bankUser", 'password' : "test", 'permissions': ["StartFlow.net.corda.finance.flows.CashPaymentFlow", + "StartFlow.net.corda.finance.flows.CashConfigDataFlow", "StartFlow.net.corda.finance.flows.CashExitFlow", "StartFlow.net.corda.finance.flows.CashIssueAndPaymentFlow"]] ] diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index 1b4b9371c7..b8b84bd776 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -17,16 +17,13 @@ import net.corda.core.utilities.getOrThrow import net.corda.finance.GBP import net.corda.finance.USD import net.corda.finance.contracts.asset.Cash -import net.corda.finance.flows.AbstractCashFlow -import net.corda.finance.flows.CashExitFlow +import net.corda.finance.flows.* import net.corda.finance.flows.CashExitFlow.ExitRequest -import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow.IssueAndPaymentRequest -import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission +import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.ServiceInfo import net.corda.nodeapi.ServiceType -import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE import net.corda.testing.BOB @@ -39,12 +36,14 @@ import java.util.* class ExplorerSimulation(val options: OptionSet) { private val user = User("user1", "test", permissions = setOf( - startFlowPermission() + startFlowPermission(), + startFlowPermission() )) private val manager = User("manager", "test", permissions = setOf( startFlowPermission(), startFlowPermission(), - startFlowPermission()) + startFlowPermission(), + startFlowPermission()) ) private lateinit var notaryNode: NodeHandle @@ -122,7 +121,7 @@ class ExplorerSimulation(val options: OptionSet) { val issuerRPCGBP = issuerGBPConnection.proxy val issuerClientUSD = issuerNodeUSD.rpcClientToNode() - val issuerUSDConnection =issuerClientUSD.start(manager.username, manager.password) + val issuerUSDConnection = issuerClientUSD.start(manager.username, manager.password) val issuerRPCUSD = issuerUSDConnection.proxy RPCConnections.addAll(listOf(aliceConnection, bobConnection, issuerGBPConnection, issuerUSDConnection)) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt index 25a85ec19e..b84f092d3a 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/model/IssuerModel.kt @@ -1,34 +1,25 @@ package net.corda.explorer.model import javafx.collections.FXCollections -import javafx.collections.ObservableList -import net.corda.client.jfx.model.NetworkIdentityModel -import net.corda.client.jfx.model.observableList +import net.corda.client.jfx.model.NodeMonitorModel import net.corda.client.jfx.model.observableValue import net.corda.client.jfx.utils.ChosenList import net.corda.client.jfx.utils.map -import net.corda.core.identity.Party -import net.corda.core.node.NodeInfo +import net.corda.core.messaging.startFlow +import net.corda.core.utilities.getOrThrow +import net.corda.finance.flows.CashConfigDataFlow import tornadofx.* -val ISSUER_SERVICE_TYPE = Regex("corda.issuer.(USD|GBP|CHF|EUR)") - class IssuerModel { - // TODO Explorer will be fixed as separate PR. - private val networkIdentities by observableList(NetworkIdentityModel::networkIdentities) - private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) - private val supportedCurrencies by observableList(ReportingCurrencyModel::supportedCurrencies) + private val proxy by observableValue(NodeMonitorModel::proxyObservable) + private val cashAppConfiguration = proxy.map { it?.startFlow(::CashConfigDataFlow)?.returnValue?.getOrThrow() } + val supportedCurrencies = ChosenList(cashAppConfiguration.map { it?.supportedCurrencies?.observable() ?: FXCollections.emptyObservableList() }) + val currencyTypes = ChosenList(cashAppConfiguration.map { it?.issuableCurrencies?.observable() ?: FXCollections.emptyObservableList() }) - val issuers: ObservableList = FXCollections.observableList(networkIdentities) - - val currencyTypes = ChosenList(myIdentity.map { supportedCurrencies }) - - val transactionTypes = ChosenList(myIdentity.map { - if (it?.isIssuerNode() ?: false) + val transactionTypes = ChosenList(cashAppConfiguration.map { + if (it?.issuableCurrencies?.isNotEmpty() == true) CashTransaction.values().asList().observable() else listOf(CashTransaction.Pay).observable() }) - - private fun Party.isIssuerNode() = true } diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/model/ReportingCurrencyModel.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/model/ReportingCurrencyModel.kt index 9c3e413382..365b6abf6a 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/model/ReportingCurrencyModel.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/model/ReportingCurrencyModel.kt @@ -16,8 +16,7 @@ import java.util.* class ReportingCurrencyModel { private val exchangeRate: ObservableValue by observableValue(ExchangeRateModel::exchangeRate) - val reportingCurrency by observableValue(SettingsModel::reportingCurrencyProperty) - val supportedCurrencies = setOf(USD, GBP, CHF, EUR).toList().observable() + private val reportingCurrency by observableValue(SettingsModel::reportingCurrencyProperty) /** * This stream provides a stream of exchange() functions that updates when either the reporting currency or the diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index 6470c57c5b..d32fa799e0 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -9,6 +9,7 @@ import javafx.beans.property.SimpleObjectProperty import javafx.beans.value.ObservableValue import javafx.collections.FXCollections import javafx.geometry.Bounds +import javafx.geometry.Insets import javafx.geometry.Point2D import javafx.scene.Parent import javafx.scene.control.Button @@ -35,6 +36,7 @@ import net.corda.explorer.model.CordaView import net.corda.finance.utils.CityDatabase import net.corda.finance.utils.ScreenCoordinate import net.corda.finance.utils.WorldMapLocation +import net.corda.nodeapi.ServiceType import tornadofx.* class Network : CordaView() { @@ -91,15 +93,19 @@ class Network : CordaView() { val node = this val identities = node.legalIdentitiesAndCerts.sortedBy { it.owningKey.toBase58String() } return button { + minWidth = 300.0 + padding = Insets(10.0) useMaxWidth = true graphic = vbox { label(PartyNameFormatter.short.format(identities[0].name)) { font = Font.font(font.family, FontWeight.BOLD, 15.0) } - gridpane { // TODO We lose node's main identity for display. + gridpane { + // TODO We lose node's main identity for display. hgap = 5.0 vgap = 5.0 for (identity in identities) { - row(PartyNameFormatter.short.format(identity.name)) { - copyableLabel(SimpleObjectProperty(identity.owningKey.toBase58String())).apply { minWidth = 400.0 } + val isNotary = identity.name.commonName?.let { ServiceType.parse(it).isNotary() } ?: false + row("${if (isNotary) "Notary " else ""}Public Key :") { + copyableLabel(SimpleObjectProperty(identity.owningKey.toBase58String())) } } node.getWorldMapLocation()?.apply { row("Location :") { label(this@apply.description) } } @@ -114,7 +120,7 @@ class Network : CordaView() { private fun NodeInfo.render(): MapViewComponents { val node = this val identities = node.legalIdentitiesAndCerts.sortedBy { it.owningKey.toBase58String() } - val mapLabel = label(PartyNameFormatter.short.format(identities[0].name)) // We choose the first one for the name of the node on the map. + val mapLabel = label(PartyNameFormatter.short.format(identities.first().name)) // We choose the first one for the name of the node on the map. mapPane.add(mapLabel) // applyCss: This method does not normally need to be invoked directly but may be used in conjunction with Parent.layout() // to size a Node before the next pulse, or if the Scene is not in a Stage. diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Settings.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Settings.kt index 6bfcd3b826..503ff7e1be 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Settings.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Settings.kt @@ -12,6 +12,7 @@ import net.corda.client.jfx.model.objectProperty import net.corda.client.jfx.model.observableList import net.corda.client.jfx.utils.map import net.corda.explorer.model.CordaView +import net.corda.explorer.model.IssuerModel import net.corda.explorer.model.ReportingCurrencyModel import net.corda.explorer.model.SettingsModel import java.util.* @@ -22,7 +23,7 @@ class Settings : CordaView() { override val icon = FontAwesomeIcon.COGS // Inject Data. - private val currencies by observableList(ReportingCurrencyModel::supportedCurrencies) + private val currencies by observableList(IssuerModel::supportedCurrencies) private val reportingCurrencies by objectProperty(SettingsModel::reportingCurrencyProperty) private val rememberMe by objectProperty(SettingsModel::rememberMeProperty) private val fullscreen by objectProperty(SettingsModel::fullscreenProperty) diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt index 8a3547863c..f528e0ec66 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/TransactionViewer.kt @@ -26,7 +26,6 @@ import net.corda.core.crypto.toStringShort import net.corda.core.identity.AbstractParty import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party -import net.corda.core.node.NodeInfo import net.corda.core.utilities.toBase58String import net.corda.explorer.AmountDiff import net.corda.explorer.formatters.AmountFormatter @@ -37,6 +36,7 @@ import net.corda.explorer.identicon.identiconToolTip import net.corda.explorer.model.CordaView import net.corda.explorer.model.CordaWidget import net.corda.explorer.model.ReportingCurrencyModel +import net.corda.explorer.model.SettingsModel import net.corda.explorer.sign import net.corda.explorer.ui.setCustomCellFactory import net.corda.finance.contracts.asset.Cash @@ -52,7 +52,7 @@ class TransactionViewer : CordaView("Transactions") { // Inject data private val transactions by observableListReadOnly(TransactionDataModel::partiallyResolvedTransactions) private val reportingExchange by observableValue(ReportingCurrencyModel::reportingExchange) - private val reportingCurrency by observableValue(ReportingCurrencyModel::reportingCurrency) + private val reportingCurrency by observableValue(SettingsModel::reportingCurrencyProperty) private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) override val widgets = listOf(CordaWidget(title, TransactionWidget(), icon)).observable() @@ -260,7 +260,7 @@ class TransactionViewer : CordaView("Transactions") { vgap = 10.0 hgap = 10.0 row { - label("${contractState.contract().javaClass.simpleName} (${contractState.ref.toString().substring(0, 16)}...)[${contractState.ref.index}]") { + label("${contractState.contract()} (${contractState.ref.toString().substring(0, 16)}...)[${contractState.ref.index}]") { graphic = identicon(contractState.ref.txhash, 30.0) tooltip = identiconToolTip(contractState.ref.txhash) gridpaneConstraints { columnSpan = 2 } @@ -298,8 +298,7 @@ class TransactionViewer : CordaView("Transactions") { } } - private fun StateAndRef.contract() = this.state.contract - + private fun StateAndRef.contract() = this.state.contract.split(".").last() } /** diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt index 1cfebe9554..985f962473 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/cordapps/cash/NewTransaction.kt @@ -13,10 +13,7 @@ import javafx.scene.text.Font import javafx.scene.text.FontWeight import javafx.stage.Window import net.corda.client.jfx.model.* -import net.corda.client.jfx.utils.ChosenList -import net.corda.client.jfx.utils.isNotNull -import net.corda.client.jfx.utils.map -import net.corda.client.jfx.utils.unique +import net.corda.client.jfx.utils.* import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount.Companion.sumOrNull import net.corda.core.contracts.withoutIssuer @@ -31,10 +28,10 @@ import net.corda.core.utilities.getOrThrow import net.corda.explorer.formatters.PartyNameFormatter import net.corda.explorer.model.CashTransaction import net.corda.explorer.model.IssuerModel -import net.corda.explorer.model.ReportingCurrencyModel import net.corda.explorer.views.bigDecimalFormatter import net.corda.explorer.views.byteFormatter import net.corda.explorer.views.stringConverter +import net.corda.explorer.views.toKnownParty import net.corda.finance.flows.AbstractCashFlow import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashExitFlow.ExitRequest @@ -42,7 +39,6 @@ import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashIssueAndPaymentFlow.IssueAndPaymentRequest import net.corda.finance.flows.CashPaymentFlow import net.corda.finance.flows.CashPaymentFlow.PaymentRequest -import net.corda.testing.chooseIdentity import net.corda.testing.chooseIdentityAndCert import org.controlsfx.dialog.ExceptionDialog import tornadofx.* @@ -71,15 +67,15 @@ class NewTransaction : Fragment() { private val issueRef = SimpleObjectProperty() // Inject data private val parties by observableList(NetworkIdentityModel::parties) - private val issuers by observableList(IssuerModel::issuers) private val rpcProxy by observableValue(NodeMonitorModel::proxyObservable) private val myIdentity by observableValue(NetworkIdentityModel::myIdentity) private val notaries by observableList(NetworkIdentityModel::notaries) private val cash by observableList(ContractStateModel::cash) private val executeButton = ButtonType("Execute", ButtonBar.ButtonData.APPLY) private val currencyTypes by observableList(IssuerModel::currencyTypes) - private val supportedCurrencies by observableList(ReportingCurrencyModel::supportedCurrencies) + private val supportedCurrencies by observableList(IssuerModel::supportedCurrencies) private val transactionTypes by observableList(IssuerModel::transactionTypes) + private val issuers = cash.map { it.token.issuer } private val currencyItems = ChosenList(transactionTypeCB.valueProperty().map { when (it) { @@ -156,7 +152,7 @@ class NewTransaction : Fragment() { val issueRef = if (issueRef.value != null) OpaqueBytes.of(issueRef.value) else defaultRef when (it) { executeButton -> when (transactionTypeCB.value) { - CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first(), anonymous) + CashTransaction.Issue -> IssueAndPaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef, partyBChoiceBox.value.party, notaries.first().value!!, anonymous) CashTransaction.Pay -> PaymentRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), partyBChoiceBox.value.party, anonymous = anonymous) CashTransaction.Exit -> ExitRequest(Amount.fromDecimal(amount.value, currencyChoiceBox.value), issueRef) else -> null @@ -192,7 +188,7 @@ class NewTransaction : Fragment() { issuerLabel.visibleProperty().bind(transactionTypeCB.valueProperty().isNotNull) // TODO This concept should burn (after services removal...) issuerChoiceBox.apply { - items = issuers.map { it.chooseIdentity() }.unique().sorted() + items = issuers.map { it.party.owningKey.toKnownParty().value }.filterNotNull().unique().sorted() converter = stringConverter { PartyNameFormatter.short.format(it.name) } visibleProperty().bind(transactionTypeCB.valueProperty().map { it == CashTransaction.Pay }) } diff --git a/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml b/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml index c1469af2ab..5e7523cf51 100644 --- a/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml +++ b/tools/explorer/src/main/resources/net/corda/explorer/views/Network.fxml @@ -19,7 +19,7 @@ - + From b1d1d74d6eec444705deef15c086ea5a7909a225 Mon Sep 17 00:00:00 2001 From: Andrzej Cichocki Date: Thu, 21 Sep 2017 13:30:29 +0100 Subject: [PATCH 027/230] Fix notary demo. (#1577) --- .../net/corda/notarydemo/flows/DummyIssueAndMove.kt | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt index 5d4820f0b5..c4c5bde481 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/flows/DummyIssueAndMove.kt @@ -14,12 +14,15 @@ import net.corda.core.transactions.TransactionBuilder @StartableByRPC class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: Party, private val discriminator: Int) : FlowLogic() { - val DO_NOTHING_PROGRAM_ID = "net.corda.notarydemo.flows.DummyIssueAndMove.DoNothingContract" - object DoNothingContract : Contract { + companion object { + private val DO_NOTHING_PROGRAM_ID = "net.corda.notarydemo.flows.DummyIssueAndMove\$DoNothingContract" + } + + class DoNothingContract : Contract { override fun verify(tx: LedgerTransaction) {} } - data class DummyCommand(val dummy: Int = 0): CommandData + data class DummyCommand(val dummy: Int = 0) : CommandData data class State(override val participants: List, private val discriminator: Int) : ContractState @@ -29,7 +32,7 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: val state = State(listOf(ourIdentity), discriminator) val issueTx = serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { addOutputState(state, DO_NOTHING_PROGRAM_ID) - addCommand(DummyCommand(),listOf(ourIdentity.owningKey)) + addCommand(DummyCommand(), listOf(ourIdentity.owningKey)) }) serviceHub.recordTransactions(issueTx) // Move ownership of the asset to the counterparty @@ -37,7 +40,7 @@ class DummyIssueAndMove(private val notary: Party, private val counterpartyNode: return serviceHub.signInitialTransaction(TransactionBuilder(notary).apply { addInputState(issueTx.tx.outRef(0)) addOutputState(state.copy(participants = listOf(counterpartyNode)), DO_NOTHING_PROGRAM_ID) - addCommand(DummyCommand(),listOf(ourIdentity.owningKey)) + addCommand(DummyCommand(), listOf(ourIdentity.owningKey)) }) } } From 76fef4ed4931eba4f240397cdae287ac5282475e Mon Sep 17 00:00:00 2001 From: Patrick Kuo Date: Thu, 21 Sep 2017 14:41:52 +0100 Subject: [PATCH 028/230] fetch unconsumed vault snapshot instead of ALL (#1587) --- .../corda/client/jfx/model/NodeMonitorModel.kt | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt index 328b164e85..3cde49536e 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NodeMonitorModel.kt @@ -9,10 +9,13 @@ import net.corda.core.identity.Party import net.corda.core.messaging.* import net.corda.core.node.services.NetworkMapCache.MapChange import net.corda.core.node.services.Vault -import net.corda.core.node.services.vault.* -import net.corda.core.utilities.seconds +import net.corda.core.node.services.vault.DEFAULT_PAGE_NUM +import net.corda.core.node.services.vault.MAX_PAGE_SIZE +import net.corda.core.node.services.vault.PageSpecification +import net.corda.core.node.services.vault.QueryCriteria import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.NetworkHostAndPort +import net.corda.core.utilities.seconds import rx.Observable import rx.subjects.PublishSubject @@ -86,8 +89,13 @@ class NodeMonitorModel { stateMachineUpdates.startWith(currentStateMachines).subscribe(stateMachineUpdatesSubject) // Vault snapshot (force single page load with MAX_PAGE_SIZE) + updates - val (vaultSnapshot, vaultUpdates) = proxy.vaultTrackBy(QueryCriteria.VaultQueryCriteria(Vault.StateStatus.ALL), - PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE)) + val (_, vaultUpdates) = proxy.vaultTrackBy(QueryCriteria.VaultQueryCriteria(Vault.StateStatus.ALL), + PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE)) + + val vaultSnapshot = proxy.vaultQueryBy(QueryCriteria.VaultQueryCriteria(Vault.StateStatus.UNCONSUMED), + PageSpecification(DEFAULT_PAGE_NUM, MAX_PAGE_SIZE)) + // We have to fetch the snapshot separately since vault query API doesn't allow different criteria for snapshot and updates. + // TODO : This will create a small window of opportunity for inconsistent updates, might need to change the vault API to handle this case. val initialVaultUpdate = Vault.Update(setOf(), vaultSnapshot.states.toSet()) vaultUpdates.startWith(initialVaultUpdate).subscribe(vaultUpdatesSubject) From 7e977c41184b42d92ecda444b26e745d7c9ca0a5 Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Thu, 21 Sep 2017 14:43:10 +0100 Subject: [PATCH 029/230] Minor changes to code documentation (#1585) --- docs/source/running-the-demos.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/source/running-the-demos.rst b/docs/source/running-the-demos.rst index 6685c6db7e..53ab0a85ac 100644 --- a/docs/source/running-the-demos.rst +++ b/docs/source/running-the-demos.rst @@ -64,10 +64,10 @@ To run from the command line in Unix: To run from the command line in Windows: -1. Run ``gradlew samples:irs-demo:deployNodes`` to install configs and a command line tool under ``samples\irs-demo\build`` -2. Run ``gradlew samples:irs-demo:installDist`` -3. Move to the ``samples\irs-demo\build`` directory -4. Run ``nodes\runnodes`` to open up three new terminals with the three nodes. +1. Run ``gradlew.bat samples:irs-demo:deployNodes`` to install configs and a command line tool under ``samples\irs-demo\build`` +2. Run ``gradlew.bat samples:irs-demo:installDist`` +3. Run ``cd samples\irs-demo\build`` to change current working directory +4. Run ``nodes\runnodes`` to open up several 6 terminals, 2 for each node. First terminal is a web-server associated with every node and second one is Corda interactive shell for the node. This demo also has a web app. To use this, run nodes and then navigate to http://localhost:10007/web/irsdemo and http://localhost:10010/web/irsdemo to see each node's view of the ledger. From b0e9183850823e4a68f50cb7c8be5893e8296849 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 21 Sep 2017 14:46:36 +0100 Subject: [PATCH 030/230] CORDA-499: Dokka cleanup for 1.0 (#1579) * Clean up Dokka comments on CordaRPCOps * Remove use of "e.g." which Dokka will take as end of the first sentence * Move example onto function that it actually works with * Change comment which refers to comment above it, without any linkage, to directly describe the function * Move implementation notes out of Dokka comment * Make functions in CompositeSignature static * Make contract IDs constant * Correct contract ID in CashTestsJava --- .../corda/core/crypto/CompositeSignature.kt | 1 + .../net/corda/core/messaging/CordaRPCOps.kt | 20 +++++++++---------- .../java/net/corda/docs/FlowCookbookJava.java | 2 +- .../finance/contracts/CommercialPaper.kt | 2 +- .../net/corda/finance/contracts/asset/Cash.kt | 3 +-- .../finance/contracts/asset/Obligation.kt | 3 +-- .../contracts/asset/CashTestsJava.java | 2 +- .../main/kotlin/net/corda/irs/contract/IRS.kt | 2 +- .../net/corda/vega/contracts/IRSState.kt | 3 ++- .../corda/testing/contracts/DummyContract.kt | 5 ++++- .../testing/contracts/DummyContractV2.kt | 2 +- 11 files changed, 24 insertions(+), 21 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/crypto/CompositeSignature.kt b/core/src/main/kotlin/net/corda/core/crypto/CompositeSignature.kt index 0438a630ae..8317a11a64 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CompositeSignature.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CompositeSignature.kt @@ -12,6 +12,7 @@ import java.security.spec.AlgorithmParameterSpec class CompositeSignature : Signature(SIGNATURE_ALGORITHM) { companion object { const val SIGNATURE_ALGORITHM = "COMPOSITESIG" + @JvmStatic fun getService(provider: Provider) = Provider.Service(provider, "Signature", SIGNATURE_ALGORITHM, CompositeSignature::class.java.name, emptyList(), emptyMap()) } diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index bdf85ce48a..84c42b228f 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -292,15 +292,9 @@ inline fun CordaRPCOps.vaultTrackBy(criteria: QueryC return vaultTrackBy(criteria, paging, sorting, T::class.java) } -/** - * These allow type safe invocations of flows from Kotlin, e.g.: - * - * val rpc: CordaRPCOps = (..) - * rpc.startFlow(::ResolveTransactionsFlow, setOf(), aliceIdentity) - * - * Note that the passed in constructor function is only used for unification of other type parameters and reification of - * the Class instance of the flow. This could be changed to use the constructor function directly. - */ +// Note that the passed in constructor function is only used for unification of other type parameters and reification of +// the Class instance of the flow. This could be changed to use the constructor function directly. + inline fun > CordaRPCOps.startFlow( @Suppress("UNUSED_PARAMETER") flowConstructor: () -> R @@ -312,6 +306,12 @@ inline fun > CordaRPCOps.startFlow( arg0: A ): FlowHandle = startFlowDynamic(R::class.java, arg0) +/** + * Extension function for type safe invocation of flows from Kotlin, for example: + * + * val rpc: CordaRPCOps = (..) + * rpc.startFlow(::ResolveTransactionsFlow, setOf(), aliceIdentity) + */ inline fun > CordaRPCOps.startFlow( @Suppress("UNUSED_PARAMETER") flowConstructor: (A, B) -> R, @@ -358,7 +358,7 @@ inline fun > CordaRPCOps.startFlow ): FlowHandle = startFlowDynamic(R::class.java, arg0, arg1, arg2, arg3, arg4, arg5) /** - * Same again, except this time with progress-tracking enabled. + * Extension function for type safe invocation of flows from Kotlin, with progress tracking enabled. */ @Suppress("unused") inline fun > CordaRPCOps.startTrackedFlow( diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java index 1b84610ca9..247b3160d2 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java @@ -328,7 +328,7 @@ public class FlowCookbookJava { // We can also add items using methods for the individual components: // DOCSTART 28 txBuilder.addInputState(ourStateAndRef); - txBuilder.addOutputState(ourOutput, DummyContractKt.getDUMMY_PROGRAM_ID()); + txBuilder.addOutputState(ourOutput, DummyContractKt.DUMMY_PROGRAM_ID); txBuilder.addCommand(ourCommand); txBuilder.addAttachment(ourAttachment); // DOCEND 28 diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt b/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt index 4953a56f25..68d2bc62bc 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/CommercialPaper.kt @@ -43,7 +43,7 @@ import java.util.* // TODO: Generalise the notion of an owned instrument into a superclass/supercontract. Consider composition vs inheritance. class CommercialPaper : Contract { companion object { - val CP_PROGRAM_ID = "net.corda.finance.contracts.CommercialPaper" + const val CP_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.CommercialPaper" } data class State( val issuance: PartyAndReference, diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt index 984c99eff2..0b405647b2 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Cash.kt @@ -36,8 +36,7 @@ import java.util.concurrent.atomic.AtomicReference // Cash // -// Just a fake program identifier for now. In a real system it could be, for instance, the hash of the program bytecode. -val CASH_PROGRAM_ID = "net.corda.finance.contracts.asset.Cash" +const val CASH_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.asset.Cash" /** * Pluggable interface to allow for different cash selection provider implementations diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Obligation.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Obligation.kt index b80a30c0aa..556791fdaf 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/Obligation.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/Obligation.kt @@ -62,8 +62,7 @@ data class MultilateralNetState

( ) : NetState

-// Just a fake program identifier for now. In a real system it could be, for instance, the hash of the program bytecode. -val OBLIGATION_PROGRAM_ID = "net.corda.finance.contracts.asset.Obligation" +const val OBLIGATION_PROGRAM_ID: ContractClassName = "net.corda.finance.contracts.asset.Obligation" /** * An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the diff --git a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java index b2875e747f..f8d510868c 100644 --- a/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java +++ b/finance/src/test/java/net/corda/finance/contracts/asset/CashTestsJava.java @@ -19,7 +19,7 @@ public class CashTestsJava { private final PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef); private final Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), new AnonymousParty(getMEGA_CORP_PUBKEY())); private final Cash.State outState = new Cash.State(inState.getAmount(), new AnonymousParty(getMINI_CORP_PUBKEY())); - private final String CASH_PROGRAM_ID = CashUtilities.getCASH_PROGRAM_ID(); + private final String CASH_PROGRAM_ID = CashUtilities.CASH_PROGRAM_ID; @Test public void trivial() { diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt index a5eca220f0..8070d86f29 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/contract/IRS.kt @@ -18,7 +18,7 @@ import java.math.RoundingMode import java.time.LocalDate import java.util.* -val IRS_PROGRAM_ID = "net.corda.irs.contract.InterestRateSwap" +const val IRS_PROGRAM_ID = "net.corda.irs.contract.InterestRateSwap" // This is a placeholder for some types that we haven't identified exactly what they are just yet for things still in discussion @CordaSerializable diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt index 4d07406a16..73537a02d3 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/contracts/IRSState.kt @@ -1,6 +1,7 @@ package net.corda.vega.contracts import net.corda.core.contracts.Command +import net.corda.core.contracts.ContractClassName import net.corda.core.contracts.StateAndContract import net.corda.core.contracts.UniqueIdentifier import net.corda.core.identity.AbstractParty @@ -8,7 +9,7 @@ import net.corda.core.identity.Party import net.corda.core.transactions.TransactionBuilder import net.corda.finance.contracts.DealState -val IRS_PROGRAM_ID = "net.corda.vega.contracts.OGTrade" +const val IRS_PROGRAM_ID: ContractClassName = "net.corda.vega.contracts.OGTrade" /** * Represents an OpenGamma IRS between two parties. Does not implement any fixing functionality. diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt index 9048ad0e43..2f9da356a4 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContract.kt @@ -8,7 +8,7 @@ import net.corda.core.transactions.TransactionBuilder // The dummy contract doesn't do anything useful. It exists for testing purposes, but has to be serializable -val DUMMY_PROGRAM_ID = "net.corda.testing.contracts.DummyContract" +const val DUMMY_PROGRAM_ID: ContractClassName = "net.corda.testing.contracts.DummyContract" data class DummyContract(val blank: Any? = null) : Contract { interface State : ContractState { @@ -54,7 +54,10 @@ data class DummyContract(val blank: Any? = null) : Contract { } } + @JvmStatic fun move(prior: StateAndRef, newOwner: AbstractParty) = move(listOf(prior), newOwner) + + @JvmStatic fun move(priors: List>, newOwner: AbstractParty): TransactionBuilder { require(priors.isNotEmpty()) val priorState = priors[0].state.data diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt index 1452e72a03..2fcb8fed73 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt @@ -8,7 +8,7 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.WireTransaction // The dummy contract doesn't do anything useful. It exists for testing purposes. -val DUMMY_V2_PROGRAM_ID = "net.corda.testing.contracts.DummyContractV2" +const val DUMMY_V2_PROGRAM_ID: ContractClassName = "net.corda.testing.contracts.DummyContractV2" /** * Dummy contract state for testing of the upgrade process. From d72d887224346c95cc9203577106e05cd70aa2ca Mon Sep 17 00:00:00 2001 From: Katarzyna Streich Date: Thu, 21 Sep 2017 14:50:20 +0100 Subject: [PATCH 031/230] Fix BankOfCorda demo after services removal (#1584) * Fix BankOfCorda demo after services removal * Add CashConfigDataFlow permission to BankOfCorda * Address comments * Add permission --- docs/source/running-the-demos.rst | 5 ----- samples/bank-of-corda-demo/build.gradle | 6 ++++-- .../kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt | 4 +++- .../src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt | 3 ++- .../main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt | 6 +++--- .../src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/source/running-the-demos.rst b/docs/source/running-the-demos.rst index 53ab0a85ac..a20990dab9 100644 --- a/docs/source/running-the-demos.rst +++ b/docs/source/running-the-demos.rst @@ -192,11 +192,6 @@ To run from the command line in Windows: .. note:: To verify that the Bank of Corda node is alive and running, navigate to the following URL: http://localhost:10007/api/bank/date -.. note:: The Bank of Corda node explicitly advertises with a node service type as follows: - ``advertisedServices = ["corda.issuer.USD"]`` - This allows for 3rd party applications to perform actions based on Node Type. - For example, the Explorer tool only allows nodes of this type to issue and exit cash. - In the window you run the command you should see (in case of Web, RPC is simmilar): - Requesting Cash via Web ... diff --git a/samples/bank-of-corda-demo/build.gradle b/samples/bank-of-corda-demo/build.gradle index 1ecf9f160a..4da684ed47 100644 --- a/samples/bank-of-corda-demo/build.gradle +++ b/samples/bank-of-corda-demo/build.gradle @@ -71,7 +71,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { 'permissions': ["StartFlow.net.corda.finance.flows.CashPaymentFlow", "StartFlow.net.corda.finance.flows.CashConfigDataFlow", "StartFlow.net.corda.finance.flows.CashExitFlow", - "StartFlow.net.corda.finance.flows.CashIssueAndPaymentFlow"]] + "StartFlow.net.corda.finance.flows.CashIssueAndPaymentFlow", + "StartFlow.net.corda.finance.flows.CashConfigDataFlow"]] ] } node { @@ -84,7 +85,8 @@ task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) { rpcUsers = [ ['username' : "bigCorpUser", 'password' : "test", - 'permissions': ["StartFlow.net.corda.flows.CashPaymentFlow"]] + 'permissions': ["StartFlow.net.corda.finance.flows.CashPaymentFlow", + "StartFlow.net.corda.finance.flows.CashConfigDataFlow"]] ] } } diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt index b7d931d99d..a1781fd1c6 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt @@ -7,6 +7,7 @@ import net.corda.nodeapi.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.BOC import net.corda.testing.driver.driver +import net.corda.testing.notary import org.junit.Test import kotlin.test.assertTrue @@ -18,7 +19,8 @@ class BankOfCordaHttpAPITest { val nodeBankOfCordaFuture = startNode(providedName = BOC.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type))) val (nodeBankOfCorda) = listOf(nodeBankOfCordaFuture, bigCorpNodeFuture).map { it.getOrThrow() } val nodeBankOfCordaApiAddr = startWebserver(nodeBankOfCorda).getOrThrow().listenAddress - assertTrue(BankOfCordaClientApi(nodeBankOfCordaApiAddr).requestWebIssue(IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, BOC.name))) + val notaryName = notary().node.nodeInfo.legalIdentities[1].name + assertTrue(BankOfCordaClientApi(nodeBankOfCordaApiAddr).requestWebIssue(IssueRequestParams(1000, "USD", BIGCORP_LEGAL_NAME, "1", BOC.name, notaryName))) }, isDebug = true) } } diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt index 8b139ba6f2..4fa643ac76 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt @@ -54,7 +54,8 @@ private class BankOfCordaDriver { // The ISSUE_CASH will request some Cash from the ISSUER on behalf of Big Corporation node val role = options.valueOf(roleArg)!! - val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME, "1", BOC.name, DUMMY_NOTARY.name) + val requestParams = IssueRequestParams(options.valueOf(quantity), options.valueOf(currency), BIGCORP_LEGAL_NAME, + "1", BOC.name, DUMMY_NOTARY.name.copy(commonName = "corda.notary.validating")) try { when (role) { diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt index b65a7f3131..39b738f04b 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt @@ -40,9 +40,9 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) { // Resolve parties via RPC val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) - ?: throw Exception("Unable to locate ${params.issueToPartyName} in Network Map Service") - val notaryLegalIdentity = rpc.partyFromX500Name(params.notaryName) - ?: throw IllegalStateException("Unable to locate ${params.notaryName} in Network Map Service") + ?: throw IllegalStateException("Unable to locate ${params.issueToPartyName} in Network Map Service") + val notaryLegalIdentity = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } ?: + throw IllegalStateException("Couldn't locate notary ${params.notaryName} in NetworkMapCache") val amount = Amount(params.amount, Currency.getInstance(params.currency)) val anonymous = true diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt index 2a25342416..b651455765 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt @@ -44,8 +44,8 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) { val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issueToPartyName} in identity service").build() rpc.partyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build() - val notaryParty = rpc.partyFromX500Name(params.notaryName) - ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.notaryName} in identity service").build() + val notaryParty = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } + ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate notary ${params.notaryName} in network map").build() val amount = Amount(params.amount, Currency.getInstance(params.currency)) val anonymous = true From c108637df623ed568b3f67319b69984a89d50f5f Mon Sep 17 00:00:00 2001 From: Matthew Nesbit Date: Thu, 21 Sep 2017 15:31:42 +0100 Subject: [PATCH 032/230] Remove unused certificate method from IdentityService. (#1582) Put wellKnownParty in methods that return a Party which is one. Fixup rebase --- .../corda/client/jackson/JacksonSupport.kt | 10 ++--- .../corda/confidential/IdentitySyncFlow.kt | 2 +- .../confidential/IdentitySyncFlowTests.kt | 6 +-- .../confidential/SwapIdentitiesFlowTests.kt | 4 +- .../net/corda/core/messaging/CordaRPCOps.kt | 4 +- .../kotlin/net/corda/core/node/ServiceHub.kt | 4 +- .../core/node/services/IdentityService.kt | 42 ++++++++++--------- docs/source/api-rpc.rst | 2 +- .../java/net/corda/docs/FlowCookbookJava.java | 2 +- .../kotlin/net/corda/docs/FlowCookbook.kt | 2 +- docs/source/tutorial-attachments.rst | 2 +- .../net/corda/finance/flows/CashExitFlow.kt | 2 +- .../corda/finance/flows/TwoPartyDealFlow.kt | 4 +- .../corda/finance/flows/TwoPartyTradeFlow.kt | 4 +- .../statemachine/LargeTransactionsTest.kt | 2 +- .../corda/node/internal/CordaRPCOpsImpl.kt | 8 ++-- .../identity/InMemoryIdentityService.kt | 11 +++-- .../identity/PersistentIdentityService.kt | 17 ++++---- .../network/PersistentNetworkMapCache.kt | 2 +- ...bstractPartyToX500NameAsStringConverter.kt | 4 +- .../network/InMemoryIdentityServiceTests.kt | 8 ++-- .../network/PersistentIdentityServiceTests.kt | 10 ++--- .../corda/attachmentdemo/AttachmentDemo.kt | 4 +- .../corda/bank/api/BankOfCordaClientApi.kt | 2 +- .../net/corda/bank/api/BankOfCordaWebApi.kt | 4 +- .../kotlin/net/corda/irs/flows/FixingFlow.kt | 2 +- .../kotlin/net/corda/vega/flows/SimmFlow.kt | 4 +- .../net/corda/vega/flows/SimmRevaluation.kt | 2 +- .../corda/traderdemo/TraderDemoClientApi.kt | 6 +-- 29 files changed, 88 insertions(+), 88 deletions(-) diff --git a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt index de028ed2e6..a9935f12fc 100644 --- a/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt +++ b/client/jackson/src/main/kotlin/net/corda/client/jackson/JacksonSupport.kt @@ -46,25 +46,25 @@ object JacksonSupport { // If you change this API please update the docs in the docsite (json.rst) interface PartyObjectMapper { - fun partyFromX500Name(name: CordaX500Name): Party? + fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? fun partyFromKey(owningKey: PublicKey): Party? fun partiesFromName(query: String): Set } class RpcObjectMapper(val rpc: CordaRPCOps, factory: JsonFactory, val fuzzyIdentityMatch: Boolean) : PartyObjectMapper, ObjectMapper(factory) { - override fun partyFromX500Name(name: CordaX500Name): Party? = rpc.partyFromX500Name(name) + override fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? = rpc.wellKnownPartyFromX500Name(name) override fun partyFromKey(owningKey: PublicKey): Party? = rpc.partyFromKey(owningKey) override fun partiesFromName(query: String) = rpc.partiesFromName(query, fuzzyIdentityMatch) } class IdentityObjectMapper(val identityService: IdentityService, factory: JsonFactory, val fuzzyIdentityMatch: Boolean) : PartyObjectMapper, ObjectMapper(factory) { - override fun partyFromX500Name(name: CordaX500Name): Party? = identityService.partyFromX500Name(name) + override fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? = identityService.wellKnownPartyFromX500Name(name) override fun partyFromKey(owningKey: PublicKey): Party? = identityService.partyFromKey(owningKey) override fun partiesFromName(query: String) = identityService.partiesFromName(query, fuzzyIdentityMatch) } class NoPartyObjectMapper(factory: JsonFactory) : PartyObjectMapper, ObjectMapper(factory) { - override fun partyFromX500Name(name: CordaX500Name): Party? = throw UnsupportedOperationException() + override fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? = throw UnsupportedOperationException() override fun partyFromKey(owningKey: PublicKey): Party? = throw UnsupportedOperationException() override fun partiesFromName(query: String) = throw UnsupportedOperationException() } @@ -192,7 +192,7 @@ object JacksonSupport { // how to parse the content return if (parser.text.contains("=")) { val principal = CordaX500Name.parse(parser.text) - mapper.partyFromX500Name(principal) ?: throw JsonParseException(parser, "Could not find a Party with name $principal") + mapper.wellKnownPartyFromX500Name(principal) ?: throw JsonParseException(parser, "Could not find a Party with name $principal") } else { val nameMatches = mapper.partiesFromName(parser.text) if (nameMatches.isEmpty()) { diff --git a/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt index e5f68de31f..01f520afda 100644 --- a/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt +++ b/confidential-identities/src/main/kotlin/net/corda/confidential/IdentitySyncFlow.kt @@ -79,7 +79,7 @@ object IdentitySyncFlow { override fun call(): Unit { progressTracker.currentStep = RECEIVING_IDENTITIES val allIdentities = otherSideSession.receive>().unwrap { it } - val unknownIdentities = allIdentities.filter { serviceHub.identityService.partyFromAnonymous(it) == null } + val unknownIdentities = allIdentities.filter { serviceHub.identityService.wellKnownPartyFromAnonymous(it) == null } progressTracker.currentStep = RECEIVING_CERTIFICATES val missingIdentities = otherSideSession.sendAndReceive>(unknownIdentities) diff --git a/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt index 867931718b..6358fe92db 100644 --- a/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt +++ b/confidential-identities/src/test/kotlin/net/corda/confidential/IdentitySyncFlowTests.kt @@ -52,15 +52,15 @@ class IdentitySyncFlowTests { val issueFlow = aliceNode.services.startFlow(CashIssueAndPaymentFlow(1000.DOLLARS, ref, alice, anonymous, notary)) val issueTx = issueFlow.resultFuture.getOrThrow().stx val confidentialIdentity = issueTx.tx.outputs.map { it.data }.filterIsInstance().single().owner - assertNull(bobNode.database.transaction { bobNode.services.identityService.partyFromAnonymous(confidentialIdentity) }) + assertNull(bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) }) // Run the flow to sync up the identities aliceNode.services.startFlow(Initiator(bob, issueTx.tx)).resultFuture.getOrThrow() val expected = aliceNode.database.transaction { - aliceNode.services.identityService.partyFromAnonymous(confidentialIdentity) + aliceNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) } val actual = bobNode.database.transaction { - bobNode.services.identityService.partyFromAnonymous(confidentialIdentity) + bobNode.services.identityService.wellKnownPartyFromAnonymous(confidentialIdentity) } assertEquals(expected, actual) } diff --git a/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt b/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt index f974216870..684cd92c82 100644 --- a/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt +++ b/confidential-identities/src/test/kotlin/net/corda/confidential/SwapIdentitiesFlowTests.kt @@ -42,8 +42,8 @@ class SwapIdentitiesFlowTests { assertNotEquals(bob, bobAnonymousIdentity) // Verify that the anonymous identities look sane - assertEquals(alice.name, aliceNode.database.transaction { aliceNode.services.identityService.partyFromAnonymous(aliceAnonymousIdentity)!!.name }) - assertEquals(bob.name, bobNode.database.transaction { bobNode.services.identityService.partyFromAnonymous(bobAnonymousIdentity)!!.name }) + assertEquals(alice.name, aliceNode.database.transaction { aliceNode.services.identityService.wellKnownPartyFromAnonymous(aliceAnonymousIdentity)!!.name }) + assertEquals(bob.name, bobNode.database.transaction { bobNode.services.identityService.wellKnownPartyFromAnonymous(bobAnonymousIdentity)!!.name }) // Verify that the nodes have the right anonymous identities assertTrue { aliceAnonymousIdentity.owningKey in aliceNode.services.keyManagementService.keys } diff --git a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt index 84c42b228f..c4421d8b38 100644 --- a/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt +++ b/core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt @@ -249,12 +249,12 @@ interface CordaRPCOps : RPCOps { * @param party identity to determine well known identity for. * @return well known identity, if found. */ - fun partyFromAnonymous(party: AbstractParty): Party? + fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? /** Returns the [Party] corresponding to the given key, if found. */ fun partyFromKey(key: PublicKey): Party? /** Returns the [Party] with the X.500 principal as it's [Party.name]. */ - fun partyFromX500Name(x500Name: CordaX500Name): Party? + fun wellKnownPartyFromX500Name(x500Name: CordaX500Name): Party? /** * Returns a list of candidate matches for a given string, with optional fuzzy(ish) matching. Fuzzy matching may diff --git a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt index 7860c687e0..650f3bb486 100644 --- a/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/net/corda/core/node/ServiceHub.kt @@ -309,7 +309,7 @@ interface ServiceHub : ServicesForResolution { @Throws(IllegalArgumentException::class) fun groupAbstractPartyByWellKnownParty(parties: Collection, ignoreUnrecognisedParties: Boolean): Map> { val partyToPublicKey: Iterable> = parties.mapNotNull { - (identityService.partyFromAnonymous(it) ?: if (ignoreUnrecognisedParties) return@mapNotNull null else throw IllegalArgumentException("Could not find Party for $it")) to it + (identityService.wellKnownPartyFromAnonymous(it) ?: if (ignoreUnrecognisedParties) return@mapNotNull null else throw IllegalArgumentException("Could not find Party for $it")) to it } return partyToPublicKey.toMultiMap() } @@ -331,7 +331,7 @@ interface ServiceHub : ServicesForResolution { /** * Remove this node from a map of well known [Party]s. * - * @return a new copy of the map, with the well known [Party] for this node removed. + * @return a new copy of the map, with he well known [Party] for this node removed. */ fun excludeMe(map: Map): Map = map.filterKeys { !myInfo.isLegalIdentity(it) } diff --git a/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt b/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt index da4ee3e600..41a60bb30d 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/IdentityService.kt @@ -42,46 +42,48 @@ interface IdentityService { fun getAllIdentities(): Iterable /** - * Get the certificate and path for a well known identity's owning key. + * Get the certificate and path for a known identity's owning key. * * @return the party and certificate, or null if unknown. */ fun certificateFromKey(owningKey: PublicKey): PartyAndCertificate? /** - * Get the certificate and path for a well known identity. - * - * @return the party and certificate. - * @throws IllegalArgumentException if the certificate and path are unknown. This should never happen for a well - * known identity. + * Converts an owning [PublicKey] to the X500Name extended [Party] object if the [Party] has been + * previously registered with the [IdentityService] either as a well known network map identity, + * or as a part of flows creating and exchanging the identity. + * @param key The owning [PublicKey] of the [Party]. + * @return Returns a [Party] with a matching owningKey if known, else returns null. */ - fun certificateFromParty(party: Party): PartyAndCertificate - - // There is no method for removing identities, as once we are made aware of a Party we want to keep track of them - // indefinitely. It may be that in the long term we need to drop or archive very old Party information for space, - // but for now this is not supported. - fun partyFromKey(key: PublicKey): Party? - fun partyFromX500Name(name: CordaX500Name): Party? + /** + * Resolves a party name to the well known identity [Party] instance for this name. + * @param name The [CordaX500Name] to search for. + * @return If known the canonical [Party] with that name, else null. + */ + fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? /** - * Returns the well known identity from an abstract party. This is intended to resolve the well known identity - * from a confidential identity, however it transparently handles returning the well known identity back if + * Returns the well known identity from an [AbstractParty]. This is intended to resolve the well known identity, + * as visible in the [NetworkMapCache] from a confidential identity. + * It transparently handles returning the well known identity back if * a well known identity is passed in. * * @param party identity to determine well known identity for. * @return well known identity, if found. */ - fun partyFromAnonymous(party: AbstractParty): Party? + fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? /** - * Resolve the well known identity of a party. If the party passed in is already a well known identity - * (i.e. a [Party]) this returns it as-is. + * Returns the well known identity from a PartyAndReference. This is intended to resolve the well known identity, + * as visible in the [NetworkMapCache] from a confidential identity. + * It transparently handles returning the well known identity back if + * a well known identity is passed in. * * @return the well known identity, or null if unknown. */ - fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party) + fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party) /** * Resolve the well known identity of a party. Throws an exception if the party cannot be identified. @@ -90,7 +92,7 @@ interface IdentityService { * @return the well known identity. * @throws IllegalArgumentException */ - fun requirePartyFromAnonymous(party: AbstractParty): Party + fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party /** * Returns a list of candidate matches for a given string, with optional fuzzy(ish) matching. Fuzzy matching may diff --git a/docs/source/api-rpc.rst b/docs/source/api-rpc.rst index 8f37fa9beb..8c7d79d9a5 100644 --- a/docs/source/api-rpc.rst +++ b/docs/source/api-rpc.rst @@ -23,7 +23,7 @@ The key RPC operations exposed by the node are: * Returns the node's identity * ``CordaRPCOps.currentNodeTime`` * Returns the node's current time -* ``CordaRPCOps.partyFromKey/CordaRPCOps.partyFromX500Name`` +* ``CordaRPCOps.partyFromKey/CordaRPCOps.wellKnownPartyFromX500Name`` * Retrieves a party on the network based on a public key or X500 name * ``CordaRPCOps.uploadAttachment``/``CordaRPCOps.openAttachment``/``CordaRPCOps.attachmentExists`` * Uploads, opens and checks for the existence of attachments \ No newline at end of file diff --git a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java index 247b3160d2..094d1757f0 100644 --- a/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java +++ b/docs/source/example-code/src/main/java/net/corda/docs/FlowCookbookJava.java @@ -135,7 +135,7 @@ public class FlowCookbookJava { // We may also need to identify a specific counterparty. // Again, we do so using the network map. // DOCSTART 2 - Party namedCounterparty = getServiceHub().getIdentityService().partyFromX500Name(new CordaX500Name("NodeA", "London", "UK")); + Party namedCounterparty = getServiceHub().getIdentityService().wellKnownPartyFromX500Name(new CordaX500Name("NodeA", "London", "UK")); Party keyedCounterparty = getServiceHub().getIdentityService().partyFromKey(dummyPubKey); // DOCEND 2 diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt index f16983a6c8..a3063e930d 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/FlowCookbook.kt @@ -116,7 +116,7 @@ object FlowCookbook { // We may also need to identify a specific counterparty. We // do so using identity service. // DOCSTART 2 - val namedCounterparty: Party = serviceHub.identityService.partyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) ?: + val namedCounterparty: Party = serviceHub.identityService.wellKnownPartyFromX500Name(CordaX500Name(organisation = "NodeA", locality = "London", country = "UK")) ?: throw IllegalArgumentException("Couldn't find counterparty for NodeA in identity service") val keyedCounterparty: Party = serviceHub.identityService.partyFromKey(dummyPubKey) ?: throw IllegalArgumentException("Couldn't find counterparty with key: $dummyPubKey in identity service") diff --git a/docs/source/tutorial-attachments.rst b/docs/source/tutorial-attachments.rst index 90dd58750c..09a2736b38 100644 --- a/docs/source/tutorial-attachments.rst +++ b/docs/source/tutorial-attachments.rst @@ -90,7 +90,7 @@ transaction and send it to the recipient node: fun sender(rpc: CordaRPCOps) { // Get the identity key of the other side (the recipient). - val otherSide: Party = rpc.partyFromName("Bank B")!! + val otherSide: Party = rpc.wellKnownPartyFromName("Bank B")!! // Make sure we have the file in storage // TODO: We should have our own demo file, not share the trader demo file diff --git a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt index 63bb087726..763f0d4cff 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/CashExitFlow.kt @@ -65,7 +65,7 @@ class CashExitFlow(private val amount: Amount, // TODO: Is it safe to drop participants we don't know how to contact? Does not knowing how to contact them // count as a reason to fail? val participants: Set = inputStates - .mapNotNull { serviceHub.identityService.partyFromAnonymous(it.state.data.owner) } + .mapNotNull { serviceHub.identityService.wellKnownPartyFromAnonymous(it.state.data.owner) } .toSet() // Sign transaction progressTracker.currentStep = SIGNING_TX diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt index 8398bb37c5..b60635c4e3 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyDealFlow.kt @@ -134,8 +134,8 @@ object TwoPartyDealFlow { progressTracker.currentStep = VERIFYING return handshake.unwrap { // Verify the transaction identities represent the correct parties - val wellKnownOtherParty = serviceHub.identityService.partyFromAnonymous(it.primaryIdentity) - val wellKnownMe = serviceHub.identityService.partyFromAnonymous(it.secondaryIdentity) + val wellKnownOtherParty = serviceHub.identityService.wellKnownPartyFromAnonymous(it.primaryIdentity) + val wellKnownMe = serviceHub.identityService.wellKnownPartyFromAnonymous(it.secondaryIdentity) require(wellKnownOtherParty == otherSideSession.counterparty) require(wellKnownMe == ourIdentity) validateHandshake(it) diff --git a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt index 57a862041c..b69fad717a 100644 --- a/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt +++ b/finance/src/main/kotlin/net/corda/finance/flows/TwoPartyTradeFlow.kt @@ -98,7 +98,7 @@ object TwoPartyTradeFlow { val states: Iterable = stx.tx.inputs.map { serviceHub.loadState(it).data } + stx.tx.outputs.map { it.data } states.forEach { state -> state.participants.forEach { anon -> - require(serviceHub.identityService.partyFromAnonymous(anon) != null) { + require(serviceHub.identityService.wellKnownPartyFromAnonymous(anon) != null) { "Transaction state $state involves unknown participant $anon" } } @@ -197,7 +197,7 @@ object TwoPartyTradeFlow { // The asset must either be owned by the well known identity of the counterparty, or we must be able to // prove the owner is a confidential identity of the counterparty. - val assetForSaleIdentity = serviceHub.identityService.partyFromAnonymous(asset.owner) + val assetForSaleIdentity = serviceHub.identityService.wellKnownPartyFromAnonymous(asset.owner) require(assetForSaleIdentity == sellerSession.counterparty) // Register the identity we're about to send payment to. This shouldn't be the same as the asset owner diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt index 36cd3a6979..97d4d83503 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/LargeTransactionsTest.kt @@ -37,7 +37,7 @@ class LargeTransactionsTest { .addAttachment(hash4) val stx = serviceHub.signInitialTransaction(tx, ourIdentity.owningKey) // Send to the other side and wait for it to trigger resolution from us. - val bob = serviceHub.identityService.partyFromX500Name(BOB.name)!! + val bob = serviceHub.identityService.wellKnownPartyFromX500Name(BOB.name)!! val bobSession = initiateFlow(bob) subFlow(SendTransactionFlow(bobSession, stx)) bobSession.receive() diff --git a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt index 7e831fb50f..ac94252dc3 100644 --- a/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt +++ b/node/src/main/kotlin/net/corda/node/internal/CordaRPCOpsImpl.kt @@ -182,9 +182,9 @@ class CordaRPCOpsImpl( } } - override fun partyFromAnonymous(party: AbstractParty): Party? { + override fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? { return database.transaction { - services.identityService.partyFromAnonymous(party) + services.identityService.wellKnownPartyFromAnonymous(party) } } @@ -194,9 +194,9 @@ class CordaRPCOpsImpl( } } - override fun partyFromX500Name(x500Name: CordaX500Name): Party? { + override fun wellKnownPartyFromX500Name(x500Name: CordaX500Name): Party? { return database.transaction { - services.identityService.partyFromX500Name(x500Name) + services.identityService.wellKnownPartyFromX500Name(x500Name) } } diff --git a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt index 39559168c8..9ee5707a57 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/InMemoryIdentityService.kt @@ -75,14 +75,13 @@ class InMemoryIdentityService(identities: Iterable = emptyS } override fun certificateFromKey(owningKey: PublicKey): PartyAndCertificate? = keyToParties[owningKey] - override fun certificateFromParty(party: Party): PartyAndCertificate = principalToParties[party.name] ?: throw IllegalArgumentException("Unknown identity ${party.name}") // We give the caller a copy of the data set to avoid any locking problems override fun getAllIdentities(): Iterable = ArrayList(keyToParties.values) override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]?.party - override fun partyFromX500Name(name: CordaX500Name): Party? = principalToParties[name]?.party - override fun partyFromAnonymous(party: AbstractParty): Party? { + override fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? = principalToParties[name]?.party + override fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? { // Expand the anonymous party to a full party (i.e. has a name) if possible val candidate = party as? Party ?: keyToParties[party.owningKey]?.party // TODO: This should be done via the network map cache, which is the authoritative source of well known identities @@ -95,9 +94,9 @@ class InMemoryIdentityService(identities: Iterable = emptyS null } } - override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party) - override fun requirePartyFromAnonymous(party: AbstractParty): Party { - return partyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") + override fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party) + override fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party { + return wellKnownPartyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") } override fun partiesFromName(query: String, exactMatch: Boolean): Set { diff --git a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt index c28a96da49..9b739f455c 100644 --- a/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt +++ b/node/src/main/kotlin/net/corda/node/services/identity/PersistentIdentityService.kt @@ -9,6 +9,7 @@ import net.corda.core.internal.toX509CertHolder import net.corda.core.node.services.IdentityService import net.corda.core.node.services.UnknownAnonymousPartyException import net.corda.core.serialization.SingletonSerializeAsToken +import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.NODE_DATABASE_PREFIX @@ -124,7 +125,7 @@ class PersistentIdentityService(identities: Iterable = empt throw e } - log.info("Registering identity $identity") + log.debug { "Registering identity $identity" } val key = mapToKey(identity) keyToParties.addWithDuplicatesAllowed(key, identity) // Always keep the first party we registered, as that's the well known identity @@ -141,14 +142,12 @@ class PersistentIdentityService(identities: Iterable = empt } else null } - override fun certificateFromParty(party: Party): PartyAndCertificate = certificateFromCordaX500Name(party.name) ?: throw IllegalArgumentException("Unknown identity ${party.name}") - // We give the caller a copy of the data set to avoid any locking problems override fun getAllIdentities(): Iterable = keyToParties.allPersisted().map { it.second }.asIterable() override fun partyFromKey(key: PublicKey): Party? = certificateFromKey(key)?.party - override fun partyFromX500Name(name: CordaX500Name): Party? = certificateFromCordaX500Name(name)?.party - override fun partyFromAnonymous(party: AbstractParty): Party? { + override fun wellKnownPartyFromX500Name(name: CordaX500Name): Party? = certificateFromCordaX500Name(name)?.party + override fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? { // Expand the anonymous party to a full party (i.e. has a name) if possible val candidate = party as? Party ?: partyFromKey(party.owningKey) // TODO: This should be done via the network map cache, which is the authoritative source of well known identities @@ -156,16 +155,16 @@ class PersistentIdentityService(identities: Iterable = empt return if (candidate != null) { // If we have a well known identity by that name, use it in preference to the candidate. Otherwise default // back to the candidate. - val res = partyFromX500Name(candidate.name) ?: candidate + val res = wellKnownPartyFromX500Name(candidate.name) ?: candidate res } else { null } } - override fun partyFromAnonymous(partyRef: PartyAndReference) = partyFromAnonymous(partyRef.party) - override fun requirePartyFromAnonymous(party: AbstractParty): Party { - return partyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") + override fun wellKnownPartyFromAnonymous(partyRef: PartyAndReference) = wellKnownPartyFromAnonymous(partyRef.party) + override fun requireWellKnownPartyFromAnonymous(party: AbstractParty): Party { + return wellKnownPartyFromAnonymous(party) ?: throw IllegalStateException("Could not deanonymise party ${party.owningKey.toStringShort()}") } override fun partiesFromName(query: String, exactMatch: Boolean): Set { diff --git a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt index 788e0a94fb..45e2b6f9b0 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/PersistentNetworkMapCache.kt @@ -110,7 +110,7 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal) override fun getNodesByLegalIdentityKey(identityKey: PublicKey): List = serviceHub.database.transaction { queryByIdentityKey(identityKey) } override fun getNodeByLegalIdentity(party: AbstractParty): NodeInfo? { - val wellKnownParty = serviceHub.identityService.partyFromAnonymous(party) + val wellKnownParty = serviceHub.identityService.wellKnownPartyFromAnonymous(party) return wellKnownParty?.let { getNodesByLegalIdentityKey(it.owningKey).singleOrNull() } diff --git a/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt b/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt index f93048868e..ac1d696af7 100644 --- a/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt +++ b/node/src/main/kotlin/net/corda/node/services/persistence/AbstractPartyToX500NameAsStringConverter.kt @@ -21,7 +21,7 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic override fun convertToDatabaseColumn(party: AbstractParty?): String? { if (party != null) { - val partyName = identityService.partyFromAnonymous(party)?.toString() + val partyName = identityService.wellKnownPartyFromAnonymous(party)?.toString() if (partyName != null) return partyName log.warn("Identity service unable to resolve AbstractParty: $party") } @@ -30,7 +30,7 @@ class AbstractPartyToX500NameAsStringConverter(identitySvc: () -> IdentityServic override fun convertToEntityAttribute(dbData: String?): AbstractParty? { if (dbData != null) { - val party = identityService.partyFromX500Name(CordaX500Name.parse(dbData)) + val party = identityService.wellKnownPartyFromX500Name(CordaX500Name.parse(dbData)) if (party != null) return party log.warn ("Identity service unable to resolve X500name: $dbData") } diff --git a/node/src/test/kotlin/net/corda/node/services/network/InMemoryIdentityServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/network/InMemoryIdentityServiceTests.kt index f54747a578..e7f87f6104 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/InMemoryIdentityServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/InMemoryIdentityServiceTests.kt @@ -54,7 +54,7 @@ class InMemoryIdentityServiceTests { @Test fun `get identity by name with no registered identities`() { val service = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT) - assertNull(service.partyFromX500Name(ALICE.name)) + assertNull(service.wellKnownPartyFromX500Name(ALICE.name)) } @Test @@ -74,9 +74,9 @@ class InMemoryIdentityServiceTests { val service = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT) val identities = listOf("Org A", "Org B", "Org C") .map { getTestPartyAndCertificate(CordaX500Name(organisation = it, locality = "London", country = "GB"), generateKeyPair().public) } - assertNull(service.partyFromX500Name(identities.first().name)) + assertNull(service.wellKnownPartyFromX500Name(identities.first().name)) identities.forEach { service.verifyAndRegisterIdentity(it) } - identities.forEach { assertEquals(it.party, service.partyFromX500Name(it.name)) } + identities.forEach { assertEquals(it.party, service.wellKnownPartyFromX500Name(it.name)) } } /** @@ -171,7 +171,7 @@ class InMemoryIdentityServiceTests { @Test fun `deanonymising a well known identity`() { val expected = ALICE - val actual = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT).partyFromAnonymous(expected) + val actual = InMemoryIdentityService(trustRoot = DEV_TRUST_ROOT).wellKnownPartyFromAnonymous(expected) assertEquals(expected, actual) } } diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentIdentityServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentIdentityServiceTests.kt index 3d596f0b05..9c5163db2d 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentIdentityServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentIdentityServiceTests.kt @@ -88,7 +88,7 @@ class PersistentIdentityServiceTests { @Test fun `get identity by name with no registered identities`() { database.transaction { - assertNull(identityService.partyFromX500Name(ALICE.name)) + assertNull(identityService.wellKnownPartyFromX500Name(ALICE.name)) } } @@ -112,7 +112,7 @@ class PersistentIdentityServiceTests { val identities = listOf("Organisation A", "Organisation B", "Organisation C") .map { getTestPartyAndCertificate(CordaX500Name(organisation = it, locality = "London", country = "GB"), generateKeyPair().public) } database.transaction { - assertNull(identityService.partyFromX500Name(identities.first().name)) + assertNull(identityService.wellKnownPartyFromX500Name(identities.first().name)) } identities.forEach { database.transaction { @@ -121,7 +121,7 @@ class PersistentIdentityServiceTests { } identities.forEach { database.transaction { - assertEquals(it.party, identityService.partyFromX500Name(it.name)) + assertEquals(it.party, identityService.wellKnownPartyFromX500Name(it.name)) } } } @@ -245,7 +245,7 @@ class PersistentIdentityServiceTests { } val aliceParent = database.transaction { - newPersistentIdentityService.partyFromAnonymous(anonymousAlice.party.anonymise()) + newPersistentIdentityService.wellKnownPartyFromAnonymous(anonymousAlice.party.anonymise()) } assertEquals(alice.party, aliceParent!!) @@ -272,7 +272,7 @@ class PersistentIdentityServiceTests { fun `deanonymising a well known identity`() { val expected = ALICE val actual = database.transaction { - identityService.partyFromAnonymous(expected) + identityService.wellKnownPartyFromAnonymous(expected) } assertEquals(expected, actual) } diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt index 630255cd71..f33f151428 100644 --- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt +++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/AttachmentDemo.kt @@ -87,8 +87,8 @@ fun sender(rpc: CordaRPCOps, numOfClearBytes: Int = 1024) { // default size 1K. private fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256, executor: ScheduledExecutorService) { // Get the identity key of the other side (the recipient). - val notaryFuture: CordaFuture = poll(executor, DUMMY_NOTARY.name.toString()) { rpc.partyFromX500Name(DUMMY_NOTARY.name) } - val otherSideFuture: CordaFuture = poll(executor, DUMMY_BANK_B.name.toString()) { rpc.partyFromX500Name(DUMMY_BANK_B.name) } + val notaryFuture: CordaFuture = poll(executor, DUMMY_NOTARY.name.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_NOTARY.name) } + val otherSideFuture: CordaFuture = poll(executor, DUMMY_BANK_B.name.toString()) { rpc.wellKnownPartyFromX500Name(DUMMY_BANK_B.name) } // Make sure we have the file in storage if (!rpc.attachmentExists(hash)) { diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt index 39b738f04b..455c090973 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaClientApi.kt @@ -39,7 +39,7 @@ class BankOfCordaClientApi(val hostAndPort: NetworkHostAndPort) { rpc.waitUntilNetworkReady() // Resolve parties via RPC - val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) + val issueToParty = rpc.wellKnownPartyFromX500Name(params.issueToPartyName) ?: throw IllegalStateException("Unable to locate ${params.issueToPartyName} in Network Map Service") val notaryLegalIdentity = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } ?: throw IllegalStateException("Couldn't locate notary ${params.notaryName} in NetworkMapCache") diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt index b651455765..8180350c74 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/api/BankOfCordaWebApi.kt @@ -41,9 +41,9 @@ class BankOfCordaWebApi(val rpc: CordaRPCOps) { @Consumes(MediaType.APPLICATION_JSON) fun issueAssetRequest(params: IssueRequestParams): Response { // Resolve parties via RPC - val issueToParty = rpc.partyFromX500Name(params.issueToPartyName) + val issueToParty = rpc.wellKnownPartyFromX500Name(params.issueToPartyName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issueToPartyName} in identity service").build() - rpc.partyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build() + rpc.wellKnownPartyFromX500Name(params.issuerBankName) ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate ${params.issuerBankName} in identity service").build() val notaryParty = rpc.notaryIdentities().firstOrNull { it.name == params.notaryName } ?: return Response.status(Response.Status.FORBIDDEN).entity("Unable to locate notary ${params.notaryName} in network map").build() diff --git a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt index e44cc055cc..e7d1074362 100644 --- a/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt +++ b/samples/irs-demo/src/main/kotlin/net/corda/irs/flows/FixingFlow.kt @@ -136,7 +136,7 @@ object FixingFlow { val myKey = ourIdentity.owningKey if (parties[0].owningKey == myKey) { val fixing = FixingSession(ref, fixableDeal.oracle) - val counterparty = serviceHub.identityService.partyFromAnonymous(parties[1]) ?: throw IllegalStateException("Cannot resolve floater party") + val counterparty = serviceHub.identityService.wellKnownPartyFromAnonymous(parties[1]) ?: throw IllegalStateException("Cannot resolve floater party") // Start the Floater which will then kick-off the Fixer val session = initiateFlow(counterparty) subFlow(Floater(session, fixing)) diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt index 852777bdfe..9bf30f2051 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmFlow.kt @@ -115,7 +115,7 @@ object SimmFlow { val state = stateRef.state.data val portfolio = serviceHub.vaultQueryService.queryBy(VaultQueryCriteria(stateRefs = state.portfolio)).states.toPortfolio() - val valuer = serviceHub.identityService.partyFromAnonymous(state.valuer) + val valuer = serviceHub.identityService.wellKnownPartyFromAnonymous(state.valuer) require(valuer != null) { "Valuer party must be known to this node" } val valuation = agreeValuation(portfolio, valuationDate, valuer!!) val update = PortfolioState.Update(valuation = valuation) @@ -317,7 +317,7 @@ object SimmFlow { @Suspendable private fun updateValuation(stateRef: StateAndRef) { val portfolio = serviceHub.vaultQueryService.queryBy(VaultQueryCriteria(stateRefs = stateRef.state.data.portfolio)).states.toPortfolio() - val valuer = serviceHub.identityService.partyFromAnonymous(stateRef.state.data.valuer) ?: throw IllegalStateException("Unknown valuer party ${stateRef.state.data.valuer}") + val valuer = serviceHub.identityService.wellKnownPartyFromAnonymous(stateRef.state.data.valuer) ?: throw IllegalStateException("Unknown valuer party ${stateRef.state.data.valuer}") val valuation = agreeValuation(portfolio, offer.valuationDate, valuer) subFlow(object : StateRevisionFlow.Receiver(replyToSession) { override fun verifyProposal(stx: SignedTransaction, proposal: Proposal) { diff --git a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt index 72fa97480a..8f607163ef 100644 --- a/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt +++ b/samples/simm-valuation-demo/src/main/kotlin/net/corda/vega/flows/SimmRevaluation.kt @@ -23,7 +23,7 @@ object SimmRevaluation { val stateAndRef = serviceHub.vaultQueryService.queryBy(VaultQueryCriteria(stateRefs = listOf(curStateRef))).states.single() val curState = stateAndRef.state.data if (ourIdentity == curState.participants[0]) { - val otherParty = serviceHub.identityService.partyFromAnonymous(curState.participants[1]) + val otherParty = serviceHub.identityService.wellKnownPartyFromAnonymous(curState.participants[1]) require(otherParty != null) { "Other party must be known by this node" } subFlow(SimmFlow.Requester(otherParty!!, valuationDate, stateAndRef)) } diff --git a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt index 5fdccd69af..e373de677d 100644 --- a/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt +++ b/samples/trader-demo/src/main/kotlin/net/corda/traderdemo/TraderDemoClientApi.kt @@ -43,8 +43,8 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) { fun runIssuer(amount: Amount, buyerName: CordaX500Name, sellerName: CordaX500Name) { val ref = OpaqueBytes.of(1) - val buyer = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") - val seller = rpc.partyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") + val buyer = rpc.wellKnownPartyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") + val seller = rpc.wellKnownPartyFromX500Name(sellerName) ?: throw IllegalStateException("Don't know $sellerName") val notaryIdentity = rpc.notaryIdentities().first() val amounts = calculateRandomlySizedAmounts(amount, 3, 10, Random()) @@ -73,7 +73,7 @@ class TraderDemoClientApi(val rpc: CordaRPCOps) { } fun runSeller(amount: Amount = 1000.0.DOLLARS, buyerName: CordaX500Name) { - val otherParty = rpc.partyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") + val otherParty = rpc.wellKnownPartyFromX500Name(buyerName) ?: throw IllegalStateException("Don't know $buyerName") // The seller will sell some commercial paper to the buyer, who will pay with (self issued) cash. // // The CP sale transaction comes with a prospectus PDF, which will tag along for the ride in an From c05e482c8ff4c36d01d62e9a197f193d913b7274 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 21 Sep 2017 15:32:02 +0100 Subject: [PATCH 033/230] Change public constant values to Kotlin constants (#1588) * Make string constants into Kotlin constants * Add JvmName annotation to KeyStoreUtilities --- .../kotlin/net/corda/core/crypto/CompositeKey.kt | 2 +- .../finance/contracts/universal/UniversalContract.kt | 2 +- .../asset/cash/selection/CashSelectionH2Impl.kt | 2 +- .../asset/cash/selection/CashSelectionMySQLImpl.kt | 2 +- .../src/main/kotlin/net/corda/nodeapi/VerifierApi.kt | 10 +++++----- .../nodeapi/internal/serialization/amqp/Schema.kt | 4 ++-- .../corda/node/services/network/NetworkMapService.kt | 12 ++++++------ .../net/corda/node/utilities/KeyStoreUtilities.kt | 4 +++- .../kotlin/net/corda/node/utilities/X509Utilities.kt | 10 +++++----- .../corda/testing/node/InMemoryMessagingNetwork.kt | 2 +- 10 files changed, 26 insertions(+), 24 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt b/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt index 3d7824751d..aac941d413 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/CompositeKey.kt @@ -30,7 +30,7 @@ import java.util.* @CordaSerializable class CompositeKey private constructor(val threshold: Int, children: List) : PublicKey { companion object { - val KEY_ALGORITHM = "COMPOSITE" + const val KEY_ALGORITHM = "COMPOSITE" /** * Build a composite key from a DER encoded form. */ diff --git a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt index 275d24a54d..6f12d53844 100644 --- a/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt +++ b/experimental/src/main/kotlin/net/corda/finance/contracts/universal/UniversalContract.kt @@ -10,7 +10,7 @@ import net.corda.finance.contracts.FixOf import java.math.BigDecimal import java.time.Instant -val UNIVERSAL_PROGRAM_ID = "net.corda.finance.contracts.universal.UniversalContract" +const val UNIVERSAL_PROGRAM_ID = "net.corda.finance.contracts.universal.UniversalContract" class UniversalContract : Contract { data class State(override val participants: List, diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt index e402103630..fb3a84371b 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionH2Impl.kt @@ -25,7 +25,7 @@ import kotlin.concurrent.withLock class CashSelectionH2Impl : CashSelection { companion object { - val JDBC_DRIVER_NAME = "H2 JDBC Driver" + const val JDBC_DRIVER_NAME = "H2 JDBC Driver" val log = loggerFor() } diff --git a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt index 0651bcdf70..73a49e8a18 100644 --- a/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt +++ b/finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/CashSelectionMySQLImpl.kt @@ -14,7 +14,7 @@ import java.util.* class CashSelectionMySQLImpl : CashSelection { companion object { - val JDBC_DRIVER_NAME = "MySQL JDBC Driver" + const val JDBC_DRIVER_NAME = "MySQL JDBC Driver" } override fun isCompatible(metadata: DatabaseMetaData): Boolean { diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/VerifierApi.kt b/node-api/src/main/kotlin/net/corda/nodeapi/VerifierApi.kt index 4fa1526536..eee653b30f 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/VerifierApi.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/VerifierApi.kt @@ -8,11 +8,11 @@ import org.apache.activemq.artemis.api.core.client.ClientMessage import org.apache.activemq.artemis.reader.MessageUtil object VerifierApi { - val VERIFIER_USERNAME = "SystemUsers/Verifier" - val VERIFICATION_REQUESTS_QUEUE_NAME = "verifier.requests" - val VERIFICATION_RESPONSES_QUEUE_NAME_PREFIX = "verifier.responses" - private val VERIFICATION_ID_FIELD_NAME = "id" - private val RESULT_EXCEPTION_FIELD_NAME = "result-exception" + const val VERIFIER_USERNAME = "SystemUsers/Verifier" + const val VERIFICATION_REQUESTS_QUEUE_NAME = "verifier.requests" + const val VERIFICATION_RESPONSES_QUEUE_NAME_PREFIX = "verifier.responses" + private const val VERIFICATION_ID_FIELD_NAME = "id" + private const val RESULT_EXCEPTION_FIELD_NAME = "result-exception" data class VerificationRequest( val verificationId: Long, diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/Schema.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/Schema.kt index b0029d36a5..4ec6bb32cf 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/Schema.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/amqp/Schema.kt @@ -18,9 +18,9 @@ import net.corda.nodeapi.internal.serialization.carpenter.Field as CarpenterFiel import net.corda.nodeapi.internal.serialization.carpenter.Schema as CarpenterSchema // TODO: get an assigned number as per AMQP spec -val DESCRIPTOR_TOP_32BITS: Long = 0xc0da0000 +const val DESCRIPTOR_TOP_32BITS: Long = 0xc0da0000 -val DESCRIPTOR_DOMAIN: String = "net.corda" +const val DESCRIPTOR_DOMAIN: String = "net.corda" // "corda" + majorVersionByte + minorVersionMSB + minorVersionLSB val AmqpHeaderV1_0: OpaqueBytes = OpaqueBytes("corda\u0001\u0000\u0000".toByteArray()) diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt index c0fa5d0778..f69b3d6736 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt @@ -62,15 +62,15 @@ interface NetworkMapService { companion object { val DEFAULT_EXPIRATION_PERIOD: Period = Period.ofWeeks(4) - val FETCH_TOPIC = "platform.network_map.fetch" - val QUERY_TOPIC = "platform.network_map.query" - val REGISTER_TOPIC = "platform.network_map.register" - val SUBSCRIPTION_TOPIC = "platform.network_map.subscribe" + const val FETCH_TOPIC = "platform.network_map.fetch" + const val QUERY_TOPIC = "platform.network_map.query" + const val REGISTER_TOPIC = "platform.network_map.register" + const val SUBSCRIPTION_TOPIC = "platform.network_map.subscribe" // Base topic used when pushing out updates to the network map. Consumed, for example, by the map cache. // When subscribing to these updates, remember they must be acknowledged - val PUSH_TOPIC = "platform.network_map.push" + const val PUSH_TOPIC = "platform.network_map.push" // Base topic for messages acknowledging pushed updates - val PUSH_ACK_TOPIC = "platform.network_map.push_ack" + const val PUSH_ACK_TOPIC = "platform.network_map.push_ack" val type = ServiceType.networkMap } diff --git a/node/src/main/kotlin/net/corda/node/utilities/KeyStoreUtilities.kt b/node/src/main/kotlin/net/corda/node/utilities/KeyStoreUtilities.kt index f903bedce7..5966f88599 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/KeyStoreUtilities.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/KeyStoreUtilities.kt @@ -1,3 +1,5 @@ +@file:JvmName("KeyStoreUtilities") + package net.corda.node.utilities import net.corda.core.crypto.Crypto @@ -14,7 +16,7 @@ import java.security.cert.Certificate import java.security.cert.CertificateFactory import java.security.cert.X509Certificate -val KEYSTORE_TYPE = "JKS" +const val KEYSTORE_TYPE = "JKS" /** * Helper method to either open an existing keystore for modification, or create a new blank keystore. diff --git a/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt b/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt index fb7baec51e..a9685fd910 100644 --- a/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt +++ b/node/src/main/kotlin/net/corda/node/utilities/X509Utilities.kt @@ -44,12 +44,12 @@ object X509Utilities { val DEFAULT_TLS_SIGNATURE_SCHEME = Crypto.ECDSA_SECP256R1_SHA256 // Aliases for private keys and certificates. - val CORDA_ROOT_CA = "cordarootca" - val CORDA_INTERMEDIATE_CA = "cordaintermediateca" - val CORDA_CLIENT_TLS = "cordaclienttls" - val CORDA_CLIENT_CA = "cordaclientca" + const val CORDA_ROOT_CA = "cordarootca" + const val CORDA_INTERMEDIATE_CA = "cordaintermediateca" + const val CORDA_CLIENT_TLS = "cordaclienttls" + const val CORDA_CLIENT_CA = "cordaclientca" - val CORDA_CLIENT_CA_CN = "Corda Client CA Certificate" + const val CORDA_CLIENT_CA_CN = "Corda Client CA Certificate" private val DEFAULT_VALIDITY_WINDOW = Pair(0.millis, 3650.days) /** diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt index e16e3c9eef..bf109863eb 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/InMemoryMessagingNetwork.kt @@ -50,7 +50,7 @@ class InMemoryMessagingNetwork( private val messagesInFlight: ReusableLatch = ReusableLatch() ) : SingletonSerializeAsToken() { companion object { - val MESSAGES_LOG_NAME = "messages" + const val MESSAGES_LOG_NAME = "messages" private val log = LoggerFactory.getLogger(MESSAGES_LOG_NAME) } From 58be3ac7007f7ac9ffa0a2ca55cb481a8304544e Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Thu, 21 Sep 2017 16:19:58 +0100 Subject: [PATCH 034/230] CORDA-570: Display calendar name instead of long and incomplete list of holiday dates (#1590) --- .../src/main/resources/irsweb/view/deal.html | 28 +++++-------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/samples/irs-demo/src/main/resources/irsweb/view/deal.html b/samples/irs-demo/src/main/resources/irsweb/view/deal.html index 75631779b2..30feb20acd 100644 --- a/samples/irs-demo/src/main/resources/irsweb/view/deal.html +++ b/samples/irs-demo/src/main/resources/irsweb/view/deal.html @@ -96,13 +96,7 @@ Holiday Dates

@@ -162,13 +156,9 @@ Holiday Dates
- - - - - - -
{{date}}
+ + {{deal.floatingLeg.paymentCalendar}} +
@@ -189,13 +179,9 @@ Holiday Dates
- - - - - - -
{{date}}
+ + {{deal.floatingLeg.fixingCalendar}} +
From 29e648d11c57e6c0f1551b8512e2619b182b08ff Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Thu, 21 Sep 2017 18:10:10 +0100 Subject: [PATCH 035/230] Removes references to clauses from the docs. (#1595) --- docs/source/clauses.rst | 278 ---------------------- docs/source/glossary.rst | 2 - docs/source/other-index.rst | 2 - docs/source/tutorial-contract-clauses.rst | 267 --------------------- docs/source/tutorial-contract.rst | 12 +- docs/source/tutorials-index.rst | 1 - 6 files changed, 1 insertion(+), 561 deletions(-) delete mode 100644 docs/source/clauses.rst delete mode 100644 docs/source/tutorial-contract-clauses.rst diff --git a/docs/source/clauses.rst b/docs/source/clauses.rst deleted file mode 100644 index 93b6b097ad..0000000000 --- a/docs/source/clauses.rst +++ /dev/null @@ -1,278 +0,0 @@ -Clauses -======= - -Basic clause structure ----------------------- - -A clause is a small building block for assembling contract verification logic, reusable and ready to test in separation. -To see clauses in action go to: :doc:`tutorial-contract-clauses`. -Let's take a look at a simplified structure of the ``Clause`` class: - -.. container:: codeset - - .. sourcecode:: kotlin - - abstract class Clause { - - /** Determine whether this clause runs or not */ - open val requiredCommands: Set> = emptySet() - - @Throws(IllegalStateException::class) - abstract fun verify(tx: LedgerTransaction, - inputs: List, - outputs: List, - commands: List>, - groupingKey: K?): Set - ... - } - -Basic clause structure contains two important components: ``requiredCommands`` and ``verify`` function. -A clause is triggered when all ``requiredCommands`` are present in transaction's command set (opposite inclusion doesn't have to hold). -Then the ``verify`` function is run, which checks if transaction meets conditions specified by this clause. Verification -is no different than normal contract verification but using clauses it's split into smaller generic code blocks with single verify method. - -When writing a contract you need to override the contract's ``verify`` function which should call ``verifyClause``. See: :ref:`verify_ref`. - -.. note:: A clause ``verify`` function returns the set of processed commands, at the end of ``verifyClause`` execution - there is a check if all of transaction's commands were matched. If not, then an exception is raised. This is done to - enforce that spurious commands cannot be included in a transaction, ensuring that the transaction is as clear as - possible. As an example imagine a transaction with two commands: ``Move`` and ``Issue`` included, with verification written - using ``FirstOf`` on clauses that require single command set. Thus only one of transaction's commands will match - leaving the second unprocessed. It should raise an error - we want to ensure that commands set is minimal to simplify - analysis of intent of a transaction. - -An example ``verify`` from ``Obligation`` contract: - -.. container:: codeset - - .. sourcecode:: kotlin - - override fun verify(tx: LedgerTransaction) = verifyClause(tx, FirstOf( - Clauses.Net(), - Clauses.Group

() - ), tx.commands.select()) - -It takes transaction to be verified, and passes it along with a top-level clause and commands to the ``verifyClause`` -function. As you can see above we have used ``FirstOf`` which is a special type of clause, which extends the -``CompositeClause`` abstract class (in that particular case, it ensures that either ``Net`` or ``Group`` will run - for explanation see `FirstOf`_). -It's a type of clause that adds support for encapsulating multiple clauses and defines common behaviour for that composition. -There is also a ``GroupClauseVerifier`` special clause, which specifies how to group transaction input/output states -together and passes them to adequate clause for further processing. - -Composition clauses -------------------- - -One of the most important concepts of clauses - composition clauses which extend ``CompositeClause`` abstract class, -providing a range of ways of assembling clauses together. They define a logic of verification execution specifying which clauses -will be run. - -AllOf -~~~~~ - -**Description** - -Composes a number of clauses, such that all of the clauses must run for verification to pass. - -.. image:: resources/allOfChart.png - -Short description: - -- ``AllOf`` holds clauses *Cl1,..,Cl5*. -- Check if all clauses that compose ``AllOf`` have associated commands in a command set - if not, verification fails. -- After successful check runs verification logic specific for every clause *Cl1,..,Cl5* from that composition. - -**Usage** - -See code in `GroupClauseVerifier`_. - -AnyOf -~~~~~ - -**Description** - -Composes a number of clauses, such that 1 or more of the clauses can be run. - -.. image:: resources/anyOfChart.png - -Short description: - -- Checks if one or more clauses that compose AnyOf have associated commands in a command set. -- After success runs verification logic specific for every *matched* (in this case *Cl2, Cl4, Cl5*) clause from composition. - -**Usage** - -Example from ``CommercialPaper.kt``: - -.. container:: codeset - - .. sourcecode:: kotlin - - class Group : GroupClauseVerifier>( - AnyOf( - Redeem(), - Move(), - Issue())) { - override fun groupStates(tx: LedgerTransaction): List>> - = tx.groupStates> { it.token } - } - -FirstOf -~~~~~~~ - -**Description** - -Composes a number of clauses, such that the first match is run, and it errors if none is run. - -.. image:: resources/firstOfChart.png - -Short description: - -- Takes first clause that matches and if none found throws an exception. -- If successful runs verification on the clause that matched (in this case *Cl4*). - -**Usage** - -See code in `GroupClauseVerifier`_. - - -Other types of clauses ----------------------- - -There are certain types of clauses that are specialized in particular types of contracts (like ``AbstractIssue``) or generally -should be used as helpers in building parts of logic (the most important one is ``GroupClauseVerifier``). - -GroupClauseVerifier -~~~~~~~~~~~~~~~~~~~ - -**Description** - -Groups input and output states according to ``groupStates`` function. Runs the top-level clause verification on each -group in turn. - -.. image:: resources/groupClauseVerifyChart.png - -Short description: - -``GroupClauseVerifier`` wraps clause *Cl1*. After grouping relevant states together with ``groupStates`` into three groups -*Gr1, Gr2, Gr3* runs *Cl1.verify(Gr1), Cl1.verify(Gr2), Cl1.verify(Gr3)*. - -For more detailed example head to :ref:`state_ref`. - -**Usage** - -You need to extend ``GroupClauseVerifier`` clause and define ``groupStates`` function which takes transaction and returns -grouped input and output states with a grouping key used for each group. Example from ``Obligation.kt`` contract: - -.. container:: codeset - - .. sourcecode:: kotlin - - class Group

: GroupClauseVerifier, Commands, Issued>>( - AllOf( - NoZeroSizedOutputs, Commands, Terms

>(), - FirstOf( - SetLifecycle

(), - AllOf( - VerifyLifecycle, Commands, Issued>, P>(), - FirstOf( - Settle

(), - Issue(), - ConserveAmount() - ) - ) - ) - ) - ) { - override fun groupStates(tx: LedgerTransaction): List, Issued>>> - = tx.groupStates, Issued>> { it.amount.token } - } - -Usually it's convenient to use ``groupStates`` function defined on ``LedgerTransaction`` class. Which given a type and a -selector function, that returns a grouping key, associates inputs and outputs together so that they can be processed as one. -The grouping key is any arbitrary object that can act as a map key (so must implement equals and hashCode). - -AbstractConserveAmount -~~~~~~~~~~~~~~~~~~~~~~ - -**Description** - -Standardised clause for checking input/output balances of fungible assets. Requires that a -Move command is provided, and errors if absent. Conserve amount clause can only be used on grouped states. - -**Usage** - -.. container:: codeset - - .. sourcecode:: kotlin - - /** - * Generic move/exit clause for fungible assets - */ - class ConserveAmount

: AbstractConserveAmount, Commands, Terms

>() - -See code in `GroupClauseVerifier`_. - -AbstractIssue -~~~~~~~~~~~~~ - -**Description** - -Standard issue clause for contracts that issue fungible assets. - -**Usage** - -Example from ``CommercialPaper.kt``: - -.. container:: codeset - - .. sourcecode:: kotlin - - class Issue : AbstractIssue( - { map { Amount(it.faceValue.quantity, it.token) }.sumOrThrow() }, - { token -> map { Amount(it.faceValue.quantity, it.token) }.sumOrZero(token) }) { - override val requiredCommands: Set> = setOf(Commands.Issue::class.java) - - override fun verify(tx: LedgerTransaction, - inputs: List, - outputs: List, - commands: List>, - groupingKey: Issued?): Set { - val consumedCommands = super.verify(tx, inputs, outputs, commands, groupingKey) - ... - -First function in constructor converts a list of states into an amount of the token. Must error if there are no states in the list. -Second function converts a list of states into an amount of the token, and returns zero if there are no states in the list. -Takes in an instance of the token definition for constructing the zero amount if needed. - -NoZeroSizedOutputs -~~~~~~~~~~~~~~~~~~ - -**Description** - -Clause for fungible asset contracts, which enforces that no output state should have a balance of zero. - -**Usage** - -See code in `GroupClauseVerifier`_. - -FilterOn -~~~~~~~~ - -**Description** - -Filter the states that are passed through to the wrapped clause, to restrict them to a specific type. - -``FilterOn`` narrows the scope of the states being verified. -Let's take a transaction with multiple cash states of different currencies, we want to run a clause that focuses -on only GBP cash states rather than all cash states. - -**Usage** - -.. container:: codeset - - .. sourcecode:: kotlin - - FilterOn(clause, { states -> states.filter { it.amount.token == GBP} }) - - -Takes ``filterStates`` function that limits states passed to ``clause`` verification. diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index 7e9763506e..05d5211fa6 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -5,8 +5,6 @@ Artemis The message queuing middleware used within Corda Attachment An attachment is a piece of data that can be referred to within a transaction but is never marked as used, i.e. can be referred to multiple times. -Clause - A clause is a reusable piece of code that performs transaction verification Command Used for directing a transaction, sometimes containing command data. For example, a Cash contract may include an Issue command, which signals that one of the purposes of the transaction is to issue cash on to the ledger (i.e. by creating one or more Cash outputs, without any corresponding inputs.) Composite Key diff --git a/docs/source/other-index.rst b/docs/source/other-index.rst index 5fd4d78554..d3971e9e8b 100644 --- a/docs/source/other-index.rst +++ b/docs/source/other-index.rst @@ -4,8 +4,6 @@ Other .. toctree:: :maxdepth: 1 - clauses - merkle-trees json secure-coding-guidelines corda-repo-layout diff --git a/docs/source/tutorial-contract-clauses.rst b/docs/source/tutorial-contract-clauses.rst deleted file mode 100644 index 6ddb5035af..0000000000 --- a/docs/source/tutorial-contract-clauses.rst +++ /dev/null @@ -1,267 +0,0 @@ -.. highlight:: kotlin -.. raw:: html - - - - -Writing a contract using clauses -================================ - -In this tutorial, we will restructure the commercial paper contract to use clauses. You should have -already completed ":doc:`tutorial-contract`". - -As before, this example is focused on a basic implementation of commercial paper (CP), which is essentially a simpler version of a corporate -bond. A company issues commercial paper with a particular face value, say $100, but sells it for less, say $90. The paper can be redeemed -for cash at a given future date. In our example, the commercial paper has a 10% interest rate, with a single repayment. -The full Kotlin code can be found in ``CommercialPaper.kt``. - -What are clauses and why use them? ----------------------------------- - -Clauses are essentially micro-contracts which contain independent verification logic, and can be logically composed -to form a complete contract. Clauses are designed to enable re-use of common verification parts. For example, issuing state objects -is generally the same for all fungible contracts, so a common issuance clause can be used for each contract's -issue clause. This cuts down on scope for error, and improves consistency of behaviour. By splitting verification logic -into smaller chunks, these can also be readily tested in isolation. - -How do clauses work? --------------------- - -There are different types of clauses. The most basic are those that define the verification logic for a single command -(e.g. ``Move``, ``Issue`` and ``Redeem``, in the case of commercial paper), or even run without any commands at all (e.g. ``Timestamp``). - -These basic clauses can then be combined using a ``CompositeClause``. The goal of composite clauses is to determine -which individual clauses need to be matched and verified for a given transaction -to be considered valid. We refer to a clause as being "matched" when the transaction has the required commands present for the clause -in question to trigger. Meanwhile, we talk about a clause "verifying" when its ``verify()`` function returns ``True``. - -As an example, let's say we want a transaction to be valid only when every single one of its clauses matches and verifies. We implement this -by wrapping the individual clauses into an ``AllOf`` composite clause, which ensures that a transaction is -only considered valid if all of its clauses are both matched and verify. - -There are two other basic composite clauses that you should be aware of: - - * ``AnyOf``, whereby 1 or more clauses may match, and every matched clause must verify - * ``FirstOf``, whereby at least one clause must match, and the first such clause must verify - -In turn, composite clauses are themselves ``Clause`` s, and can, for example, be wrapped in the special ``GroupClauseVerifier`` grouping clause. -For ``CommercialPaper``, this would look as follows: - -.. image:: resources/commPaperClauses.png - -For this tutorial, we will be using ``GroupClauseVerifier`` and ``AnyOf``. Since it's important to understand how these work, -charts showing their execution and other details can be found in :doc:`clauses`. - -.. _verify_ref: - -Commercial paper class ----------------------- - -We start by defining the ``CommercialPaper`` class. As in the previous tutorial, we need some elementary parts: a ``Commands`` interface, -``generateMove``, ``generateIssue``, ``generateRedeem``. So far, so good - these stay the same. The new part is verification and the -``Clauses`` interface (which we will see later in code). Let's start from the basic structure: - -.. container:: codeset - - .. sourcecode:: kotlin - - class CommercialPaper : Contract { - override fun verify(tx: LedgerTransaction) = verifyClause(tx, Clauses.Group(), tx.commands.select()) - - interface Commands : CommandData { - data class Move(override val contractHash: SecureHash? = null) : FungibleAsset.Commands.Move, Commands - class Redeem : TypeOnlyCommandData(), Commands - data class Issue(override val nonce: Long = random63BitValue()) : IssueCommand, Commands - } - - .. sourcecode:: java - - public class CommercialPaper implements Contract { - @Override - public void verify(@NotNull LedgerTransaction tx) throws IllegalArgumentException { - ClauseVerifier.verifyClause(tx, new Clauses.Group(), extractCommands(tx)); - } - - public interface Commands extends CommandData { - class Move implements Commands { - @Override - public boolean equals(Object obj) { return obj instanceof Move; } - } - - class Redeem implements Commands { - @Override - public boolean equals(Object obj) { return obj instanceof Redeem; } - } - - class Issue implements Commands { - @Override - public boolean equals(Object obj) { return obj instanceof Issue; } - } - } - -As you can see, we used ``verifyClause`` function with ``Clauses.Group()`` in place of our previous verification logic. -It's an entry point to running clause logic. ``verifyClause`` takes the transaction, a clause (usually a composite one) -to verify, and all of the commands the clause is expected to handle. This list of commands is important because -``verifyClause`` checks that none of the commands are left unprocessed at the end, raising an error if they are. - -Simple Clauses --------------- - -Let's move to constructing contract logic in terms of clauses. The commercial paper contract has three commands and -three corresponding behaviours: ``Issue``, ``Move`` and ``Redeem``. Each of them has a specific set of requirements that must be satisfied - -perfect material for defining clauses. For brevity, we will only show the ``Move`` clause. The rest is constructed in similar manner, -and is included in the ``CommercialPaper.kt`` code. - -.. container:: codeset - - .. sourcecode:: kotlin - - interface Clauses { - class Move: Clause>() { - override val requiredCommands: Set> - get() = setOf(Commands.Move::class.java) - - override fun verify(tx: LedgerTransaction, - inputs: List, - outputs: List, - commands: List>, - groupingKey: Issued?): Set { - val command = commands.requireSingleCommand() - val input = inputs.single() - requireThat { - "the transaction is signed by the owner of the CP" using (input.owner.owningKey in command.signers) - "the state is propagated" using (outputs.size == 1) - // Don't need to check anything else, as if outputs.size == 1 then the output is equal to - // the input ignoring the owner field due to the grouping. - } - return setOf(command.value) - } - } - ... - - .. sourcecode:: java - - public interface Clauses { - class Move extends Clause { - @NotNull - @Override - public Set> getRequiredCommands() { - return Collections.singleton(Commands.Move.class); - } - - @NotNull - @Override - public Set verify(@NotNull LedgerTransaction tx, - @NotNull List inputs, - @NotNull List outputs, - @NotNull List> commands, - @NotNull State groupingKey) { - CommandWithParties cmd = requireSingleCommand(tx.getCommands(), Commands.Move.class); - // There should be only a single input due to aggregation above - State input = single(inputs); - - if (!cmd.getSigners().contains(input.getOwner().getOwningKey())) - throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP"); - - // Check the output CP state is the same as the input state, ignoring the owner field. - if (outputs.size() != 1) { - throw new IllegalStateException("the state is propagated"); - } - // Don't need to check anything else, as if outputs.size == 1 then the output is equal to - // the input ignoring the owner field due to the grouping. - return Collections.singleton(cmd.getValue()); - } - } - ... - -We took part of the code for ``Command.Move`` verification from the previous tutorial and put it into the verify function -of ``Move`` class. Notice that this class must extend the ``Clause`` abstract class, which defines -the ``verify`` function and the ``requiredCommands`` property used to determine the conditions under which a clause -is triggered. In the above example, this means that the clause will run its verification logic when ``Commands.Move`` is present in a transaction. - -.. note:: Notice that commands refer to all input and output states in a transaction. For a clause to be executed, the transaction has - to include all commands from the ``requiredCommands`` set. - -A few important changes: - -- The ``verify`` function returns the set of commands which it has processed. Normally this set is identical to the - ``requiredCommands`` used to trigger the clause. However, in some cases, the clause may process further optional commands - which it needs to report that it has handled. - -- Verification takes new parameters. Usually inputs and outputs are some subset of the original transaction entries - passed to the clause by outer composite or grouping clause. ``groupingKey`` is a key used to group original states. - -As a simple example, imagine the following input states: - -1. 1000 GBP issued by Bank of England -2. 500 GBP issued by Bank of England -3. 1000 GBP issued by Bank of Scotland - -We will group states by Issuer, meaning that we have inputs 1 and 2 in one group, and input 3 in another group. The grouping keys are -'GBP issued by Bank of England' and 'GBP issued by Bank of Scotland'. - -How are the states grouped and passed in this form to the ``Move`` clause? Answering that question leads us to the concept of -``GroupClauseVerifier``. - -Group clause ------------- - -We may have a transaction with similar but unrelated state evolutions which need to be validated independently. It -makes sense to check the ``Move`` command on groups of related inputs and outputs (see example above). Thus, we need to collect -relevant states together. -For this, we extend the standard ``GroupClauseVerifier`` and specify how to group input/output states, as well as the top-level -clause to run on each group. In our example, the top level is a composite clause - ``AnyCompostion`` - that delegates verification to -its subclauses (wrapped move, issue, redeem). "Any" in this case means that it will take 0 or more clauses that match the transaction commands. - -.. container:: codeset - - .. sourcecode:: kotlin - - class Group : GroupClauseVerifier>( - AnyOf( - Redeem(), - Move(), - Issue())) { - override fun groupStates(tx: LedgerTransaction): List>> - = tx.groupStates> { it.token } - } - - .. sourcecode:: java - - class Group extends GroupClauseVerifier { - public Group() { - super(new AnyOf<>( - new Clauses.Redeem(), - new Clauses.Move(), - new Clauses.Issue() - )); - } - - @NotNull - @Override - public List> groupStates(@NotNull LedgerTransaction tx) { - return tx.groupStates(State.class, State::withoutOwner); - } - } - -For the ``CommercialPaper`` contract, ``Group`` is the main clause for the contract, and is passed directly into -``verifyClause`` (see the example code at the top of this tutorial). We also used ``groupStates`` function here - it -may be worth reminding yourself how it works here: :ref:`state_ref`. - -Summary -------- - -In summary, the top-level contract ``CommercialPaper`` specifies a single grouping clause of type -``CommercialPaper.Clauses.Group``, which in turn specifies ``GroupClause`` implementations for each type of command -(``Redeem``, ``Move`` and ``Issue``). This reflects the verification flow: in order to verify ``CommercialPaper``, -we first group states, then we check which commands are specified, and finally we run command-specific verification logic accordingly. - -.. image:: resources/commPaperExecution.png - -Debugging ---------- - -Debugging clauses which have been composed together can be complicated due to the difficulty in knowing which clauses -have been matched, whether specific clauses failed to match or passed verification, etc. There is "trace" level -logging code in the clause verifier which evaluates which clauses will be matched and logs them, before actually -performing the validation. To enable this, ensure trace level logging is enabled on the ``Clause`` interface. diff --git a/docs/source/tutorial-contract.rst b/docs/source/tutorial-contract.rst index ffefcfb2fa..2aca2177f7 100644 --- a/docs/source/tutorial-contract.rst +++ b/docs/source/tutorial-contract.rst @@ -47,8 +47,7 @@ Starting the commercial paper class A smart contract is a class that implements the ``Contract`` interface. This can be either implemented directly, as done here, or by subclassing an abstract contract such as ``OnLedgerAsset``. The heart of any contract in Corda is the ``verify()`` function, which determined whether any given transaction is valid. This example shows how to write a -``verify()`` function from scratch. A later tutorial will introduce "clauses", which are reusable chunks of verification -logic, but first it's worth understanding how a contract is built without them. +``verify()`` function from scratch. You can see the full Kotlin version of this contract in the code as ``CommercialPaperLegacy``. The code in this tutorial is available in both Kotlin and Java. You can quickly switch between them to get a feeling for how @@ -816,12 +815,3 @@ the all future cash states stemming from this one. We will also consider marking states that are capable of being encumbrances as such. This will prevent states being used as encumbrances inadvertently. For example, the time-lock above would be usable as an encumbrance, but it makes no sense to be able to encumber a cash state with another one. - -Clauses -------- - -It is typical for slightly different contracts to have lots of common logic that can be shared. For example, the -concept of being issued, being exited and being upgraded are all usually required in any contract. Corda calls these -frequently needed chunks of logic "clauses", and they can simplify development considerably. - -Clauses and how to use them are addressed in the next tutorial, ":doc:`tutorial-contract-clauses`". diff --git a/docs/source/tutorials-index.rst b/docs/source/tutorials-index.rst index faaa498335..f9ffad2dd3 100644 --- a/docs/source/tutorials-index.rst +++ b/docs/source/tutorials-index.rst @@ -7,7 +7,6 @@ Tutorials hello-world-index tut-two-party-index tutorial-contract - tutorial-contract-clauses tutorial-test-dsl contract-upgrade tutorial-integration-testing From 22be9fd6dfe947c24597a09f0b4ce6234b2f8253 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Thu, 21 Sep 2017 18:18:37 +0100 Subject: [PATCH 036/230] CORDA-579: Move X509EdDSAEngine into net.corda.core.internal package (#1563) * Add reflection based X509EdDSAEngine * Rewrite X509EdDSAEngine to use public API rather than the direct equivalent functions * Add unit tests for X509EdDSAEngine * Remove unused imports * Add unit tests for X509Key verification * Add explicit x509 construct from eddsa key This allows testing of conversion engine * Review Comments --- .idea/compiler.xml | 1 + .../kotlin/net/corda/core/crypto/Crypto.kt | 1 + .../core/internal}/X509EdDSAEngine.kt | 37 +++--- .../core/internal/X509EdDSAEngineTest.kt | 117 ++++++++++++++++++ 4 files changed, 139 insertions(+), 17 deletions(-) rename core/src/main/kotlin/net/{i2p/crypto/eddsa => corda/core/internal}/X509EdDSAEngine.kt (67%) create mode 100644 core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt diff --git a/.idea/compiler.xml b/.idea/compiler.xml index f455e61871..f0b65c5a84 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -93,6 +93,7 @@ + diff --git a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt index ab6ea15722..605b95466c 100644 --- a/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt +++ b/core/src/main/kotlin/net/corda/core/crypto/Crypto.kt @@ -1,5 +1,6 @@ package net.corda.core.crypto +import net.corda.core.internal.X509EdDSAEngine import net.corda.core.serialization.serialize import net.i2p.crypto.eddsa.* import net.i2p.crypto.eddsa.math.GroupElement diff --git a/core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt b/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt similarity index 67% rename from core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt rename to core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt index 9ce017a484..0bebc73130 100644 --- a/core/src/main/kotlin/net/i2p/crypto/eddsa/X509EdDSAEngine.kt +++ b/core/src/main/kotlin/net/corda/core/internal/X509EdDSAEngine.kt @@ -1,5 +1,7 @@ -package net.i2p.crypto.eddsa +package net.corda.core.internal +import net.i2p.crypto.eddsa.EdDSAEngine +import net.i2p.crypto.eddsa.EdDSAPublicKey import java.security.* import java.security.spec.AlgorithmParameterSpec import java.security.spec.X509EncodedKeySpec @@ -16,33 +18,34 @@ class X509EdDSAEngine : Signature { constructor() : super(EdDSAEngine.SIGNATURE_ALGORITHM) { engine = EdDSAEngine() } + constructor(digest: MessageDigest) : super(EdDSAEngine.SIGNATURE_ALGORITHM) { engine = EdDSAEngine(digest) } - override fun engineInitSign(privateKey: PrivateKey) = engine.engineInitSign(privateKey) + override fun engineInitSign(privateKey: PrivateKey) = engine.initSign(privateKey) + override fun engineInitSign(privateKey: PrivateKey, random: SecureRandom) = engine.initSign(privateKey, random) + override fun engineInitVerify(publicKey: PublicKey) { val parsedKey = if (publicKey is sun.security.x509.X509Key) { EdDSAPublicKey(X509EncodedKeySpec(publicKey.encoded)) } else { publicKey } - engine.engineInitVerify(parsedKey) + + engine.initVerify(parsedKey) } - override fun engineVerify(sigBytes: ByteArray): Boolean = engine.engineVerify(sigBytes) - override fun engineSign(): ByteArray = engine.engineSign() - override fun engineUpdate(b: Byte) = engine.engineUpdate(b) - override fun engineUpdate(b: ByteArray, off: Int, len: Int) = engine.engineUpdate(b, off, len) - override fun engineGetParameters(): AlgorithmParameters { - val method = engine.javaClass.getMethod("engineGetParameters") - return method.invoke(engine) as AlgorithmParameters - } + override fun engineSign(): ByteArray = engine.sign() + override fun engineVerify(sigBytes: ByteArray): Boolean = engine.verify(sigBytes) + + override fun engineUpdate(b: Byte) = engine.update(b) + override fun engineUpdate(b: ByteArray, off: Int, len: Int) = engine.update(b, off, len) + + override fun engineGetParameters(): AlgorithmParameters = engine.parameters override fun engineSetParameter(params: AlgorithmParameterSpec) = engine.setParameter(params) - override fun engineGetParameter(param: String): Any = engine.engineGetParameter(param) - override fun engineSetParameter(param: String, value: Any?) = engine.engineSetParameter(param, value) - override fun engineInitSign(privateKey: PrivateKey, random: SecureRandom) { - val method = engine.javaClass.getMethod("engineInitSign", PrivateKey::class.java, SecureRandom::class.java) - method.invoke(engine, privateKey, random) - } + @Suppress("DEPRECATION") + override fun engineGetParameter(param: String): Any = engine.getParameter(param) + @Suppress("DEPRECATION") + override fun engineSetParameter(param: String, value: Any?) = engine.setParameter(param, value) } diff --git a/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt b/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt new file mode 100644 index 0000000000..3f79a6ce36 --- /dev/null +++ b/core/src/test/kotlin/net/corda/core/internal/X509EdDSAEngineTest.kt @@ -0,0 +1,117 @@ +package net.corda.core.internal + +import net.corda.core.crypto.Crypto +import net.i2p.crypto.eddsa.EdDSAEngine +import net.i2p.crypto.eddsa.EdDSAPublicKey +import org.junit.Test +import sun.security.util.BitArray +import sun.security.util.ObjectIdentifier +import sun.security.x509.AlgorithmId +import sun.security.x509.X509Key +import java.math.BigInteger +import java.security.InvalidKeyException +import java.util.* +import kotlin.test.assertFailsWith +import kotlin.test.assertTrue + +class TestX509Key(algorithmId: AlgorithmId, key: BitArray) : X509Key() { + init { + this.algid = algorithmId + this.setKey(key) + this.encode() + } +} + +class X509EdDSAEngineTest { + companion object { + private const val SEED = 20170920L + private const val TEST_DATA_SIZE = 2000 + + // offset into an EdDSA header indicating where the key header and actual key start + // in the underlying byte array + private const val keyHeaderStart = 9 + private const val keyStart = 12 + + private fun toX509Key(publicKey: EdDSAPublicKey): X509Key { + val internals = publicKey.encoded + + // key size in the header includes the count unused bits at the end of the key + // [keyHeaderStart + 2] but NOT the key header ID [keyHeaderStart] so the + // actual length of the key blob is size - 1 + val keySize = (internals[keyHeaderStart + 1].toInt()) - 1 + + val key = ByteArray(keySize) + System.arraycopy(internals, keyStart, key, 0, keySize) + + // 1.3.101.102 is the EdDSA OID + return TestX509Key(AlgorithmId(ObjectIdentifier("1.3.101.112")), BitArray(keySize * 8, key)) + } + } + + /** + * Put the X509EdDSA engine through basic tests to verify that the functions are hooked up correctly. + */ + @Test + fun `sign and verify`() { + val engine = X509EdDSAEngine() + val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED)) + val publicKey = keyPair.public as EdDSAPublicKey + val randomBytes = ByteArray(TEST_DATA_SIZE) + Random(SEED).nextBytes(randomBytes) + engine.initSign(keyPair.private) + engine.update(randomBytes[0]) + engine.update(randomBytes, 1, randomBytes.size - 1) + + // Now verify the signature + val signature = engine.sign() + + engine.initVerify(publicKey) + engine.update(randomBytes) + assertTrue { engine.verify(signature) } + } + + /** + * Verify that signing with an X509Key wrapped EdDSA key works. + */ + @Test + fun `sign and verify with X509Key`() { + val engine = X509EdDSAEngine() + val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED + 1)) + val publicKey = toX509Key(keyPair.public as EdDSAPublicKey) + val randomBytes = ByteArray(TEST_DATA_SIZE) + Random(SEED + 1).nextBytes(randomBytes) + engine.initSign(keyPair.private) + engine.update(randomBytes[0]) + engine.update(randomBytes, 1, randomBytes.size - 1) + + // Now verify the signature + val signature = engine.sign() + + engine.initVerify(publicKey) + engine.update(randomBytes) + assertTrue { engine.verify(signature) } + } + + /** + * Verify that signing with an X509Key wrapped EdDSA key fails when using the underlying EdDSAEngine. + */ + @Test + fun `sign and verify with X509Key and old engine fails`() { + val engine = EdDSAEngine() + val keyPair = Crypto.deriveKeyPairFromEntropy(Crypto.EDDSA_ED25519_SHA512, BigInteger.valueOf(SEED + 1)) + val publicKey = toX509Key(keyPair.public as EdDSAPublicKey) + val randomBytes = ByteArray(TEST_DATA_SIZE) + Random(SEED + 1).nextBytes(randomBytes) + engine.initSign(keyPair.private) + engine.update(randomBytes[0]) + engine.update(randomBytes, 1, randomBytes.size - 1) + + // Now verify the signature + val signature = engine.sign() + assertFailsWith { + engine.initVerify(publicKey) + engine.update(randomBytes) + engine.verify(signature) + } + } +} \ No newline at end of file From a11577840c232f7a9695895a4f85c9348dfd8cb6 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Fri, 22 Sep 2017 10:15:03 +0100 Subject: [PATCH 037/230] Moved ServiceInfo and ServiceType into internal package (#1599) --- .../kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt | 2 +- .../net/corda/client/jfx/model/NetworkIdentityModel.kt | 2 +- .../java/net/corda/client/rpc/CordaRPCJavaClientTest.java | 2 +- .../kotlin/net/corda/client/rpc/CordaRPCClientTest.kt | 2 +- core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt | 2 +- .../corda/core/serialization/AttachmentSerializationTest.kt | 3 +-- .../kotlin/net/corda/docs/IntegrationTestingTutorial.kt | 2 +- .../src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt | 2 +- .../src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt | 2 +- .../kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt | 2 +- .../net/corda/docs/WorkflowTransactionBuildTutorialTest.kt | 2 +- .../kotlin/net/corda/nodeapi/{ => internal}/ServiceInfo.kt | 2 +- .../kotlin/net/corda/nodeapi/{ => internal}/ServiceType.kt | 2 +- node/src/integration-test/kotlin/net/corda/node/BootTests.kt | 4 ++-- .../kotlin/net/corda/node/NodePerformanceTests.kt | 2 +- .../kotlin/net/corda/node/services/BFTNotaryServiceTests.kt | 2 +- .../kotlin/net/corda/services/messaging/P2PMessagingTest.kt | 2 +- .../kotlin/net/corda/test/node/NodeStatePersistenceTests.kt | 2 +- node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt | 5 ++--- node/src/main/kotlin/net/corda/node/internal/Node.kt | 2 +- node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt | 2 +- .../net/corda/node/services/config/NodeConfiguration.kt | 2 +- .../net/corda/node/services/network/NetworkMapService.kt | 2 +- .../corda/node/services/transactions/SimpleNotaryService.kt | 2 +- .../node/services/transactions/ValidatingNotaryService.kt | 2 +- node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt | 2 +- .../net/corda/node/messaging/InMemoryMessagingTests.kt | 2 +- .../net/corda/node/messaging/TwoPartyTradeFlowTests.kt | 2 +- .../test/kotlin/net/corda/node/services/NotaryChangeTests.kt | 2 +- .../net/corda/node/services/events/ScheduledFlowTests.kt | 2 +- .../node/services/network/AbstractNetworkMapServiceTest.kt | 2 +- .../net/corda/node/services/network/NetworkMapCacheTest.kt | 2 +- .../node/services/network/PersistentNetworkMapServiceTest.kt | 2 +- .../corda/node/services/statemachine/FlowFrameworkTests.kt | 2 +- .../corda/node/services/transactions/NotaryServiceTests.kt | 2 +- .../services/transactions/ValidatingNotaryServiceTests.kt | 2 +- .../kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt | 2 +- .../src/main/kotlin/net/corda/attachmentdemo/Main.kt | 2 +- .../kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt | 2 +- .../kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt | 2 +- .../src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt | 2 +- .../src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt | 2 +- samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt | 2 +- .../main/kotlin/net/corda/netmap/simulation/Simulation.kt | 4 ++-- .../main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt | 2 +- .../main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt | 2 +- .../main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt | 2 +- .../kotlin/net/corda/vega/SimmValuationTest.kt | 2 +- .../src/test/kotlin/net/corda/vega/Main.kt | 2 +- .../kotlin/net/corda/traderdemo/TraderDemoTest.kt | 2 +- .../trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt | 2 +- .../kotlin/net/corda/testing/driver/DriverTests.kt | 2 +- .../src/main/kotlin/net/corda/testing/DriverConstants.kt | 2 +- .../src/main/kotlin/net/corda/testing/driver/Driver.kt | 4 ++-- .../net/corda/testing/internal/demorun/CordformUtils.kt | 2 +- .../src/main/kotlin/net/corda/testing/node/MockNode.kt | 4 ++-- .../src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt | 4 ++-- .../main/kotlin/net/corda/demobench/model/InstallFactory.kt | 4 ++-- .../main/kotlin/net/corda/demobench/model/NodeController.kt | 4 ++-- .../src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt | 4 ++-- .../src/main/kotlin/net/corda/explorer/views/Network.kt | 2 +- .../kotlin/net/corda/verifier/VerifierTests.kt | 2 +- 62 files changed, 71 insertions(+), 73 deletions(-) rename node-api/src/main/kotlin/net/corda/nodeapi/{ => internal}/ServiceInfo.kt (96%) rename node-api/src/main/kotlin/net/corda/nodeapi/{ => internal}/ServiceType.kt (98%) diff --git a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt index 519b668cc6..bf5140fc36 100644 --- a/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt +++ b/client/jfx/src/integration-test/kotlin/net/corda/client/jfx/NodeMonitorModelTest.kt @@ -27,7 +27,7 @@ import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.* diff --git a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt index 7f5e23babf..15cf636622 100644 --- a/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt +++ b/client/jfx/src/main/kotlin/net/corda/client/jfx/model/NetworkIdentityModel.kt @@ -12,7 +12,7 @@ import net.corda.core.identity.AnonymousParty import net.corda.core.identity.Party import net.corda.core.node.NodeInfo import net.corda.core.node.services.NetworkMapCache.MapChange -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceType import java.security.PublicKey class NetworkIdentityModel { diff --git a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java index 29a86c00aa..3842299920 100644 --- a/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java +++ b/client/rpc/src/integration-test/java/net/corda/client/rpc/CordaRPCJavaClientTest.java @@ -13,7 +13,7 @@ import net.corda.finance.schemas.*; import net.corda.node.internal.Node; import net.corda.node.internal.StartedNode; import net.corda.node.services.transactions.ValidatingNotaryService; -import net.corda.nodeapi.ServiceInfo; +import net.corda.nodeapi.internal.ServiceInfo; import net.corda.nodeapi.User; import net.corda.testing.CoreTestUtils; import net.corda.testing.node.NodeBasedTest; diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt index 03401224c2..96322bf7b8 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/CordaRPCClientTest.kt @@ -19,7 +19,7 @@ import net.corda.finance.schemas.CashSchemaV1 import net.corda.node.internal.Node import net.corda.node.internal.StartedNode import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE diff --git a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt index 735798118c..5a61e01605 100644 --- a/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt +++ b/core/src/test/kotlin/net/corda/core/flows/AttachmentTests.kt @@ -10,7 +10,7 @@ import net.corda.core.internal.FetchDataFlow import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.NodeAttachmentService diff --git a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt index 0dc98505dc..5692f69722 100644 --- a/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt +++ b/core/src/test/kotlin/net/corda/core/serialization/AttachmentSerializationTest.kt @@ -7,7 +7,6 @@ import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowSession import net.corda.core.flows.InitiatingFlow import net.corda.core.flows.TestDataVendingFlow -import net.corda.core.identity.Party import net.corda.core.internal.FetchAttachmentsFlow import net.corda.core.internal.FetchDataFlow import net.corda.core.messaging.SingleMessageRecipient @@ -15,7 +14,7 @@ import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.unwrap import net.corda.node.internal.InitiatedFlowFactory import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.NodeAttachmentService diff --git a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt index a5cbf809dc..0a107b6c12 100644 --- a/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt +++ b/docs/source/example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt @@ -11,7 +11,7 @@ import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.* diff --git a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt index 7812a71bdc..b2ffa4b3f2 100644 --- a/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt +++ b/docs/source/example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt @@ -16,7 +16,7 @@ import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.ALICE diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt index 182248414c..19feeb4737 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/CustomVaultQueryTest.kt @@ -9,7 +9,7 @@ import net.corda.finance.contracts.getCashBalances import net.corda.finance.flows.CashIssueFlow import net.corda.node.internal.StartedNode import net.corda.finance.schemas.CashSchemaV1 -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.testing.DUMMY_NOTARY diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt index c3b56f34a1..7b04baf0d0 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/FxTransactionBuildTutorialTest.kt @@ -11,7 +11,7 @@ import net.corda.finance.schemas.CashSchemaV1 import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity diff --git a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt index 85cb11b422..48c3a0b0c8 100644 --- a/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt +++ b/docs/source/example-code/src/test/kotlin/net/corda/docs/WorkflowTransactionBuildTutorialTest.kt @@ -11,7 +11,7 @@ import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.ValidatingNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_NOTARY_KEY import net.corda.testing.chooseIdentity diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceInfo.kt similarity index 96% rename from node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt rename to node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceInfo.kt index c77e2cbb17..25e3734165 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/ServiceInfo.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceInfo.kt @@ -1,4 +1,4 @@ -package net.corda.nodeapi +package net.corda.nodeapi.internal import net.corda.core.identity.CordaX500Name import net.corda.core.serialization.CordaSerializable diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceType.kt similarity index 98% rename from node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt rename to node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceType.kt index 05748eb564..65cdf86820 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/ServiceType.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/ServiceType.kt @@ -1,4 +1,4 @@ -package net.corda.nodeapi +package net.corda.nodeapi.internal import net.corda.core.serialization.CordaSerializable diff --git a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt index 846b21d0b2..c61ad1cca9 100644 --- a/node/src/integration-test/kotlin/net/corda/node/BootTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/BootTests.kt @@ -9,8 +9,8 @@ import net.corda.core.utilities.getOrThrow import net.corda.testing.ALICE import net.corda.node.internal.NodeStartup import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.nodeapi.User import net.corda.testing.driver.ListenProcessDeathException import net.corda.testing.driver.NetworkMapStartStrategy diff --git a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt index 9aed7cf1c9..e2d9648556 100644 --- a/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/NodePerformanceTests.kt @@ -12,7 +12,7 @@ import net.corda.finance.DOLLARS import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.chooseIdentity diff --git a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt index 693a9d83fc..458862123d 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/BFTNotaryServiceTests.kt @@ -22,7 +22,7 @@ import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.minClusterSize import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.utilities.ServiceIdentityGenerator -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyContract diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index 23fe7caf9b..cfe5d04854 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -19,7 +19,7 @@ import net.corda.node.services.messaging.* import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.services.transactions.SimpleNotaryService import net.corda.node.utilities.ServiceIdentityGenerator -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.* import net.corda.testing.node.NodeBasedTest import org.assertj.core.api.Assertions.assertThat diff --git a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt index 7073632133..45e3975c43 100644 --- a/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/test/node/NodeStatePersistenceTests.kt @@ -19,7 +19,7 @@ import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.getOrThrow import net.corda.node.services.FlowPermissions import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.nodeapi.User import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index 23b72fb693..d7a37a1602 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -7,7 +7,6 @@ import com.google.common.util.concurrent.MoreExecutors import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesHandler import net.corda.core.concurrent.CordaFuture -import net.corda.core.crypto.* import net.corda.core.flows.* import net.corda.core.flows.ContractUpgradeFlow.Acceptor import net.corda.core.identity.CordaX500Name @@ -67,8 +66,8 @@ import net.corda.node.services.vault.NodeVaultService import net.corda.node.services.vault.VaultSoftLockManager import net.corda.node.utilities.* import net.corda.node.utilities.AddOrRemove.ADD -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.nodeapi.internal.serialization.DefaultWhitelist import org.apache.activemq.artemis.utils.ReusableLatch import org.slf4j.Logger diff --git a/node/src/main/kotlin/net/corda/node/internal/Node.kt b/node/src/main/kotlin/net/corda/node/internal/Node.kt index 957e8150f0..bc4dcb386f 100644 --- a/node/src/main/kotlin/net/corda/node/internal/Node.kt +++ b/node/src/main/kotlin/net/corda/node/internal/Node.kt @@ -18,7 +18,7 @@ import net.corda.node.serialization.KryoServerSerializationScheme import net.corda.node.serialization.NodeClock import net.corda.node.services.RPCUserService import net.corda.node.services.RPCUserServiceImpl -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.messaging.ArtemisMessagingServer import net.corda.node.services.messaging.ArtemisMessagingServer.Companion.ipDetectRequestProperty diff --git a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt index dfd3572333..6fb990d27e 100644 --- a/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt +++ b/node/src/main/kotlin/net/corda/node/internal/NodeStartup.kt @@ -7,7 +7,7 @@ import net.corda.core.internal.* import net.corda.core.internal.concurrent.thenMatch import net.corda.core.utilities.loggerFor import net.corda.node.* -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.transactions.bftSMaRtSerialFilter import net.corda.node.shell.InteractiveShell diff --git a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt index 30f87dc06b..d078c1df48 100644 --- a/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt +++ b/node/src/main/kotlin/net/corda/node/services/config/NodeConfiguration.kt @@ -3,7 +3,7 @@ package net.corda.node.services.config import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort import net.corda.node.internal.NetworkMapInfo -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.messaging.CertificateChainCheckPolicy import net.corda.node.services.network.NetworkMapService import net.corda.nodeapi.User diff --git a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt index f69b3d6736..81448e1469 100644 --- a/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/net/corda/node/services/network/NetworkMapService.kt @@ -18,7 +18,7 @@ import net.corda.core.serialization.deserialize import net.corda.core.serialization.serialize import net.corda.core.utilities.debug import net.corda.core.utilities.loggerFor -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.api.AbstractNodeService import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.messaging.MessageHandlerRegistration diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt index f27d4e7478..e62bcecb85 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/SimpleNotaryService.kt @@ -4,7 +4,7 @@ import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.api.ServiceHubInternal import java.security.PublicKey diff --git a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt index e3f7289393..c13b9186f1 100644 --- a/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/net/corda/node/services/transactions/ValidatingNotaryService.kt @@ -4,7 +4,7 @@ import net.corda.core.flows.FlowSession import net.corda.core.flows.NotaryFlow import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TrustedAuthorityNotaryService -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.api.ServiceHubInternal import java.security.PublicKey diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index af82b87cd3..0f2a33aec5 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -28,7 +28,7 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT import net.corda.node.services.messaging.RpcContext import net.corda.node.services.network.NetworkMapService import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.PermissionException import net.corda.nodeapi.User diff --git a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt index d356afb76f..95c26319c2 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/InMemoryMessagingTests.kt @@ -1,6 +1,6 @@ package net.corda.node.messaging -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.messaging.Message import net.corda.node.services.messaging.TopicStringValidator import net.corda.node.services.messaging.createMessage diff --git a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt index 74d0d43886..4d841f73b4 100644 --- a/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/messaging/TwoPartyTradeFlowTests.kt @@ -33,7 +33,7 @@ import net.corda.finance.contracts.asset.* import net.corda.finance.flows.TwoPartyTradeFlow.Buyer import net.corda.finance.flows.TwoPartyTradeFlow.Seller import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.api.WritableTransactionStorage import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.persistence.DBTransactionStorage diff --git a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt index f577a15a01..cc6be02581 100644 --- a/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/NotaryChangeTests.kt @@ -13,7 +13,7 @@ import net.corda.core.utilities.seconds import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.chooseIdentity diff --git a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt index 73b9058561..e39766768a 100644 --- a/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/events/ScheduledFlowTests.kt @@ -18,7 +18,7 @@ import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager import net.corda.node.services.transactions.ValidatingNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity import net.corda.testing.contracts.DUMMY_PROGRAM_ID diff --git a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt index 355e54c104..7b133c965f 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/AbstractNetworkMapServiceTest.kt @@ -7,7 +7,7 @@ import net.corda.core.node.NodeInfo import net.corda.core.serialization.deserialize import net.corda.core.utilities.getOrThrow import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.send diff --git a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt index d7e65d8162..1297d979cb 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/NetworkMapCacheTest.kt @@ -2,7 +2,7 @@ package net.corda.node.services.network import net.corda.core.node.services.NetworkMapCache import net.corda.core.utilities.getOrThrow -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.ALICE import net.corda.testing.BOB import net.corda.testing.chooseIdentity diff --git a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt index ecb930a28f..2f6966097a 100644 --- a/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/net/corda/node/services/network/PersistentNetworkMapServiceTest.kt @@ -1,7 +1,7 @@ package net.corda.node.services.network import net.corda.core.messaging.SingleMessageRecipient -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.api.ServiceHubInternal import net.corda.node.services.config.NodeConfiguration import net.corda.testing.node.MockNetwork diff --git a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt index 64d6af905e..3ceb50a2e7 100644 --- a/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/statemachine/FlowFrameworkTests.kt @@ -34,7 +34,7 @@ import net.corda.node.internal.StartedNode import net.corda.node.services.network.NetworkMapService import net.corda.node.services.persistence.checkpoints import net.corda.node.services.transactions.ValidatingNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.* import net.corda.testing.contracts.DUMMY_PROGRAM_ID import net.corda.testing.contracts.DummyState diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt index 6b4fdb6899..9c910d973e 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/NotaryServiceTests.kt @@ -13,7 +13,7 @@ import net.corda.core.transactions.TransactionBuilder import net.corda.core.utilities.getOrThrow import net.corda.core.utilities.seconds import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.network.NetworkMapService import net.corda.testing.DUMMY_NOTARY import net.corda.testing.chooseIdentity diff --git a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt index 2bdd835486..407914ee08 100644 --- a/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt +++ b/node/src/test/kotlin/net/corda/node/services/transactions/ValidatingNotaryServiceTests.kt @@ -13,7 +13,7 @@ import net.corda.core.transactions.SignedTransaction import net.corda.core.utilities.getOrThrow import net.corda.core.transactions.TransactionBuilder import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.issueInvalidState import net.corda.node.services.network.NetworkMapService import net.corda.testing.DUMMY_NOTARY diff --git a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt index fc56ffee65..7e825f5ea7 100644 --- a/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt +++ b/samples/attachment-demo/src/integration-test/kotlin/net/corda/attachmentdemo/AttachmentDemoTest.kt @@ -2,7 +2,7 @@ package net.corda.attachmentdemo import net.corda.core.utilities.getOrThrow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.DUMMY_BANK_A diff --git a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt index 9cd19574bd..b331dbacc7 100644 --- a/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt +++ b/samples/attachment-demo/src/main/kotlin/net/corda/attachmentdemo/Main.kt @@ -1,7 +1,7 @@ package net.corda.attachmentdemo import net.corda.core.internal.div -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_NOTARY diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt index a1781fd1c6..22e33c41b9 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaHttpAPITest.kt @@ -3,7 +3,7 @@ package net.corda.bank import net.corda.bank.api.BankOfCordaClientApi import net.corda.bank.api.BankOfCordaWebApi.IssueRequestParams import net.corda.core.utilities.getOrThrow -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.BOC import net.corda.testing.driver.driver diff --git a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt index fdd53846ff..33a36ec75f 100644 --- a/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt +++ b/samples/bank-of-corda-demo/src/integration-test/kotlin/net/corda/bank/BankOfCordaRPCClientTest.kt @@ -8,7 +8,7 @@ import net.corda.finance.DOLLARS import net.corda.finance.contracts.asset.Cash import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.* diff --git a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt index 4fa643ac76..e1b75e3f1b 100644 --- a/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt +++ b/samples/bank-of-corda-demo/src/main/kotlin/net/corda/bank/BankOfCordaDriver.kt @@ -9,7 +9,7 @@ import net.corda.finance.flows.CashExitFlow import net.corda.finance.flows.CashIssueAndPaymentFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.BOC diff --git a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt index 51e2fca205..188eb21894 100644 --- a/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt +++ b/samples/irs-demo/src/integration-test/kotlin/net/corda/irs/IRSDemoTest.kt @@ -20,7 +20,7 @@ import net.corda.core.utilities.seconds import net.corda.finance.plugin.registerFinanceJSONMappers import net.corda.irs.contract.InterestRateSwap import net.corda.irs.utilities.uploadFile -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User diff --git a/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt b/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt index e16314bff9..6cd3425e58 100644 --- a/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt +++ b/samples/irs-demo/src/test/kotlin/net/corda/irs/Main.kt @@ -1,7 +1,7 @@ package net.corda.irs import net.corda.core.utilities.getOrThrow -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B diff --git a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt index ab6ab1d037..6ba3f19e18 100644 --- a/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt +++ b/samples/network-visualiser/src/main/kotlin/net/corda/netmap/simulation/Simulation.kt @@ -9,8 +9,8 @@ import net.corda.core.messaging.SingleMessageRecipient import net.corda.core.utilities.ProgressTracker import net.corda.irs.api.NodeInterestRates import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.network.NetworkMapService import net.corda.node.services.statemachine.StateMachineManager diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt index 5d2230fb76..0a6032ca92 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/BFTNotaryCordform.kt @@ -8,7 +8,7 @@ import net.corda.core.internal.div import net.corda.core.internal.stream import net.corda.core.internal.toTypedArray import net.corda.core.utilities.NetworkHostAndPort -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.BFTNonValidatingNotaryService import net.corda.node.services.transactions.minCorrectReplicas import net.corda.node.utilities.ServiceIdentityGenerator diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt index f2ba787f10..d2aa76c14d 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/RaftNotaryCordform.kt @@ -6,7 +6,7 @@ import net.corda.cordform.CordformNode import net.corda.core.identity.CordaX500Name import net.corda.core.internal.div import net.corda.core.utilities.NetworkHostAndPort -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.RaftValidatingNotaryService import net.corda.node.utilities.ServiceIdentityGenerator import net.corda.testing.ALICE diff --git a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt index 95398b1aae..080d415501 100644 --- a/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt +++ b/samples/notary-demo/src/main/kotlin/net/corda/notarydemo/SingleNotaryCordform.kt @@ -11,7 +11,7 @@ import net.corda.notarydemo.flows.DummyIssueAndMove import net.corda.notarydemo.flows.RPCStartableNotaryFlowClient import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformContext -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.internal.demorun.* fun main(args: Array) = SingleNotaryCordform.runNodes() diff --git a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt index b000d69b65..dec1031348 100644 --- a/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt +++ b/samples/simm-valuation-demo/src/integration-test/kotlin/net/corda/vega/SimmValuationTest.kt @@ -3,7 +3,7 @@ package net.corda.vega import com.opengamma.strata.product.common.BuySell import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.getOrThrow -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B diff --git a/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt b/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt index a017760163..ee855f6ffc 100644 --- a/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt +++ b/samples/simm-valuation-demo/src/test/kotlin/net/corda/vega/Main.kt @@ -1,7 +1,7 @@ package net.corda.vega import net.corda.core.utilities.getOrThrow -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_BANK_B import net.corda.testing.DUMMY_BANK_C diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 329e144b2b..9cc6f89bc7 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -10,7 +10,7 @@ import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CommercialPaperSchemaV1 import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.nodeapi.User import net.corda.testing.* import net.corda.testing.driver.poll diff --git a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt index 1b19fedd9f..5b41ae9ec3 100644 --- a/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt +++ b/samples/trader-demo/src/test/kotlin/net/corda/traderdemo/Main.kt @@ -3,7 +3,7 @@ package net.corda.traderdemo import net.corda.core.internal.div import net.corda.finance.flows.CashIssueFlow import net.corda.node.services.FlowPermissions.Companion.startFlowPermission -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.nodeapi.User import net.corda.testing.BOC diff --git a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt index c7089024a6..43260d5500 100644 --- a/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt +++ b/testing/node-driver/src/integration-test/kotlin/net/corda/testing/driver/DriverTests.kt @@ -9,7 +9,7 @@ import net.corda.testing.DUMMY_BANK_A import net.corda.testing.DUMMY_NOTARY import net.corda.testing.DUMMY_REGULATOR import net.corda.node.internal.NodeStartup -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService import net.corda.testing.ProjectStructure.projectRootDir import org.assertj.core.api.Assertions.assertThat diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt index fc82022656..398cc9262c 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/DriverConstants.kt @@ -5,7 +5,7 @@ package net.corda.testing import net.corda.core.identity.Party import net.corda.core.internal.concurrent.transpose import net.corda.core.messaging.CordaRPCOps -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.ValidatingNotaryService import net.corda.nodeapi.User import net.corda.testing.driver.DriverDSLExposedInterface diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index 6b1484e260..fa9f2503bf 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -23,8 +23,8 @@ import net.corda.core.utilities.* import net.corda.node.internal.Node import net.corda.node.internal.NodeStartup import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.config.* import net.corda.node.services.network.NetworkMapService import net.corda.node.services.transactions.RaftValidatingNotaryService diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt index 7de9b15f40..c7006d02f4 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/internal/demorun/CordformUtils.kt @@ -6,7 +6,7 @@ import net.corda.cordform.CordformDefinition import net.corda.cordform.CordformNode import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.nodeapi.User fun CordformDefinition.node(configure: CordformNode.() -> Unit) { diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt index dfffb71f61..9baeb6d470 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockNode.kt @@ -23,8 +23,8 @@ import net.corda.core.utilities.loggerFor import net.corda.finance.utils.WorldMapLocation import net.corda.node.internal.AbstractNode import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.config.NodeConfiguration import net.corda.node.services.identity.PersistentIdentityService import net.corda.node.services.keys.E2ETestKeyManagementService diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt index 7223814c7a..7cbb549ba8 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/NodeBasedTest.kt @@ -8,8 +8,8 @@ import net.corda.core.internal.div import net.corda.core.utilities.getOrThrow import net.corda.node.internal.Node import net.corda.node.internal.StartedNode -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.node.services.config.ConfigHelper import net.corda.node.services.config.FullNodeConfiguration import net.corda.node.services.config.configOf diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt index d0137bd76b..e2eeb63203 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/InstallFactory.kt @@ -3,8 +3,8 @@ package net.corda.demobench.model import com.typesafe.config.Config import net.corda.core.identity.CordaX500Name import net.corda.core.utilities.NetworkHostAndPort -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import tornadofx.* import java.io.IOException import java.nio.file.Files diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 95d5592c5b..798c3609e1 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -3,8 +3,8 @@ package net.corda.demobench.model import net.corda.core.identity.CordaX500Name import net.corda.demobench.plugin.PluginController import net.corda.demobench.pty.R3Pty -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import tornadofx.* import java.io.IOException import java.lang.management.ManagementFactory diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt index b8b84bd776..31f5b0ff14 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/ExplorerSimulation.kt @@ -22,8 +22,8 @@ import net.corda.finance.flows.CashExitFlow.ExitRequest import net.corda.finance.flows.CashIssueAndPaymentFlow.IssueAndPaymentRequest import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.ServiceInfo -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceInfo +import net.corda.nodeapi.internal.ServiceType import net.corda.nodeapi.User import net.corda.testing.ALICE import net.corda.testing.BOB diff --git a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt index d32fa799e0..cb7f69df1f 100644 --- a/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt +++ b/tools/explorer/src/main/kotlin/net/corda/explorer/views/Network.kt @@ -36,7 +36,7 @@ import net.corda.explorer.model.CordaView import net.corda.finance.utils.CityDatabase import net.corda.finance.utils.ScreenCoordinate import net.corda.finance.utils.WorldMapLocation -import net.corda.nodeapi.ServiceType +import net.corda.nodeapi.internal.ServiceType import tornadofx.* class Network : CordaView() { diff --git a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt index 0c1ec073ca..466b540f6a 100644 --- a/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt +++ b/verifier/src/integration-test/kotlin/net/corda/verifier/VerifierTests.kt @@ -11,7 +11,7 @@ import net.corda.finance.flows.CashIssueFlow import net.corda.finance.flows.CashPaymentFlow import net.corda.node.services.config.VerifierType import net.corda.node.services.transactions.ValidatingNotaryService -import net.corda.nodeapi.ServiceInfo +import net.corda.nodeapi.internal.ServiceInfo import net.corda.testing.ALICE import net.corda.testing.DUMMY_NOTARY import net.corda.testing.driver.NetworkMapStartStrategy From 11be5dd41713dc80003d58b2b8278a99c8a60ee4 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Fri, 22 Sep 2017 10:17:01 +0100 Subject: [PATCH 038/230] Cleaned up ContractUpgradeFlow API (#1591) --- .../corda/core/flows/ContractUpgradeFlow.kt | 116 ++++++------------ .../core/internal/ContractUpgradeUtils.kt | 21 ++++ .../core/flows/ContractUpgradeFlowTest.kt | 17 ++- docs/source/changelog.rst | 2 + .../net/corda/node/internal/AbstractNode.kt | 4 +- .../node/internal/cordapp/CordappLoader.kt | 9 +- .../corda/node/services/CoreFlowHandlers.kt | 29 +++++ .../corda/node/cordapp/CordappLoaderTest.kt | 2 +- .../testing/contracts/DummyContractV2.kt | 4 +- 9 files changed, 107 insertions(+), 97 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/internal/ContractUpgradeUtils.kt diff --git a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt index ec1c6a307c..f5813fdb05 100644 --- a/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt +++ b/core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt @@ -2,9 +2,8 @@ package net.corda.core.flows import co.paralleluniverse.fibers.Suspendable import net.corda.core.contracts.* +import net.corda.core.internal.ContractUpgradeUtils import net.corda.core.transactions.LedgerTransaction -import net.corda.core.transactions.SignedTransaction -import net.corda.core.transactions.TransactionBuilder import java.security.PublicKey /** @@ -17,11 +16,37 @@ import java.security.PublicKey */ object ContractUpgradeFlow { + @JvmStatic + fun verify(tx: LedgerTransaction) { + // Contract Upgrade transaction should have 1 input, 1 output and 1 command. + verify(tx.inputs.single().state, + tx.outputs.single(), + tx.commandsOfType().single()) + } + + @JvmStatic + fun verify(input: TransactionState, output: TransactionState, commandData: Command) { + val command = commandData.value + val participantKeys: Set = input.data.participants.map { it.owningKey }.toSet() + val keysThatSigned: Set = commandData.signers.toSet() + @Suppress("UNCHECKED_CAST") + val upgradedContract = javaClass.classLoader.loadClass(command.upgradedContractClass).newInstance() as UpgradedContract + requireThat { + "The signing keys include all participant keys" using keysThatSigned.containsAll(participantKeys) + "Inputs state reference the legacy contract" using (input.contract == upgradedContract.legacyContract) + "Outputs state reference the upgraded contract" using (output.contract == command.upgradedContractClass) + "Output state must be an upgraded version of the input state" using (output.data == upgradedContract.upgrade(input.data)) + } + } + /** * Authorise a contract state upgrade. - * This will store the upgrade authorisation in persistent store, and will be queried by [ContractUpgradeFlow.Acceptor] during contract upgrade process. - * Invoking this flow indicates the node is willing to upgrade the [StateAndRef] using the [UpgradedContract] class. - * This method will NOT initiate the upgrade process. To start the upgrade process, see [Initiator]. + * + * This will store the upgrade authorisation in persistent store, and will be queried by [ContractUpgradeFlow.Acceptor] + * during contract upgrade process. Invoking this flow indicates the node is willing to upgrade the [StateAndRef] using + * the [UpgradedContract] class. + * + * This flow will NOT initiate the upgrade process. To start the upgrade process, see [Initiate]. */ @StartableByRPC class Authorise( @@ -45,9 +70,7 @@ object ContractUpgradeFlow { * This will remove the upgrade authorisation from persistent store (and prevent any further upgrade) */ @StartableByRPC - class Deauthorise( - val stateRef: StateRef - ) : FlowLogic< Void?>() { + class Deauthorise(val stateRef: StateRef) : FlowLogic() { @Suspendable override fun call(): Void? { serviceHub.contractUpgradeService.removeAuthorisedContractUpgrade(stateRef) @@ -55,33 +78,19 @@ object ContractUpgradeFlow { } } + /** + * This flow begins the contract upgrade process. + */ @InitiatingFlow @StartableByRPC - class Initiator( + class Initiate( originalState: StateAndRef, newContractClass: Class> ) : AbstractStateReplacementFlow.Instigator>>(originalState, newContractClass) { - companion object { - fun assembleBareTx( - stateRef: StateAndRef, - upgradedContractClass: Class>, - privacySalt: PrivacySalt - ): TransactionBuilder { - val contractUpgrade = upgradedContractClass.newInstance() - return TransactionBuilder(stateRef.state.notary) - .withItems( - stateRef, - StateAndContract(contractUpgrade.upgrade(stateRef.state.data), upgradedContractClass.name), - Command(UpgradeCommand(upgradedContractClass.name), stateRef.state.data.participants.map { it.owningKey }), - privacySalt - ) - } - } - @Suspendable override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx { - val baseTx = assembleBareTx(originalState, modification, PrivacySalt()) + val baseTx = ContractUpgradeUtils.assembleBareTx(originalState, modification, PrivacySalt()) val participantKeys = originalState.state.data.participants.map { it.owningKey }.toSet() // TODO: We need a much faster way of finding our key in the transaction val myKey = serviceHub.keyManagementService.filterMyKeys(participantKeys).single() @@ -89,57 +98,4 @@ object ContractUpgradeFlow { return AbstractStateReplacementFlow.UpgradeTx(stx) } } - - @StartableByRPC - @InitiatedBy(ContractUpgradeFlow.Initiator::class) - class Acceptor(otherSide: FlowSession) : AbstractStateReplacementFlow.Acceptor>>(otherSide) { - - companion object { - @JvmStatic - fun verify(tx: LedgerTransaction) { - // Contract Upgrade transaction should have 1 input, 1 output and 1 command. - verify(tx.inputs.single().state, - tx.outputs.single(), - tx.commandsOfType().single()) - } - - @JvmStatic - fun verify(input: TransactionState, output: TransactionState, commandData: Command) { - val command = commandData.value - val participantKeys: Set = input.data.participants.map { it.owningKey }.toSet() - val keysThatSigned: Set = commandData.signers.toSet() - @Suppress("UNCHECKED_CAST") - val upgradedContract = javaClass.classLoader.loadClass(command.upgradedContractClass).newInstance() as UpgradedContract - requireThat { - "The signing keys include all participant keys" using keysThatSigned.containsAll(participantKeys) - "Inputs state reference the legacy contract" using (input.contract == upgradedContract.legacyContract) - "Outputs state reference the upgraded contract" using (output.contract == command.upgradedContractClass) - "Output state must be an upgraded version of the input state" using (output.data == upgradedContract.upgrade(input.data)) - } - } - } - - @Suspendable - @Throws(StateReplacementException::class) - override fun verifyProposal(stx: SignedTransaction, proposal: AbstractStateReplacementFlow.Proposal>>) { - // Retrieve signed transaction from our side, we will apply the upgrade logic to the transaction on our side, and - // verify outputs matches the proposed upgrade. - val ourSTX = serviceHub.validatedTransactions.getTransaction(proposal.stateRef.txhash) - requireNotNull(ourSTX) { "We don't have a copy of the referenced state" } - val oldStateAndRef = ourSTX!!.tx.outRef(proposal.stateRef.index) - val authorisedUpgrade = serviceHub.contractUpgradeService.getAuthorisedContractUpgrade(oldStateAndRef.ref) ?: - throw IllegalStateException("Contract state upgrade is unauthorised. State hash : ${oldStateAndRef.ref}") - val proposedTx = stx.tx - val expectedTx = ContractUpgradeFlow.Initiator.assembleBareTx(oldStateAndRef, proposal.modification, proposedTx.privacySalt).toWireTransaction() - requireThat { - "The instigator is one of the participants" using (initiatingSession.counterparty in oldStateAndRef.state.data.participants) - "The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" using (proposal.modification.name == authorisedUpgrade) - "The proposed tx matches the expected tx for this upgrade" using (proposedTx == expectedTx) - } - ContractUpgradeFlow.Acceptor.verify( - oldStateAndRef.state, - expectedTx.outRef(0).state, - expectedTx.toLedgerTransaction(serviceHub).commandsOfType().single()) - } - } } diff --git a/core/src/main/kotlin/net/corda/core/internal/ContractUpgradeUtils.kt b/core/src/main/kotlin/net/corda/core/internal/ContractUpgradeUtils.kt new file mode 100644 index 0000000000..e2e36294e7 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/internal/ContractUpgradeUtils.kt @@ -0,0 +1,21 @@ +package net.corda.core.internal + +import net.corda.core.contracts.* +import net.corda.core.transactions.TransactionBuilder + +object ContractUpgradeUtils { + fun assembleBareTx( + stateRef: StateAndRef, + upgradedContractClass: Class>, + privacySalt: PrivacySalt + ): TransactionBuilder { + val contractUpgrade = upgradedContractClass.newInstance() + return TransactionBuilder(stateRef.state.notary) + .withItems( + stateRef, + StateAndContract(contractUpgrade.upgrade(stateRef.state.data), upgradedContractClass.name), + Command(UpgradeCommand(upgradedContractClass.name), stateRef.state.data.participants.map { it.owningKey }), + privacySalt + ) + } +} diff --git a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt index edc9dd0df0..f749e6e262 100644 --- a/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt +++ b/core/src/test/kotlin/net/corda/core/flows/ContractUpgradeFlowTest.kt @@ -81,7 +81,7 @@ class ContractUpgradeFlowTest { requireNotNull(btx) // The request is expected to be rejected because party B hasn't authorised the upgrade yet. - val rejectedFuture = a.services.startFlow(ContractUpgradeFlow.Initiator(atx!!.tx.outRef(0), DummyContractV2::class.java)).resultFuture + val rejectedFuture = a.services.startFlow(ContractUpgradeFlow.Initiate(atx!!.tx.outRef(0), DummyContractV2::class.java)).resultFuture mockNet.runNetwork() assertFailsWith(UnexpectedFlowEndException::class) { rejectedFuture.getOrThrow() } @@ -90,7 +90,7 @@ class ContractUpgradeFlowTest { b.services.startFlow(ContractUpgradeFlow.Deauthorise(btx.tx.outRef(0).ref)).resultFuture.getOrThrow() // The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade. - val deauthorisedFuture = a.services.startFlow(ContractUpgradeFlow.Initiator(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture + val deauthorisedFuture = a.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture mockNet.runNetwork() assertFailsWith(UnexpectedFlowEndException::class) { deauthorisedFuture.getOrThrow() } @@ -98,7 +98,7 @@ class ContractUpgradeFlowTest { b.services.startFlow(ContractUpgradeFlow.Authorise(btx.tx.outRef(0), DummyContractV2::class.java)).resultFuture.getOrThrow() // Party A initiates contract upgrade flow, expected to succeed this time. - val resultFuture = a.services.startFlow(ContractUpgradeFlow.Initiator(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture + val resultFuture = a.services.startFlow(ContractUpgradeFlow.Initiate(atx.tx.outRef(0), DummyContractV2::class.java)).resultFuture mockNet.runNetwork() val result = resultFuture.getOrThrow() @@ -144,8 +144,7 @@ class ContractUpgradeFlowTest { val user = rpcTestUser.copy(permissions = setOf( startFlowPermission(), - startFlowPermission>(), - startFlowPermission(), + startFlowPermission>(), startFlowPermission(), startFlowPermission() )) @@ -160,7 +159,7 @@ class ContractUpgradeFlowTest { requireNotNull(atx) requireNotNull(btx) - val rejectedFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiator(stateAndRef, upgrade) }, + val rejectedFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) }, atx!!.tx.outRef(0), DummyContractV2::class.java).returnValue @@ -175,7 +174,7 @@ class ContractUpgradeFlowTest { btx.tx.outRef(0).ref).returnValue // The request is expected to be rejected because party B has subsequently deauthorised and a previously authorised upgrade. - val deauthorisedFuture = rpcA.startFlow( {stateAndRef, upgrade -> ContractUpgradeFlow.Initiator(stateAndRef, upgrade) }, + val deauthorisedFuture = rpcA.startFlow( {stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) }, atx.tx.outRef(0), DummyContractV2::class.java).returnValue @@ -188,7 +187,7 @@ class ContractUpgradeFlowTest { DummyContractV2::class.java).returnValue // Party A initiates contract upgrade flow, expected to succeed this time. - val resultFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiator(stateAndRef, upgrade) }, + val resultFuture = rpcA.startFlow({ stateAndRef, upgrade -> ContractUpgradeFlow.Initiate(stateAndRef, upgrade) }, atx.tx.outRef(0), DummyContractV2::class.java).returnValue @@ -222,7 +221,7 @@ class ContractUpgradeFlowTest { val baseState = a.database.transaction { a.services.vaultQueryService.queryBy().states.single() } assertTrue(baseState.state.data is Cash.State, "Contract state is old version.") // Starts contract upgrade flow. - val upgradeResult = a.services.startFlow(ContractUpgradeFlow.Initiator(stateAndRef, CashV2::class.java)).resultFuture + val upgradeResult = a.services.startFlow(ContractUpgradeFlow.Initiate(stateAndRef, CashV2::class.java)).resultFuture mockNet.runNetwork() upgradeResult.getOrThrow() // Get contract state from the vault. diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 173c9f2a73..dccfbcc459 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -207,6 +207,8 @@ UNRELEASED * A new ``ComponentGroupEnum`` is added with the following enum items: ``INPUTS_GROUP``, ``OUTPUTS_GROUP``, ``COMMANDS_GROUP``, ``ATTACHMENTS_GROUP``, ``NOTARY_GROUP``, ``TIMEWINDOW_GROUP``. +* ``ContractUpgradeFlow.Initiator`` has been renamed to ``ContractUpgradeFlow.Initiate`` + Milestone 14 ------------ diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt index d7a37a1602..1b5fdc0afa 100644 --- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt @@ -8,7 +8,6 @@ import net.corda.confidential.SwapIdentitiesFlow import net.corda.confidential.SwapIdentitiesHandler import net.corda.core.concurrent.CordaFuture import net.corda.core.flows.* -import net.corda.core.flows.ContractUpgradeFlow.Acceptor import net.corda.core.identity.CordaX500Name import net.corda.core.identity.Party import net.corda.core.identity.PartyAndCertificate @@ -35,6 +34,7 @@ import net.corda.core.utilities.debug import net.corda.node.internal.classloading.requireAnnotation import net.corda.node.internal.cordapp.CordappLoader import net.corda.node.internal.cordapp.CordappProvider +import net.corda.node.services.ContractUpgradeHandler import net.corda.node.services.FinalityHandler import net.corda.node.services.NotaryChangeHandler import net.corda.node.services.api.* @@ -372,7 +372,7 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, private fun installCoreFlows() { installCoreFlow(FinalityFlow::class, ::FinalityHandler) installCoreFlow(NotaryChangeFlow::class, ::NotaryChangeHandler) - installCoreFlow(ContractUpgradeFlow.Initiator::class, ::Acceptor) + installCoreFlow(ContractUpgradeFlow.Initiate::class, ::ContractUpgradeHandler) installCoreFlow(SwapIdentitiesFlow::class, ::SwapIdentitiesHandler) } diff --git a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt index 77d34308e9..95d8ecc27e 100644 --- a/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt +++ b/node/src/main/kotlin/net/corda/node/internal/cordapp/CordappLoader.kt @@ -54,8 +54,7 @@ class CordappLoader private constructor(private val cordappJarPaths: List) /** * Creates a dev mode CordappLoader intended to only be used in test environments. * - * @param scanPackage Resolves the JARs that contain scanPackage and use them as the source for - * the classpath scanning. + * @param scanPackages list of packages to scan. */ fun createDevMode(scanPackages: String): CordappLoader { val paths = scanPackages.split(",").flatMap { scanPackage -> @@ -123,7 +122,11 @@ class CordappLoader private constructor(private val cordappJarPaths: List) } val found = scanResult.getClassesWithAnnotation(FlowLogic::class, StartableByRPC::class).filter { it.isUserInvokable() } - val coreFlows = listOf(ContractUpgradeFlow.Initiator::class.java) + val coreFlows = listOf( + ContractUpgradeFlow.Initiate::class.java, + ContractUpgradeFlow.Authorise::class.java, + ContractUpgradeFlow.Deauthorise::class.java + ) return found + coreFlows } diff --git a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt index 57b6349dc2..6c2ad845a3 100644 --- a/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt +++ b/node/src/main/kotlin/net/corda/node/services/CoreFlowHandlers.kt @@ -1,8 +1,13 @@ package net.corda.node.services import co.paralleluniverse.fibers.Suspendable +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.UpgradeCommand +import net.corda.core.contracts.UpgradedContract +import net.corda.core.contracts.requireThat import net.corda.core.flows.* import net.corda.core.identity.Party +import net.corda.core.internal.ContractUpgradeUtils import net.corda.core.transactions.SignedTransaction // TODO: We should have a whitelist of contracts we're willing to accept at all, and reject if the transaction @@ -41,3 +46,27 @@ class NotaryChangeHandler(otherSideSession: FlowSession) : AbstractStateReplacem } } } + +class ContractUpgradeHandler(otherSide: FlowSession) : AbstractStateReplacementFlow.Acceptor>>(otherSide) { + @Suspendable + override fun verifyProposal(stx: SignedTransaction, proposal: AbstractStateReplacementFlow.Proposal>>) { + // Retrieve signed transaction from our side, we will apply the upgrade logic to the transaction on our side, and + // verify outputs matches the proposed upgrade. + val ourSTX = serviceHub.validatedTransactions.getTransaction(proposal.stateRef.txhash) + requireNotNull(ourSTX) { "We don't have a copy of the referenced state" } + val oldStateAndRef = ourSTX!!.tx.outRef(proposal.stateRef.index) + val authorisedUpgrade = serviceHub.contractUpgradeService.getAuthorisedContractUpgrade(oldStateAndRef.ref) ?: + throw IllegalStateException("Contract state upgrade is unauthorised. State hash : ${oldStateAndRef.ref}") + val proposedTx = stx.tx + val expectedTx = ContractUpgradeUtils.assembleBareTx(oldStateAndRef, proposal.modification, proposedTx.privacySalt).toWireTransaction() + requireThat { + "The instigator is one of the participants" using (initiatingSession.counterparty in oldStateAndRef.state.data.participants) + "The proposed upgrade ${proposal.modification.javaClass} is a trusted upgrade path" using (proposal.modification.name == authorisedUpgrade) + "The proposed tx matches the expected tx for this upgrade" using (proposedTx == expectedTx) + } + ContractUpgradeFlow.verify( + oldStateAndRef.state, + expectedTx.outRef(0).state, + expectedTx.toLedgerTransaction(serviceHub).commandsOfType().single()) + } +} diff --git a/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt b/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt index b239ac01d6..a4cf1bfb85 100644 --- a/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt +++ b/node/src/test/kotlin/net/corda/node/cordapp/CordappLoaderTest.kt @@ -46,7 +46,7 @@ class CordappLoaderTest { val actualCordapp = actual.first() assertThat(actualCordapp.contractClassNames).isEqualTo(listOf("net.corda.finance.contracts.isolated.AnotherDummyContract")) assertThat(actualCordapp.initiatedFlows).isEmpty() - assertThat(actualCordapp.rpcFlows).isEqualTo(listOf(loader.appClassLoader.loadClass("net.corda.core.flows.ContractUpgradeFlow\$Initiator").asSubclass(FlowLogic::class.java))) + assertThat(actualCordapp.rpcFlows).contains(loader.appClassLoader.loadClass("net.corda.core.flows.ContractUpgradeFlow\$Initiate").asSubclass(FlowLogic::class.java)) assertThat(actualCordapp.services).isEmpty() assertThat(actualCordapp.plugins).hasSize(1) assertThat(actualCordapp.plugins.first().javaClass.name).isEqualTo("net.corda.finance.contracts.isolated.DummyPlugin") diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt index 2fcb8fed73..cf7c7ddd34 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt @@ -15,7 +15,7 @@ const val DUMMY_V2_PROGRAM_ID: ContractClassName = "net.corda.testing.contracts. */ // DOCSTART 1 class DummyContractV2 : UpgradedContract { - override val legacyContract = DummyContract::class.java.name + override val legacyContract: String = DummyContract::class.java.name data class State(val magicNumber: Int = 0, val owners: List) : ContractState { override val participants: List = owners @@ -31,7 +31,7 @@ class DummyContractV2 : UpgradedContract Date: Fri, 22 Sep 2017 15:14:16 +0100 Subject: [PATCH 039/230] Joel states api (#1605) * Updates the states API page. * Minor fixes. * Further fixes. * Adds ToC * Addresses review feedback. --- docs/source/api-states.rst | 117 +++++++++++++++++++------------------ 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/docs/source/api-states.rst b/docs/source/api-states.rst index 30b4b3686e..6b3aea888d 100644 --- a/docs/source/api-states.rst +++ b/docs/source/api-states.rst @@ -3,9 +3,12 @@ API: States .. note:: Before reading this page, you should be familiar with the key concepts of :doc:`key-concepts-states`. +.. contents:: + ContractState ------------- -In Corda, states are classes that implement ``ContractState``. The ``ContractState`` interface is defined as follows: +In Corda, states are instances of classes that implement ``ContractState``. The ``ContractState`` interface is defined +as follows: .. container:: codeset @@ -14,37 +17,29 @@ In Corda, states are classes that implement ``ContractState``. The ``ContractSta :start-after: DOCSTART 1 :end-before: DOCEND 1 -Where: +``ContractState`` has a single field, ``participants``. ``participants`` is a ``List`` of the ``AbstractParty`` that +are considered to have a stake in the state. Among other things, the ``participants`` will: -* ``contract`` is the ``Contract`` class defining the constraints on transactions involving states of this type -* ``participants`` is a ``List`` of the ``AbstractParty`` who are considered to have a stake in the state. For example, - all the ``participants`` will: +* Usually store the state in their vault (see below) - * Need to sign a notary-change transaction for this state - * Receive any committed transactions involving this state as part of ``FinalityFlow`` +* Need to sign any notary-change and contract-upgrade transactions involving this state -The vault ---------- -Each node has a vault, where it stores the states that are "relevant" to the node's owner. Whenever the node sees a -new transaction, it performs a relevancy check to decide whether to add each of the transaction's output states to -its vault. The default vault implementation decides whether a state is relevant as follows: - - * The vault will store any state for which it is one of the ``participants`` - * This behavior is overridden for states that implement ``LinearState`` or ``OwnableState`` (see below) - -If a state is not considered relevant, the node will still store the transaction in its local storage, but it will -not track the transaction's states in its vault. +* Receive any finalised transactions involving this state as part of ``FinalityFlow`` ContractState sub-interfaces ---------------------------- -There are two common optional sub-interfaces of ``ContractState``: +The behaviour of the state can be further customised by implementing sub-interfaces of ``ContractState``. The two most +common sub-interfaces are: -* ``LinearState``, which helps represent objects that have a constant identity over time -* ``OwnableState``, which helps represent fungible assets +* ``LinearState`` -For example, a cash is an ``OwnableState`` - you don't have a specific piece of cash you are tracking over time, but -rather a total amount of cash that you can combine and divide at will. A contract, on the other hand, cannot be -merged with other contracts of the same type - it has a unique separate identity over time. +* ``OwnableState`` + +``LinearState`` models shared facts for which there is only one current version at any point in time. ``LinearState`` +states evolve in a straight line by superseding themselves. On the other hand, ``OwnableState`` is meant to represent +assets that can be freely split and merged over time. Cash is a good example of an ``OwnableState`` - two existing $5 +cash states can be combined into a single $10 cash state, or split into five $1 cash states. With ``OwnableState``, its +the total amount held that is important, rather than the actual units held. We can picture the hierarchy as follows: @@ -52,12 +47,6 @@ We can picture the hierarchy as follows: LinearState ^^^^^^^^^^^ -``LinearState`` models facts that have a constant identity over time. Remember that in Corda, states are immutable and -can't be updated directly. Instead, we represent an evolving fact as a sequence of states where every state is a -``LinearState`` that shares the same ``linearId``. Each sequence of linear states represents the lifecycle of a given -fact up to the current point in time. It represents the historic audit trail of how the fact evolved over time to its -current "state". - The ``LinearState`` interface is defined as follows: .. container:: codeset @@ -67,32 +56,31 @@ The ``LinearState`` interface is defined as follows: :start-after: DOCSTART 2 :end-before: DOCEND 2 -Where: +Remember that in Corda, states are immutable and can't be updated directly. Instead, we represent an evolving fact as a +sequence of ``LinearState`` states that share the same ``linearId`` and represent an audit trail for the lifecycle of +the fact over time. -* ``linearId`` is a ``UniqueIdentifier`` that: +When we want to extend a ``LinearState`` chain (i.e. a sequence of states sharing a ``linearId``), we: - * Allows the successive versions of the fact to be linked over time - * Provides an ``externalId`` for referencing the state in external systems +* Use the ``linearId`` to extract the latest state in the chain from the vault -* ``isRelevant(ourKeys: Set)`` overrides the default vault implementation's relevancy check. You would - generally override it to check whether ``ourKeys`` is relevant to the state at hand in some way. +* Create a new state that has the same ``linearId`` -The vault tracks the head (i.e. the most recent version) of each ``LinearState`` chain (i.e. each sequence of -states all sharing a ``linearId``). To create a transaction updating a ``LinearState``, we retrieve the state from the -vault using its ``linearId``. +* Create a transaction with: -UniqueIdentifier -~~~~~~~~~~~~~~~~ -``UniqueIdentifier`` is a combination of a (Java) ``UUID`` representing a globally unique 128 bit random number, and -an arbitrary string which can be paired with it. For instance the string may represent an existing "weak" (not -guaranteed unique) identifier for convenience purposes. + * The current latest state in the chain as an input + + * The newly-created state as an output + +The new state will now become the latest state in the chain, representing the new current state of the agreement. + +``linearId`` is of type ``UniqueIdentifier``, which is a combination of: + +* A Java ``UUID`` representing a globally unique 128 bit random number +* An optional external-reference string for referencing the state in external systems OwnableState ^^^^^^^^^^^^ -``OwnableState`` models fungible assets. Fungible assets are assets for which it's the total amount held that is -important, rather than the actual units held. US dollars are an example of a fungible asset - we do not track the -individual dollar bills held, but rather the total amount of dollars. - The ``OwnableState`` interface is defined as follows: .. container:: codeset @@ -106,26 +94,26 @@ Where: * ``owner`` is the ``PublicKey`` of the asset's owner - * ``OwnableState`` also override the default behavior of the vault's relevancy check. The default vault - implementation will track any ``OwnableState`` of which it is the owner. +* ``withNewOwner(newOwner: AbstractParty)`` creates an copy of the state with a new owner -* ``withNewOwner(newOwner: AbstractParty)`` creates an identical copy of the state, only with a new owner +Because ``OwnableState`` models fungible assets that can be merged and split over time, ``OwnableState`` instances do +not have a ``linearId``. $5 of cash created by one transaction is considered to be identical to $5 of cash produced by +another transaction. Other interfaces ^^^^^^^^^^^^^^^^ -``ContractState`` has several more sub-interfaces that can optionally be implemented: +You can also customize your state by implementing the following interfaces: -* ``QueryableState``, which allows the state to be queried in the node's database using SQL (see +* ``QueryableState``, which allows the state to be queried in the node's database using custom attributes (see :doc:`api-persistence`) -* ``SchedulableState``, which allows us to schedule future actions for the state (e.g. a coupon on a bond) (see + +* ``SchedulableState``, which allows us to schedule future actions for the state (e.g. a coupon payment on a bond) (see :doc:`event-scheduling`) User-defined fields ------------------- -Beyond implementing ``LinearState`` or ``OwnableState``, the definition of the state is up to the CorDapp developer. -You can define any additional class fields and methods you see fit. - -For example, here is a relatively complex state definition, for a state representing cash: +Beyond implementing ``ContractState`` or a sub-interface, a state is allowed to have any number of additional fields +and methods. For example, here is the relatively complex definition for a state representing cash: .. container:: codeset @@ -134,6 +122,17 @@ For example, here is a relatively complex state definition, for a state represen :start-after: DOCSTART 1 :end-before: DOCEND 1 +The vault +--------- +Whenever a node records a new transaction, it also decides whether it should store each of the transaction's output +states in its vault. The default vault implementation makes the decision based on the following rules: + + * If the state is an ``OwnableState``, the vault will store the state if the node is the state's ``owner`` + * Otherwise, the vault will store the state if it is one of the ``participants`` + +States that are not considered relevant are not stored in the node's vault. However, the node will still store the +transactions that created the states in its transaction storage. + TransactionState ---------------- When a ``ContractState`` is added to a ``TransactionBuilder``, it is wrapped in a ``TransactionState``: @@ -148,6 +147,8 @@ When a ``ContractState`` is added to a ``TransactionBuilder``, it is wrapped in Where: * ``data`` is the state to be stored on-ledger +* ``contract`` is the contract governing evolutions of this state * ``notary`` is the notary service for this state * ``encumbrance`` points to another state that must also appear as an input to any transaction consuming this state +* ``constraint`` is a constraint on which contract-code attachments can be used with this state \ No newline at end of file From 21cb1bf6f31ef3ac83ed69b03cb94a17318d2d28 Mon Sep 17 00:00:00 2001 From: Shams Asari Date: Fri, 22 Sep 2017 16:03:24 +0100 Subject: [PATCH 040/230] Moved the RPC classes in node-api that are needed in client-rpc. (#1610) Everything that now remains in node-api isn't needed as public API for app developers so we can mark this module as non-public and subject to change. --- .../corda/client/rpc/PermissionException.kt | 10 +++++++++ .../net/corda/client/rpc/RPCException.kt | 11 ++++++++++ .../net/corda/client/rpc/RPCSinceVersion.kt | 6 +++++ .../corda/client/rpc/internal/RPCClient.kt | 2 +- .../rpc/internal/RPCClientProxyHandler.kt | 2 ++ .../rpc/ClientRPCInfrastructureTests.kt | 1 - .../corda/client/rpc/RPCPermissionsTests.kt | 1 - docs/source/changelog.rst | 2 ++ .../kotlin/net/corda/nodeapi/RPCStructures.kt | 22 ------------------- .../amqp/SerializationOutputTests.kt | 2 +- .../node/services/messaging/RPCServer.kt | 1 + .../services/messaging/RPCServerStructures.kt | 2 +- .../net/corda/node/CordaRPCOpsImplTest.kt | 2 +- 13 files changed, 36 insertions(+), 28 deletions(-) create mode 100644 client/rpc/src/main/kotlin/net/corda/client/rpc/PermissionException.kt create mode 100644 client/rpc/src/main/kotlin/net/corda/client/rpc/RPCException.kt create mode 100644 client/rpc/src/main/kotlin/net/corda/client/rpc/RPCSinceVersion.kt diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/PermissionException.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/PermissionException.kt new file mode 100644 index 0000000000..0498801989 --- /dev/null +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/PermissionException.kt @@ -0,0 +1,10 @@ +package net.corda.client.rpc + +import net.corda.core.serialization.CordaSerializable + +/** + * Thrown to indicate that the calling user does not have permission for something they have requested (for example + * calling a method). + */ +@CordaSerializable +class PermissionException(msg: String) : RuntimeException(msg) diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCException.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCException.kt new file mode 100644 index 0000000000..32ea9928be --- /dev/null +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCException.kt @@ -0,0 +1,11 @@ +package net.corda.client.rpc + +import net.corda.core.CordaRuntimeException + +/** + * Thrown to indicate a fatal error in the RPC system itself, as opposed to an error generated by the invoked + * method. + */ +open class RPCException(message: String?, cause: Throwable?) : CordaRuntimeException(message, cause) { + constructor(msg: String) : this(msg, null) +} diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCSinceVersion.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCSinceVersion.kt new file mode 100644 index 0000000000..262d009427 --- /dev/null +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/RPCSinceVersion.kt @@ -0,0 +1,6 @@ +package net.corda.client.rpc + +/** Records the protocol version in which this RPC was added. */ +@Target(AnnotationTarget.FUNCTION) +@MustBeDocumented +annotation class RPCSinceVersion(val version: Int) diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClient.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClient.kt index cca836d858..f0fc941668 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClient.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClient.kt @@ -1,5 +1,6 @@ package net.corda.client.rpc.internal +import net.corda.client.rpc.RPCException import net.corda.core.crypto.random63BitValue import net.corda.core.internal.logElapsedTime import net.corda.core.messaging.RPCOps @@ -12,7 +13,6 @@ import net.corda.core.utilities.seconds import net.corda.nodeapi.ArtemisTcpTransport.Companion.tcpTransport import net.corda.nodeapi.ConnectionDirection import net.corda.nodeapi.RPCApi -import net.corda.nodeapi.RPCException import net.corda.nodeapi.config.SSLConfiguration import org.apache.activemq.artemis.api.core.SimpleString import org.apache.activemq.artemis.api.core.TransportConfiguration diff --git a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt index e0a0c21ca0..10e901eb70 100644 --- a/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt +++ b/client/rpc/src/main/kotlin/net/corda/client/rpc/internal/RPCClientProxyHandler.kt @@ -10,6 +10,8 @@ import com.google.common.cache.RemovalCause import com.google.common.cache.RemovalListener import com.google.common.util.concurrent.SettableFuture import com.google.common.util.concurrent.ThreadFactoryBuilder +import net.corda.client.rpc.RPCException +import net.corda.client.rpc.RPCSinceVersion import net.corda.core.crypto.random63BitValue import net.corda.core.internal.LazyPool import net.corda.core.internal.LazyStickyPool diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/ClientRPCInfrastructureTests.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/ClientRPCInfrastructureTests.kt index e798438fa7..3502145ae0 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/ClientRPCInfrastructureTests.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/ClientRPCInfrastructureTests.kt @@ -7,7 +7,6 @@ import net.corda.core.internal.concurrent.thenMatch import net.corda.core.messaging.RPCOps import net.corda.core.utilities.getOrThrow import net.corda.node.services.messaging.getRpcContext -import net.corda.nodeapi.RPCSinceVersion import net.corda.testing.RPCDriverExposedDSLInterface import net.corda.testing.rpcDriver import net.corda.testing.rpcTestUser diff --git a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt index f31469bcb4..4411bbfd07 100644 --- a/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt +++ b/client/rpc/src/test/kotlin/net/corda/client/rpc/RPCPermissionsTests.kt @@ -3,7 +3,6 @@ package net.corda.client.rpc import net.corda.core.messaging.RPCOps import net.corda.node.services.messaging.getRpcContext import net.corda.node.services.messaging.requirePermission -import net.corda.nodeapi.PermissionException import net.corda.nodeapi.User import net.corda.testing.RPCDriverExposedDSLInterface import net.corda.testing.rpcDriver diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index dccfbcc459..69de13333b 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -209,6 +209,8 @@ UNRELEASED * ``ContractUpgradeFlow.Initiator`` has been renamed to ``ContractUpgradeFlow.Initiate`` +* ``@RPCSinceVersion``, ``RPCException`` and ``PermissionException`` have moved to ``net.corda.client.rpc``. + Milestone 14 ------------ diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/RPCStructures.kt b/node-api/src/main/kotlin/net/corda/nodeapi/RPCStructures.kt index 3911943969..01f56973b5 100644 --- a/node-api/src/main/kotlin/net/corda/nodeapi/RPCStructures.kt +++ b/node-api/src/main/kotlin/net/corda/nodeapi/RPCStructures.kt @@ -5,8 +5,6 @@ package net.corda.nodeapi import com.esotericsoftware.kryo.Registration import com.esotericsoftware.kryo.Serializer import net.corda.core.concurrent.CordaFuture -import net.corda.core.CordaRuntimeException -import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializationContext import net.corda.core.toFuture import net.corda.core.toObservable @@ -28,26 +26,6 @@ data class User( ) } -/** Records the protocol version in which this RPC was added. */ -@Target(AnnotationTarget.FUNCTION) -@MustBeDocumented -annotation class RPCSinceVersion(val version: Int) - -/** - * Thrown to indicate a fatal error in the RPC system itself, as opposed to an error generated by the invoked - * method. - */ -open class RPCException(message: String?, cause: Throwable?) : CordaRuntimeException(message, cause) { - constructor(msg: String) : this(msg, null) -} - -/** - * Thrown to indicate that the calling user does not have permission for something they have requested (for example - * calling a method). - */ -@CordaSerializable -class PermissionException(msg: String) : RuntimeException(msg) - /** * The Kryo used for the RPC wire protocol. */ diff --git a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt index e30e63c3c4..05cd84c934 100644 --- a/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt +++ b/node-api/src/test/kotlin/net/corda/nodeapi/internal/serialization/amqp/SerializationOutputTests.kt @@ -12,7 +12,7 @@ import net.corda.core.internal.toX509CertHolder import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.SerializationFactory import net.corda.core.transactions.LedgerTransaction -import net.corda.nodeapi.RPCException +import net.corda.client.rpc.RPCException import net.corda.nodeapi.internal.serialization.AbstractAMQPSerializationScheme import net.corda.nodeapi.internal.serialization.AllWhitelist import net.corda.nodeapi.internal.serialization.EmptyWhitelist diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt index 10b4373716..b4c61c2574 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServer.kt @@ -11,6 +11,7 @@ import com.google.common.collect.HashMultimap import com.google.common.collect.Multimaps import com.google.common.collect.SetMultimap import com.google.common.util.concurrent.ThreadFactoryBuilder +import net.corda.client.rpc.RPCException import net.corda.core.crypto.random63BitValue import net.corda.core.identity.CordaX500Name import net.corda.core.internal.LazyStickyPool diff --git a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServerStructures.kt b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServerStructures.kt index ab546ea4d9..e8e91d793f 100644 --- a/node/src/main/kotlin/net/corda/node/services/messaging/RPCServerStructures.kt +++ b/node/src/main/kotlin/net/corda/node/services/messaging/RPCServerStructures.kt @@ -2,8 +2,8 @@ package net.corda.node.services.messaging +import net.corda.client.rpc.PermissionException import net.corda.nodeapi.ArtemisMessagingComponent -import net.corda.nodeapi.PermissionException /** Helper method which checks that the current RPC user is entitled for the given permission. Throws a [PermissionException] otherwise. */ fun RpcContext.requirePermission(permission: String) { diff --git a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt index 0f2a33aec5..eb05bac499 100644 --- a/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt +++ b/node/src/test/kotlin/net/corda/node/CordaRPCOpsImplTest.kt @@ -30,7 +30,7 @@ import net.corda.node.services.network.NetworkMapService import net.corda.node.services.FlowPermissions.Companion.startFlowPermission import net.corda.nodeapi.internal.ServiceInfo import net.corda.node.services.transactions.SimpleNotaryService -import net.corda.nodeapi.PermissionException +import net.corda.client.rpc.PermissionException import net.corda.nodeapi.User import net.corda.testing.chooseIdentity import net.corda.testing.expect From addd3b34c8682ed75a1c6717aa6093099bdb30ca Mon Sep 17 00:00:00 2001 From: Matthew Nesbit Date: Fri, 22 Sep 2017 16:11:45 +0100 Subject: [PATCH 041/230] Ensure Shell parsing of commands has a database, so that identity lookups can function. (#1608) Fixup unit tests --- .../net/corda/node/shell/InteractiveShell.kt | 12 +++++++++--- .../net/corda/node/InteractiveShellTest.kt | 17 +++++++++++++++-- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt b/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt index 27d790e8f1..668236515a 100644 --- a/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt +++ b/node/src/main/kotlin/net/corda/node/shell/InteractiveShell.kt @@ -29,6 +29,7 @@ import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT import net.corda.node.services.messaging.RpcContext import net.corda.node.services.statemachine.FlowStateMachineImpl import net.corda.node.utilities.ANSIProgressRenderer +import net.corda.node.utilities.CordaPersistence import net.corda.nodeapi.ArtemisMessagingComponent import net.corda.nodeapi.User import org.crsh.command.InvocationContext @@ -77,6 +78,8 @@ import kotlin.concurrent.thread object InteractiveShell { private val log = loggerFor() private lateinit var node: StartedNode + @VisibleForTesting + internal lateinit var database: CordaPersistence /** * Starts an interactive shell connected to the local terminal. This shell gives administrator access to the node @@ -84,6 +87,7 @@ object InteractiveShell { */ fun startShell(dir: Path, runLocalShell: Boolean, runSSHServer: Boolean, node: StartedNode) { this.node = node + this.database = node.database var runSSH = runSSHServer val config = Properties() @@ -287,8 +291,10 @@ object InteractiveShell { try { // Attempt construction with the given arguments. - paramNamesFromConstructor = parser.paramNamesFromConstructor(ctor) - val args = parser.parseArguments(clazz.name, paramNamesFromConstructor.zip(ctor.parameterTypes), inputData) + val args = database.transaction { + paramNamesFromConstructor = parser.paramNamesFromConstructor(ctor) + parser.parseArguments(clazz.name, paramNamesFromConstructor!!.zip(ctor.parameterTypes), inputData) + } if (args.size != ctor.parameterTypes.size) { errors.add("${getPrototype()}: Wrong number of arguments (${args.size} provided, ${ctor.parameterTypes.size} needed)") continue @@ -358,7 +364,7 @@ object InteractiveShell { var result: Any? = null try { InputStreamSerializer.invokeContext = context - val call = parser.parse(context.attributes["ops"] as CordaRPCOps, cmd) + val call = database.transaction { parser.parse(context.attributes["ops"] as CordaRPCOps, cmd) } result = call.call() if (result != null && result !is kotlin.Unit && result !is Void) { result = printAndFollowRPCResponse(result, out) diff --git a/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt b/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt index a0c425540d..d13fda0a4c 100644 --- a/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt +++ b/node/src/test/kotlin/net/corda/node/InteractiveShellTest.kt @@ -7,20 +7,33 @@ import net.corda.core.contracts.Amount import net.corda.core.crypto.SecureHash import net.corda.core.flows.FlowLogic import net.corda.core.identity.Party -import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.FlowStateMachine import net.corda.core.utilities.ProgressTracker -import net.corda.core.utilities.UntrustworthyData import net.corda.node.services.identity.InMemoryIdentityService import net.corda.node.shell.InteractiveShell +import net.corda.node.utilities.configureDatabase import net.corda.testing.DEV_TRUST_ROOT import net.corda.testing.MEGA_CORP import net.corda.testing.MEGA_CORP_IDENTITY +import net.corda.testing.node.MockServices +import net.corda.testing.node.MockServices.Companion.makeTestIdentityService +import org.junit.After +import org.junit.Before import org.junit.Test import java.util.* import kotlin.test.assertEquals class InteractiveShellTest { + @Before + fun setup() { + InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), MockServices.makeTestDatabaseProperties(), createIdentityService = ::makeTestIdentityService) + } + + @After + fun shutdown() { + InteractiveShell.database.close() + } + @Suppress("UNUSED") class FlowA(val a: String) : FlowLogic() { constructor(b: Int) : this(b.toString()) From ce8ea5cb503a172804bf6cc0f5aa8c1760e1c8bd Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Fri, 22 Sep 2017 16:51:14 +0100 Subject: [PATCH 042/230] Joel api contracts (#1611) Updated documentation: API contracts --- docs/source/api-contracts.rst | 220 +++++++++++++--------------------- 1 file changed, 81 insertions(+), 139 deletions(-) diff --git a/docs/source/api-contracts.rst b/docs/source/api-contracts.rst index ea057bbce9..b7096c66f6 100644 --- a/docs/source/api-contracts.rst +++ b/docs/source/api-contracts.rst @@ -9,9 +9,11 @@ API: Contracts .. note:: Before reading this page, you should be familiar with the key concepts of :doc:`key-concepts-contracts`. -All Corda contracts are JVM classes that implement ``net.corda.core.contracts.Contract``. +.. contents:: -The ``Contract`` interface is defined as follows: +Contract +-------- +Contracts are classes that implement the ``Contract`` interface. The ``Contract`` interface is defined as follows: .. container:: codeset @@ -20,25 +22,27 @@ The ``Contract`` interface is defined as follows: :start-after: DOCSTART 5 :end-before: DOCEND 5 -Where: +``Contract`` has a single method, ``verify``, which takes a ``LedgerTransaction`` as input and returns +nothing. This function is used to check whether a transaction proposal is valid, as follows: -* ``verify(tx: LedgerTransaction)`` determines whether transactions involving states which reference this contract type are valid +* We gather together the contracts of each of the transaction's input and output states +* We call each contract's ``verify`` function, passing in the transaction as an input +* The proposal is only valid if none of the ``verify`` calls throw an exception -verify() --------- +``verify`` is executed in a sandbox: -``verify()`` is a method that doesn't return anything and takes a ``LedgerTransaction`` as a parameter. It -either throws an exception if the transaction is considered invalid, or returns normally if the transaction is -considered valid. +* It does not have access to the enclosing scope +* The libraries available to it are whitelisted to disallow: + * Network access + * I/O such as disk or database access + * Sources of randomness such as the current time or random number generators -``verify()`` is executed in a sandbox. It does not have access to the enclosing scope, and is not able to access -the network or perform any other I/O. It only has access to the properties defined on ``LedgerTransaction`` when -establishing whether a transaction is valid. +This means that ``verify`` only has access to the properties defined on ``LedgerTransaction`` when deciding whether a +transaction is valid. -The two simplest ``verify`` functions are the one that accepts all transactions, and the one that rejects all -transactions. +Here are the two simplest ``verify`` functions: -Here is the ``verify`` that accepts all transactions: +* A ``verify`` that **accepts** all possible transactions: .. container:: codeset @@ -55,7 +59,7 @@ Here is the ``verify`` that accepts all transactions: // Always accepts! } -And here is the ``verify`` that rejects all transactions: +* A ``verify`` that **rejects** all possible transactions: .. container:: codeset @@ -73,10 +77,8 @@ And here is the ``verify`` that rejects all transactions: } LedgerTransaction -^^^^^^^^^^^^^^^^^^^^^^ - -The ``LedgerTransaction`` object passed into ``verify()`` represents the full set of information available to -``verify()`` when deciding whether to accept or reject the transaction. It has the following properties: +----------------- +The ``LedgerTransaction`` object passed into ``verify`` has the following properties: .. container:: codeset @@ -87,18 +89,52 @@ The ``LedgerTransaction`` object passed into ``verify()`` represents the full se Where: - * ``inputs`` is a list of the transaction's inputs' -* ``outputs`` is a list of the transaction's outputs' -* ``attachments`` is a list of the transaction's attachments' -* ``commands`` is a list of the transaction's commands, and their associated signatures' -* ``id`` is the transaction's Merkle root hash' -* ``notary`` is the transaction's notary. If there are inputs these must have the same notary on their source transactions. -* ``timeWindow`` is the transaction's timestamp and defines the acceptable delay for notarisation. +* ``inputs`` are the transaction's inputs as ``List>`` +* ``outputs`` are the transaction's outputs as ``List>`` +* ``commands`` are the transaction's commands and associated signers, as ``List>`` +* ``attachments`` are the transaction's attachments as ``List`` +* ``notary`` is the transaction's notary. This must match the notary of all the inputs +* ``timeWindow`` defines the window during which the transaction can be notarised -requireThat() -^^^^^^^^^^^^^ +``LedgerTransaction`` exposes a large number of utility methods to access the transaction's contents: -Instead of throwing exceptions manually to reject a transaction, we can use the ``requireThat`` DSL: +* ``inputStates`` extracts the input ``ContractState`` objects from the list of ``StateAndRef`` +* ``getInput``/``getOutput``/``getCommand``/``getAttachment`` extracts a component by index +* ``getAttachment`` extracts an attachment by ID +* ``inputsOfType``/``inRefsOfType``/``outputsOfType``/``outRefsOfType``/``commandsOfType`` extracts components based on + their generic type +* ``filterInputs``/``filterInRefs``/``filterOutputs``/``filterOutRefs``/``filterCommands`` extracts components based on + a predicate +* ``findInput``/``findInRef``/``findOutput``/``findOutRef``/``findCommand`` extracts the single component that matches + a predicate, or throws an exception if there are multiple matches + +requireThat +----------- +``verify`` can be written to manually throw an exception for each constraint: + +.. container:: codeset + + .. sourcecode:: kotlin + + override fun verify(tx: LedgerTransaction) { + if (tx.inputs.size > 0) + throw IllegalArgumentException("No inputs should be consumed when issuing an X.") + + if (tx.outputs.size != 1) + throw IllegalArgumentException("Only one output state should be created.") + } + + .. sourcecode:: java + + public void verify(LedgerTransaction tx) { + if (tx.getInputs().size() > 0) + throw new IllegalArgumentException("No inputs should be consumed when issuing an X."); + + if (tx.getOutputs().size() != 1) + throw new IllegalArgumentException("Only one output state should be created."); + } + +However, this is verbose. To impose a series of constraints, we can use ``requireThat`` instead: .. container:: codeset @@ -130,11 +166,9 @@ For each <``String``, ``Boolean``> pair within ``requireThat``, if the boolean c exception will cause the transaction to be rejected. Commands -^^^^^^^^ - -``LedgerTransaction`` contains the commands as a list of ``CommandWithParties`` instances. -``CommandWithParties`` pairs a command with a list of the entities that are required to sign a transaction -where this command is present: +-------- +``LedgerTransaction`` contains the commands as a list of ``CommandWithParties`` instances. ``CommandWithParties`` pairs +a ``CommandData`` with a list of required signers for the transaction: .. container:: codeset @@ -149,19 +183,13 @@ Where: * ``signingParties`` is the list of the signer's identities, if known * ``value`` is the object being signed (a command, in this case) -Extracting commands -~~~~~~~~~~~~~~~~~~~ -You can use the ``requireSingleCommand()`` helper method to extract commands. +Branching verify with commands +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Generally, we will want to impose different constraints on a transaction based on its commands. For example, we will +want to impose different constraints on a cash issuance transaction to on a cash transfer transaction. -`` Collection>.requireSingleCommand(klass: Class)`` asserts that -the transaction contains exactly one command of type ``T``, and returns it. If there is not exactly one command of this -type in the transaction, an exception is thrown, rejecting the transaction. - -For ``requireSingleCommand`` to work, all the commands that we wish to match against must be grouped using the same -marker interface. - -Here is an example of using ``requireSingleCommand`` to extract a transaction's command and using it to fork the -execution of ``verify()``: +We can achieve this by extracting the command and using standard branching logic within ``verify``. Here, we extract +the single command of type ``XContract.Commands`` from the transaction, and branch ``verify`` accordingly: .. container:: codeset @@ -174,9 +202,9 @@ execution of ``verify()``: } override fun verify(tx: LedgerTransaction) { - val command = tx.commands.requireSingleCommand() + val command = tx.findCommand { true } - when (command.value) { + when (command) { is Commands.Issue -> { // Issuance verification logic. } @@ -197,98 +225,12 @@ execution of ``verify()``: @Override public void verify(LedgerTransaction tx) { - final CommandWithParties command = requireSingleCommand(tx.getCommands(), Commands.class); + final Command command = tx.findCommand(Commands.class, cmd -> true); - if (command.getValue() instanceof Commands.Issue) { + if (command instanceof Commands.Issue) { // Issuance verification logic. - } else if (command.getValue() instanceof Commands.Transfer) { + } else if (command instanceof Commands.Transfer) { // Transfer verification logic. } } - } - -Grouping states ---------------- -Suppose we have the following transaction, where 15 USD is being exchanged for 10 GBP: - -.. image:: resources/ungrouped-tx.png - :scale: 20 - :align: center - -We can imagine that we would like to verify the USD states and the GBP states separately: - -.. image:: resources/grouped-tx.png - :scale: 20 - :align: center - -``LedgerTransaction`` provides a ``groupStates`` method to allow you to group states in this way: - -.. container:: codeset - - .. literalinclude:: ../../core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt - :language: kotlin - :start-after: DOCSTART 2 - :end-before: DOCEND 2 - -Where ``InOutGroup`` is defined as: - -.. container:: codeset - - .. literalinclude:: ../../core/src/main/kotlin/net/corda/core/contracts/TransactionVerification.kt - :language: kotlin - :start-after: DOCSTART 3 - :end-before: DOCEND 3 - -For example, we could group the states in the transaction above by currency (i.e. by ``amount.token``): - -.. container:: codeset - - .. sourcecode:: kotlin - - val groups: List>> = tx.groupStates(Cash.State::class.java) { - it -> it.amount.token - } - - .. sourcecode:: java - - final List>> groups = tx.groupStates( - Cash.State.class, - it -> it.getAmount().getToken() - ); - -This would produce the following InOutGroups: - -.. image:: resources/in-out-groups.png - -We can now verify these groups individually: - -.. container:: codeset - - .. sourcecode:: kotlin - - for ((in_, out, key) in groups) { - when (key) { - is GBP -> { - // GBP verification logic. - } - is USD -> { - // USD verification logic. - } - } - } - - .. sourcecode:: java - - for (InOutGroup group : groups) { - if (group.getGroupingKey() == USD) { - // USD verification logic. - } else if (group.getGroupingKey() == GBP) { - // GBP verification logic. - } - } - -Legal prose ------------ - -Currently, a ``Contract`` subtype may refer to the legal prose it implements via a ``LegalProseReference`` annotation. -In the future, a contract's legal prose will be included as an attachment. + } \ No newline at end of file From 477dc4292111cd097413b4299a71ace4e85eb80f Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Fri, 22 Sep 2017 16:51:32 +0100 Subject: [PATCH 043/230] Andr3ej tutorial doc (#1593) Updated documentation: Tutorial --- docs/source/tutorial-cordapp.rst | 462 ++++++++++++++----------------- 1 file changed, 204 insertions(+), 258 deletions(-) diff --git a/docs/source/tutorial-cordapp.rst b/docs/source/tutorial-cordapp.rst index 086c146747..0aa499c45e 100644 --- a/docs/source/tutorial-cordapp.rst +++ b/docs/source/tutorial-cordapp.rst @@ -10,75 +10,80 @@ The example CorDapp .. contents:: The example CorDapp allows nodes to agree IOUs with each other. Nodes will always agree to the creation of a new IOU -unless: +if: -* Its value is less than 1, or greater than 99 -* A node tries to issue an IOU to itself +* Its value is strictly positive +* The node is not trying to issue the IOU to itself -By default, the CorDapp is deployed on 4 test nodes: +We will deploy the CorDapp on 4 test nodes: -* **Controller**, which hosts the network map service and validating notary service -* **NodeA** -* **NodeB** -* **NodeC** +* **Controller**, which hosts the network map service and a validating notary service +* **PartyA** +* **PartyB** +* **PartyC** -Because data is only propagated on a need-to-know basis, any IOUs agreed between NodeA and NodeB become "shared facts" -between NodeA and NodeB only. NodeC won't be aware of these IOUs. +Because data is only propagated on a need-to-know basis, any IOUs agreed between PartyA and PartyB become "shared +facts" between PartyA and PartyB only. PartyC won't be aware of these IOUs. Downloading the example CorDapp ------------------------------- -If you haven't already, set up your machine by following the :doc:`quickstart guide `. Then clone the -example CorDapp from the `cordapp-tutorial repository `_ using the following -command: +We need to download the example CorDapp from GitHub. -``git clone https://github.com/corda/cordapp-tutorial`` +* Set up your machine by following the :doc:`quickstart guide ` -And change directories to the freshly cloned repo: +* Clone the example CorDapp from the `cordapp-example repository `_ using + the following command: ``git clone https://github.com/corda/cordapp-example`` -``cd cordapp-tutorial`` +* Change directories to the freshly cloned repo: ``cd cordapp-example`` -We want to work off the latest Milestone release. To enumerate all the Milestone releases, run: +* We want to work off the latest Milestone release -``git tag`` + * To enumerate all the Milestone releases, run: ``git tag`` -And check out the latest (highest-numbered) Milestone release using: + * Check out the latest (highest-numbered) Milestone release using: ``git checkout [tag_name]`` -``git checkout [tag_name]`` + Where ``tag_name`` is the name of the tag you wish to checkout -Where ``tag_name`` is the name of the tag you wish to checkout. Gradle will grab all the required dependencies for you -from our `public Maven repository `_. + * Gradle will grab all the required dependencies for you from `Maven `_ .. note:: If you wish to build off the latest, unstable version of the codebase, follow the instructions in - `Using a SNAPSHOT release`_. + :doc:`building against Master ` instead. Opening the example CorDapp in IntelliJ --------------------------------------- -Let's open the example CorDapp in the IntelliJ IDE. +Let's open the example CorDapp in IntelliJ IDEA. -**For those completely new to IntelliJ** +**If opening a fresh IntelliJ instance** -Upon opening IntelliJ, a dialogue will appear: +* Open IntelliJ +* A dialogue box will appear: -.. image:: resources/intellij-welcome.png - :width: 400 + .. image:: resources/intellij-welcome.png + :width: 400 -Click open, then navigate to the folder where you cloned the ``cordapp-tutorial`` and click OK. +* Click open, navigate to the folder where you cloned the ``cordapp-example``, and click OK -Next, IntelliJ will show several pop-up windows, one of which requires our attention: +* IntelliJ will show several pop-up windows, one of which requires our attention: -.. image:: resources/unlinked-gradle-project.png - :width: 400 + .. image:: resources/unlinked-gradle-project.png + :width: 400 -Click the 'import gradle project' link. A dialogue will pop-up. Press OK. Gradle will now download all the -project dependencies and perform some indexing. This usually takes a minute or so. +* Click the 'import gradle project' link. Press OK on the dialogue that pops up -If the 'import gradle project' pop-up does not appear, click the small green speech bubble at the bottom-right of -the IDE, or simply close and re-open IntelliJ again to make it reappear. +* Gradle will now download all the project dependencies and perform some indexing. This usually takes a minute or so. + + * If the 'import gradle project' pop-up does not appear, click the small green speech bubble at the bottom-right of + the IDE, or simply close and re-open IntelliJ again to make it reappear. **If you already have IntelliJ open** -From the ``File`` menu, navigate to ``Open ...`` and then navigate to the directory where you cloned the -``cordapp-tutorial`` and click OK. +* Open the ``File`` menu + +* Navigate to ``Open ...`` + +* Navigate to the directory where you cloned the ``cordapp-example`` + +* Click OK Project structure ----------------- @@ -87,10 +92,6 @@ The example CorDapp has the following directory structure: .. sourcecode:: none . - ├── LICENCE - ├── README.md - ├── TRADEMARK - ├── build.gradle ├── config │   ├── dev │   │   └── log4j2.xml @@ -102,9 +103,9 @@ The example CorDapp has the following directory structure: │   └── wrapper │   ├── gradle-wrapper.jar │   └── gradle-wrapper.properties - ├── gradle.properties - ├── gradlew - ├── gradlew.bat + ├── lib + │   ├── README.txt + │   └── quasar.jar ├── java-source │   └── ... ├── kotlin-source @@ -151,27 +152,31 @@ The example CorDapp has the following directory structure: │   │   └── IOUContractTests.kt │   └── flow │   └── IOUFlowTests.kt - ├── lib - │   ├── README.txt - │   └── quasar.jar + ├── .gitignore + ├── LICENCE + ├── README.md + ├── TRADEMARK + ├── build.gradle + ├── gradle.properties + ├── gradlew + ├── gradlew.bat └── settings.gradle -The most important files and directories to note are: +The key files and directories are as follows: * The **root directory** contains some gradle files, a README and a LICENSE * **config** contains log4j configs * **gradle** contains the gradle wrapper, which allows the use of Gradle without installing it yourself and worrying about which version is required -* **lib** contains the Quasar jar which is required for runtime instrumentation of classes by Quasar +* **lib** contains the Quasar jar which rewrites our CorDapp's flows to be checkpointable * **kotlin-source** contains the source code for the example CorDapp written in Kotlin * **kotlin-source/src/main/kotlin** contains the source code for the example CorDapp - * **kotlin-source/src/main/python** contains a python script which accesses nodes via RPC * **kotlin-source/src/main/resources** contains the certificate store, some static web content to be served by the nodes and the WebServerPluginRegistry file * **kotlin-source/src/test/kotlin** contains unit tests for the contracts and flows, and the driver to run the nodes via IntelliJ -* **java-source** contains the same source code, but written in java. This is an aid for users who do not want to - develop in Kotlin, and serves as an example of how CorDapps can be developed in any language targeting the JVM +* **java-source** contains the same source code, but written in Java. CorDapps can be developed in any language + targeting the JVM Running the example CorDapp --------------------------- @@ -180,49 +185,57 @@ There are two ways to run the example CorDapp: * Via the terminal * Via IntelliJ -We explain both below. +In both cases, we will deploy a set of test nodes with our CorDapp installed, then run the nodes. You can read more +about how we define the nodes to be deployed :doc:`here `. -Terminal: Building the example CorDapp -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Return to your terminal window and make sure you are in the ``cordapp-tutorial`` directory. To build the example -CorDapp use the following command: +Terminal +~~~~~~~~ -* Unix/Mac OSX: ``./gradlew deployNodes`` -* Windows: ``gradlew.bat deployNodes`` +Building the example CorDapp +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +* Open a terminal window in the ``cordapp-example`` directory -This will package up our CorDapp source files into a plugin and automatically build four pre-configured nodes that have -our CorDapp plugin installed. These nodes are meant for local testing only. +* Build the test nodes with our CorDapp using the following command: -After the build process has finished, you will see the newly-build nodes in the ``kotlin-source/build/nodes``. There -will be one folder generated for each node you built, plus a ``runnodes`` shell script (or batch file on Windows). + * Unix/Mac OSX: ``./gradlew deployNodes`` + + * Windows: ``gradlew.bat deployNodes`` + + This will automatically build four pre-configured nodes with our CorDapp installed. These nodes are meant for local + testing only .. note:: CorDapps can be written in any language targeting the JVM. In our case, we've provided the example source in both Kotlin (``/kotlin-source/src``) and Java (``/java-source/src``) Since both sets of source files are functionally identical, we will refer to the Kotlin build throughout the documentation. -Each node in the ``nodes`` folder has the following structure: +* After the build process has finished, you will see the newly-build nodes in the ``kotlin-source/build/nodes`` folder -.. sourcecode:: none + * There will be one folder generated for each node you built, plus a ``runnodes`` shell script (or batch file on + Windows) to run all the nodes simultaneously - . nodeName - ├── corda.jar - ├── node.conf - └── plugins + * Each node in the ``nodes`` folder has the following structure: -``corda.jar` is the Corda runtime, ``plugins`` contains our node's CorDapps, and our node's configuration is provided -in ``node.conf``. + .. sourcecode:: none -Terminal: Running the example CorDapp -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To run our nodes, run the following command from the root of the ``cordapp-tutorial`` folder: + . nodeName + ├── corda.jar + ├── node.conf + └── plugins + + ``corda.jar`` is the Corda runtime, ``plugins`` contains our node's CorDapps, and the node's configuration is + given by ``node.conf`` + +Running the example CorDapp +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Start the nodes by running the following command from the root of the ``cordapp-example`` folder: * Unix/Mac OSX: ``kotlin-source/build/nodes/runnodes`` * Windows: ``call kotlin-source\build\nodes\runnodes.bat`` -On Unix/Mac OSX, do not click/change focus until all eight additional terminal windows have opened, or some nodes may -fail to start. +.. warn:: On Unix/Mac OSX, do not click/change focus until all seven additional terminal windows have opened, or some + nodes may fail to start. -The ``runnodes`` script creates a terminal tab/window for each node: +For each node, the ``runnodes`` script creates a node tab/window: .. sourcecode:: none @@ -236,12 +249,12 @@ The ``runnodes`` script creates a terminal tab/window for each node: 📚 New! Training now available worldwide, see https://corda.net/corda-training/ - Logs can be found in : /Users/joeldudley/Desktop/cordapp-tutorial/kotlin-source/build/nodes/NodeA/logs + Logs can be found in : /Users/joeldudley/Desktop/cordapp-example/kotlin-source/build/nodes/PartyA/logs Database connection url is : jdbc:h2:tcp://10.163.199.132:54763/node Listening on address : 127.0.0.1:10005 RPC service listening on address : localhost:10006 Loaded plugins : com.example.plugin.ExamplePlugin - Node for "NodeA" started up and registered in 35.0 sec + Node for "PartyA" started up and registered in 35.0 sec Welcome to the Corda interactive shell. @@ -249,67 +262,69 @@ The ``runnodes`` script creates a terminal tab/window for each node: Fri Jul 07 10:33:47 BST 2017>>> -The script will also create a webserver terminal tab for each node: +For every node except the controller, the script also creates a webserver terminal tab/window: .. sourcecode:: none - Logs can be found in /Users/joeldudley/Desktop/cordapp-tutorial/kotlin-source/build/nodes/NodeA/logs/web + Logs can be found in /Users/joeldudley/Desktop/cordapp-example/kotlin-source/build/nodes/PartyA/logs/web Starting as webserver: localhost:10007 Webserver started up in 42.02 sec -Depending on your machine, it usually takes around 60 seconds for the nodes to finish starting up. If you want to -ensure that all the nodes are running OK, you can query the 'status' end-point located at -``http://localhost:[port]/api/status`` (e.g. ``http://localhost:10007/api/status`` for ``NodeA``). +It usually takes around 60 seconds for the nodes to finish starting up. To ensure that all the nodes are running OK, +you can query the 'status' end-point located at ``http://localhost:[port]/api/status`` (e.g. +``http://localhost:10007/api/status`` for ``PartyA``). -IntelliJ: Building and running the example CorDapp -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -To run the example CorDapp via IntelliJ you can use the ``Run Example CorDapp - Kotlin`` run configuration. Select it -from the drop-down menu at the top right-hand side of the IDE and press the green arrow to start the nodes: +IntelliJ +~~~~~~~~ +* Select the ``Run Example CorDapp - Kotlin`` run configuration from the drop-down menu at the top right-hand side of + the IDE -.. image:: resources/run-config-drop-down.png - :width: 400 +* Click the green arrow to start the nodes: -The node driver defined in ``/src/test/kotlin/com/example/Main.kt`` allows you to specify how many nodes you would like -to run and the configuration settings for each node. With the example CorDapp, the driver starts up four nodes -and adds an RPC user for all but the "Controller" node (which serves as the notary and network map service): + .. image:: resources/run-config-drop-down.png + :width: 400 -.. sourcecode:: kotlin + The node driver defined in ``/src/test/kotlin/com/example/Main.kt`` allows you to specify how many nodes you would like + to run and the configuration settings for each node. For the example CorDapp, the driver starts up four nodes + and adds an RPC user for all but the "Controller" node (which serves as the notary and network map service): - fun main(args: Array) { - // No permissions required as we are not invoking flows. - val user = User("user1", "test", permissions = setOf()) - driver(isDebug = true) { - startNode(getX500Name(O="Controller",OU="corda",L="London",C='UK"), setOf(ServiceInfo(ValidatingNotaryService.type))) - val (nodeA, nodeB, nodeC) = Futures.allAsList( - startNode(getX500Name(O="NodeA",L="London",C="UK"), rpcUsers = listOf(user)), - startNode(getX500Name(O="NodeB",L="New York",C="US"), rpcUsers = listOf(user)), - startNode(getX500Name(O="NodeC",L="Paris",C="FR"), rpcUsers = listOf(user))).getOrThrow() + .. sourcecode:: kotlin - startWebserver(nodeA) - startWebserver(nodeB) - startWebserver(nodeC) + fun main(args: Array) { + // No permissions required as we are not invoking flows. + val user = User("user1", "test", permissions = setOf()) + driver(isDebug = true) { + startNode(getX500Name(O="Controller",L="London",C='GB"), setOf(ServiceInfo(ValidatingNotaryService.type))) + val (nodeA, nodeB, nodeC) = Futures.allAsList( + startNode(getX500Name(O="PartyA",L="London",C="GB"), rpcUsers = listOf(user)), + startNode(getX500Name(O="PartyB",L="New York",C="US"), rpcUsers = listOf(user)), + startNode(getX500Name(O="PartyC",L="Paris",C="FR"), rpcUsers = listOf(user))).getOrThrow() - waitForAllNodesToFinish() - } - } + startWebserver(nodeA) + startWebserver(nodeB) + startWebserver(nodeC) -To stop the nodes, press the red square button at the top right-hand side of the IDE, next to the run configurations. + waitForAllNodesToFinish() + } + } -We'll look later at how the node driver can be useful for `debugging your CorDapp`_. +* To stop the nodes, press the red square button at the top right-hand side of the IDE, next to the run configurations + +Later, we'll look at how the node driver can be useful for `debugging your CorDapp`_. Interacting with the example CorDapp ------------------------------------ Via HTTP ~~~~~~~~ -The CorDapp defines several HTTP API end-points and a web front-end. The end-points allow you to list your existing -IOUs, agree new IOUs, and see who is on the network. +The CorDapp defines several HTTP API end-points and a web front-end. The end-points allow you to list the IOUs a node +is involved in, agree new IOUs, and see who is on the network. The nodes are running locally on the following ports: -* NodeA: ``localhost:10007`` -* NodeB: ``localhost:10010`` -* NodeC: ``localhost:10013`` +* PartyA: ``localhost:10007`` +* PartyB: ``localhost:10010`` +* PartyC: ``localhost:10013`` These ports are defined in build.gradle and in each node's node.conf file under ``kotlin-source/build/nodes/NodeX``. @@ -329,22 +344,22 @@ the web form hosted at ``/web/example``. .. warning:: The content in ``web/example`` is only available for demonstration purposes and does not implement anti-XSS, anti-XSRF or any other security techniques. Do not use this code in production. -**Creating an IOU via the HTTP API:** - -To create an IOU between NodeA and NodeB, we would run the following from the command line: +Creating an IOU via the endpoint +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To create an IOU between PartyA and PartyB, run the following command from the command line: .. sourcecode:: bash - echo '{"value": "1"}' | cURL -T - -H 'Content-Type: application/json' http://localhost:10007/api/example/NodeB/create-iou + curl -X PUT 'http://localhost:10007/api/example/create-iou?iouValue=1&partyName=O=PartyB,L=New%20York,C=US' -Note that both NodeA's port number (``10007``) and NodeB are referenced in the PUT request path. This command instructs -NodeA to agree an IOU with NodeB. Once the process is complete, both nodes will have a signed, notarised copy of the -IOU. NodeC will not. +Note that both PartyA's port number (``10007``) and PartyB are referenced in the PUT request path. This command +instructs PartyA to agree an IOU with PartyB. Once the process is complete, both nodes will have a signed, notarised +copy of the IOU. PartyC will not. -**Submitting an IOU via the web front-end:** - -Navigate to ``/web/example``, click the "create IOU" button at the top-left of the page, and enter the IOU details into -the web-form. The IOU must have a value of between 1 and 99. +Submitting an IOU via the web front-end +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +To create an IOU between PartyA and PartyB, navigate to ``/web/example``, click the "create IOU" button at the top-left +of the page, and enter the IOU details into the web-form. The IOU must have a positive value. For example: .. sourcecode:: none @@ -353,45 +368,43 @@ the web-form. The IOU must have a value of between 1 and 99. And click submit. Upon clicking submit, the modal dialogue will close, and the nodes will agree the IOU. -**Once an IOU has been submitted:** - -Assuming all went well, you should see some activity in NodeA's web-server terminal window: +Once an IOU has been submitted +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +Assuming all went well, you should see some activity in PartyA's web-server terminal window: .. sourcecode:: none - >> Generating transaction based on new IOU. - >> Verifying contract constraints. - >> Signing transaction with our private key. - >> Gathering the counterparty's signature. - >> Structural step change in child of Gathering the counterparty's signature. - >> Collecting signatures from counter-parties. - >> Verifying collected signatures. - >> Done - >> Obtaining notary signature and recording transaction. - >> Structural step change in child of Obtaining notary signature and recording transaction. - >> Requesting signature by notary service - >> Broadcasting transaction to participants - >> Done - >> Done + >> Signing transaction with our private key. + >> Gathering the counterparty's signature. + >> Structural step change in child of Gathering the counterparty's signature. + >> Collecting signatures from counter-parties. + >> Verifying collected signatures. + >> Done + >> Obtaining notary signature and recording transaction. + >> Structural step change in child of Obtaining notary signature and recording transaction. + >> Requesting signature by notary service + >> Broadcasting transaction to participants + >> Done + >> Done -You can view the newly-created IOU by accessing the vault of NodeA or NodeB: +You can view the newly-created IOU by accessing the vault of PartyA or PartyB: *Via the HTTP API:* -* NodeA's vault: Navigate to http://localhost:10007/api/example/ious -* NodeB's vault: Navigate to http://localhost:10010/api/example/ious +* PartyA's vault: Navigate to http://localhost:10007/api/example/ious +* PartyB's vault: Navigate to http://localhost:10010/api/example/ious *Via web/example:* -* NodeA: Navigate to http://localhost:10007/web/example and hit the "refresh" button -* NodeA: Navigate to http://localhost:10010/web/example and hit the "refresh" button +* PartyA: Navigate to http://localhost:10007/web/example and hit the "refresh" button +* PartyA: Navigate to http://localhost:10010/web/example and hit the "refresh" button -If you access the vault or web front-end of NodeC (on ``localhost:10013``), there will be no IOUs. This is because -NodeC was not involved in this transaction. +The vault and web front-end of PartyC (on ``localhost:10013``) will not display any IOUs. This is because PartyC was +not involved in this transaction. Via the interactive shell (terminal only) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Once a node has been started via the terminal, it will display an interactive shell: +Nodes started via the terminal will display an interactive shell: .. sourcecode:: none @@ -400,19 +413,22 @@ Once a node has been started via the terminal, it will display an interactive sh Fri Jul 07 16:36:29 BST 2017>>> -You can see a list of the flows that your node can run using `flow list`. In our case, this will return the following -list: +Type ``flow list`` in the shell to see a list of the flows that your node can run. In our case, this will return the +following list: .. sourcecode:: none - com.example.flow.ExampleFlow$Initiator - net.corda.finance.flows.CashExitFlow - net.corda.finance.flows.CashIssueFlow - net.corda.finance.flows.CashPaymentFlow - net.corda.finance.flows.ContractUpgradeFlow + com.example.flow.ExampleFlow$Initiator + net.corda.core.flows.ContractUpgradeFlow$Initiator + net.corda.core.flows.ContractUpgradeFlow$Initiator + net.corda.finance.flows.CashExitFlow + net.corda.finance.flows.CashIssueAndPaymentFlow + net.corda.finance.flows.CashIssueFlow + net.corda.finance.flows.CashPaymentFlow -We can create a new IOU using the ``ExampleFlow$Initiator`` flow. For example, from the interactive shell of NodeA, you -can agree an IOU of 50 with NodeB by running ``flow start Initiator iouValue: 50, otherParty: NodeB``. +We can create a new IOU using the ``ExampleFlow$Initiator`` flow. For example, from the interactive shell of PartyA, +you can agree an IOU of 50 with PartyB by running +``flow start ExampleFlow$Initiator iouValue: 50, otherParty: "O=PartyB,L=New York,C=US"``. This will print out the following progress steps: @@ -434,82 +450,6 @@ This will print out the following progress steps: We can also issue RPC operations to the node via the interactive shell. Type ``run`` to see the full list of available operations. -We can see a list of the states in our node's vault using ``run vaultAndUpdates``: - -.. sourcecode:: none - - --- - first: - - state: - data: - iou: - value: 50 - sender: "CN=NodeB,O=NodeB,L=New York,C=US" - recipient: "CN=NodeA,O=NodeA,L=London,C=UK" - linearId: - externalId: null - id: "84628565-2688-45ef-bb06-aae70fcf3be7" - contract: {} - participants: - - "CN=NodeB,O=NodeB,L=New York,C=US" - - "CN=NodeA,O=NodeA,L=London,C=UK" - notary: "O=Controller,OU=corda,L=London,C=UK,OU=corda.notary.validating" - encumbrance: null - ref: - txhash: "52A1B18E6ABD535EF36B2075469B01D2EF888034F721C4BECD26F40355C8C9DC" - index: 0 - second: "(observable)" - -We can also see the transactions stored in our node's local storage using ``run verifiedTransactions`` (we've -abbreviated the output below): - -.. sourcecode:: none - - first: - - txBits: "Y29yZGEAAAEOAQEAamF2YS51dGlsLkFycmF5TGlz9AABAAABAAEBAW5ldC5jb3JkYS5jb3JlLmNvbnRyYWN0cy5UcmFuc2FjdGlvblN0YXTlA1RyYW5zYWN0aW9uU3RhdGUuZGF04VRyYW5zYWN0aW9uU3RhdGUuZW5jdW1icmFuY+VUcmFuc2FjdGlvblN0YXRlLm5vdGFy+WkBAmNvbS5leGFtcGxlLnN0YXRlLklPVVN0YXTlBElPVVN0YXRlLmlv9UlPVVN0YXRlLmxpbmVhcknkSU9VU3RhdGUucmVjaXBpZW70SU9VU3RhdGUuc2VuZGXyDQEBSU9VLnZhbHXlAWQCAQA0ADIBAlVuaXF1ZUlkZW50aWZpZXIuZXh0ZXJuYWxJ5FVuaXF1ZUlkZW50aWZpZXIuaeQBgDAvAC0BAlVVSUQubGVhc3RTaWdCaXTzVVVJRC5tb3N0U2lnQml08wmxkIaDnsaq+YkNDAsACaHovZfbpr2d9wMCAQACAQBIAEYBAkFic3RyYWN0UGFydHkub3duaW5nS2X5UGFydHkubmFt5SIuIOnhdbFQY3EL/LQD90w6y+kCfj4x8UWXaqKtW68GBPlnREMAQTkwPjEOMAwGA1UEAwwFTm9kZUExDjAMBgNVBAoMBU5vZGVBMQ8wDQYDVQQHDAZMb25kb24xCzAJBgNVBAYTAlVLAgEAJgAkASIuIHI7goTSxPMdaRgJgGJVLQbFEzE++qJeYbEbQjrYxzuVRkUAQzkwQDEOMAwGA1UEAwwFTm9kZUIxDjAMBgNVBAoMBU5vZGVCMREwDwYDVQQHDAhOZXcgWW9yazELMAkGA1UEBhMCVVMCAQABAAABAAAkASIuIMqulslvpZ0PaM6fdyFZm+JsDGkuJ7xWnL3zB6PqpzANdwB1OTByMRMwEQYDVQQDDApDb250cm9sbGVyMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGExDzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUsxIDAeBgNVBAsMF2NvcmRhLm5vdGFyeS52YWxpZGF0aW5nAQAAAQABAQNuZXQuY29yZGEuY29yZS5jb250cmFjdHMuQ29tbWFu5AJDb21tYW5kLnNpZ25lcvNDb21tYW5kLnZhbHXlRwEAAi4gcjuChNLE8x1pGAmAYlUtBsUTMT76ol5hsRtCOtjHO5UuIOnhdbFQY3EL/LQD90w6y+kCfj4x8UWXaqKtW68GBPlnADMBBGNvbS5leGFtcGxlLmNvbnRyYWN0LklPVUNvbnRyYWN0JENvbW1hbmRzJENyZWF05QAAAQVuZXQuY29yZGEuY29yZS5pZGVudGl0eS5QYXJ0+SIuIMqulslvpZ0PaM6fdyFZm+JsDGkuJ7xWnL3zB6PqpzANAHU5MHIxEzARBgNVBAMMCkNvbnRyb2xsZXIxCzAJBgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYDVQQGEwJVSzEgMB4GA1UECwwXY29yZGEubm90YXJ5LnZhbGlkYXRpbmcAAQACLiByO4KE0sTzHWkYCYBiVS0GxRMxPvqiXmGxG0I62Mc7lS4g6eF1sVBjcQv8tAP3TDrL6QJ+PjHxRZdqoq1brwYE+WcBBm5ldC5jb3JkYS5jb3JlLmNvbnRyYWN0cy5UcmFuc2FjdGlvblR5cGUkR2VuZXJh7AA=" - sigs: - - "cRgJlF8cUMMooyaV2OIKmR4/+3XmMsEPsbdlhU5YqngRhqgy9+tLzylh7kvWOhYZ4hjjOfrazLoZ6uOx6BAMCQ==" - - "iGLRDIbhlwguMz6yayX5p6vfQcAsp8haZc1cLGm7DPDIgq6hFyx2fzoI03DjXAV/mBT1upcUjM9UZ4gbRMedAw==" - id: "52A1B18E6ABD535EF36B2075469B01D2EF888034F721C4BECD26F40355C8C9DC" - tx: - inputs: [] - attachments: [] - outputs: - - data: - iou: - value: 50 - sender: "CN=NodeB,O=NodeB,L=New York,C=US" - recipient: "CN=NodeA,O=NodeA,L=London,C=UK" - linearId: - externalId: null - id: "84628565-2688-45ef-bb06-aae70fcf3be7" - contract: {} - participants: - - "CN=NodeB,O=NodeB,L=New York,C=US" - - "CN=NodeA,O=NodeA,L=London,C=UK" - notary: "O=Controller,OU=corda,L=London,C=UK,OU=corda.notary.validating" - encumbrance: null - commands: - - value: {} - signers: - - "8Kqd4oWdx4KQAVc3u5qvHZTGJxMtrShFudAzLUTdZUzbF9aPQcCZD5KXViC" - - "8Kqd4oWdx4KQAVcBx98LBHwXwC3a7hNptQomrg9mq2ScY7t1Qqsyk5dCNAr" - notary: "O=Controller,OU=corda,L=London,C=UK,OU=corda.notary.validating" - type: {} - timeWindow: null - mustSign: - - "8Kqd4oWdx4KQAVc3u5qvHZTGJxMtrShFudAzLUTdZUzbF9aPQcCZD5KXViC" - - "8Kqd4oWdx4KQAVcBx98LBHwXwC3a7hNptQomrg9mq2ScY7t1Qqsyk5dCNAr" - id: "52A1B18E6ABD535EF36B2075469B01D2EF888034F721C4BECD26F40355C8C9DC" - merkleTree: ... - availableComponents: ... - availableComponentHashes: ... - serialized: "Y29yZGEAAAEOAQEAamF2YS51dGlsLkFycmF5TGlz9AABAAABAAEBAW5ldC5jb3JkYS5jb3JlLmNvbnRyYWN0cy5UcmFuc2FjdGlvblN0YXTlA1RyYW5zYWN0aW9uU3RhdGUuZGF04VRyYW5zYWN0aW9uU3RhdGUuZW5jdW1icmFuY+VUcmFuc2FjdGlvblN0YXRlLm5vdGFy+WkBAmNvbS5leGFtcGxlLnN0YXRlLklPVVN0YXTlBElPVVN0YXRlLmlv9UlPVVN0YXRlLmxpbmVhcknkSU9VU3RhdGUucmVjaXBpZW70SU9VU3RhdGUuc2VuZGXyDQEBSU9VLnZhbHXlAWQCAQA0ADIBAlVuaXF1ZUlkZW50aWZpZXIuZXh0ZXJuYWxJ5FVuaXF1ZUlkZW50aWZpZXIuaeQBgDAvAC0BAlVVSUQubGVhc3RTaWdCaXTzVVVJRC5tb3N0U2lnQml08wmxkIaDnsaq+YkNDAsACaHovZfbpr2d9wMCAQACAQBIAEYBAkFic3RyYWN0UGFydHkub3duaW5nS2X5UGFydHkubmFt5SIuIOnhdbFQY3EL/LQD90w6y+kCfj4x8UWXaqKtW68GBPlnREMAQTkwPjEOMAwGA1UEAwwFTm9kZUExDjAMBgNVBAoMBU5vZGVBMQ8wDQYDVQQHDAZMb25kb24xCzAJBgNVBAYTAlVLAgEAJgAkASIuIHI7goTSxPMdaRgJgGJVLQbFEzE++qJeYbEbQjrYxzuVRkUAQzkwQDEOMAwGA1UEAwwFTm9kZUIxDjAMBgNVBAoMBU5vZGVCMREwDwYDVQQHDAhOZXcgWW9yazELMAkGA1UEBhMCVVMCAQABAAABAAAkASIuIMqulslvpZ0PaM6fdyFZm+JsDGkuJ7xWnL3zB6PqpzANdwB1OTByMRMwEQYDVQQDDApDb250cm9sbGVyMQswCQYDVQQKDAJSMzEOMAwGA1UECwwFY29yZGExDzANBgNVBAcMBkxvbmRvbjELMAkGA1UEBhMCVUsxIDAeBgNVBAsMF2NvcmRhLm5vdGFyeS52YWxpZGF0aW5nAQAAAQABAQNuZXQuY29yZGEuY29yZS5jb250cmFjdHMuQ29tbWFu5AJDb21tYW5kLnNpZ25lcvNDb21tYW5kLnZhbHXlRwEAAi4gcjuChNLE8x1pGAmAYlUtBsUTMT76ol5hsRtCOtjHO5UuIOnhdbFQY3EL/LQD90w6y+kCfj4x8UWXaqKtW68GBPlnADMBBGNvbS5leGFtcGxlLmNvbnRyYWN0LklPVUNvbnRyYWN0JENvbW1hbmRzJENyZWF05QAAAQVuZXQuY29yZGEuY29yZS5pZGVudGl0eS5QYXJ0+SIuIMqulslvpZ0PaM6fdyFZm+JsDGkuJ7xWnL3zB6PqpzANAHU5MHIxEzARBgNVBAMMCkNvbnRyb2xsZXIxCzAJBgNVBAoMAlIzMQ4wDAYDVQQLDAVjb3JkYTEPMA0GA1UEBwwGTG9uZG9uMQswCQYDVQQGEwJVSzEgMB4GA1UECwwXY29yZGEubm90YXJ5LnZhbGlkYXRpbmcAAQACLiByO4KE0sTzHWkYCYBiVS0GxRMxPvqiXmGxG0I62Mc7lS4g6eF1sVBjcQv8tAP3TDrL6QJ+PjHxRZdqoq1brwYE+WcBBm5ldC5jb3JkYS5jb3JlLmNvbnRyYWN0cy5UcmFuc2FjdGlvblR5cGUkR2VuZXJh7AA=" - second: "(observable)" - -The same states and transactions will be present on NodeB, who was NodeA's counterparty in the creation of the IOU. -However, the vault and local storage of NodeC will remain empty, since NodeC was not involved in the transaction. - Via the h2 web console ~~~~~~~~~~~~~~~~~~~~~~ You can connect directly to your node's database to see its stored states, transactions and attachments. To do so, @@ -523,14 +463,16 @@ any IOUs when you first connect to one of the nodes, the client will simply log *Running the client via IntelliJ:* -Select the 'Run Example RPC Client' run configuration which, by default, connects to NodeA (Artemis port 10007). Click the -Green Arrow to run the client. You can edit the run configuration to connect on a different port. +Select the 'Run Example RPC Client' run configuration which, by default, connects to PartyA. Click the green arrow to +run the client. You can edit the run configuration to connect on a different port. *Running the client via the command line:* Run the following gradle task: -``./gradlew runExampleClientRPCKotlin localhost:10007`` +``./gradlew runExampleClientRPCKotlin`` + +This will connect the RPC client to PartyA and log their past and future IOU activity. You can close the application using ``ctrl+C``. @@ -541,12 +483,12 @@ For more information on the client RPC interface and how to build an RPC client Running Nodes Across Machines ----------------------------- -The nodes can also be configured to communicate across the network when residing on different machines. +The nodes can be split across machines and configured to communicate across the network. -After deploying the nodes, navigate to the build folder (``kotlin-source/build/nodes`` or ``java-source/build/nodes``) -and move some of the individual node folders to separate machines (e.g. using a USB key). It is important that none of -the nodes - including the controller node - end up on more than one machine. Each computer should also have a copy of -``runnodes`` and ``runnodes.bat``. +After deploying the nodes, navigate to the build folder (``kotlin-source/build/nodes``) and move some of the individual +node folders to a different machine (e.g. using a USB key). It is important that none of the nodes - including the +controller node - end up on more than one machine. Each computer should also have a copy of ``runnodes`` and +``runnodes.bat``. For example, you may end up with the following layout: @@ -558,18 +500,18 @@ and make the following changes: * Change the Artemis messaging address to the machine's IP address (e.g. ``p2pAddress="10.18.0.166:10006"``) * Change the network map service's address to the IP address of the machine where the controller node is running - (e.g. ``networkMapService { address="10.18.0.166:10002" ...``). The controller will not have the - ``networkMapService`` config + (e.g. ``networkMapService { address="10.18.0.166:10002" legalName="O=Controller,L=London,C=GB" ``). The controller + will not have the ``networkMapService`` configuration entry -After starting each node, they should be able to see one another and agree IOUs among themselves. +After starting each node, the nodes will be able to see one another and agree IOUs among themselves. Debugging your CorDapp ---------------------- Debugging is done via IntelliJ as follows: -1. Edit the node driver code in ``Main.kt`` to reflect the number of nodes you wish to start, along with any other - configuration options. For example, the code below starts 4 nodes, with one being the network map service and notary. - It also sets up RPC credentials for the three non-notary nodes +1. Edit the node driver code in ``Main.kt`` based on the number of nodes you wish to start, along with any other + configuration options. For example, the code below starts 4 nodes, with one being the network map service and + notary. It also sets up RPC credentials for the three non-notary nodes .. sourcecode:: kotlin @@ -577,11 +519,11 @@ Debugging is done via IntelliJ as follows: // No permissions required as we are not invoking flows. val user = User("user1", "test", permissions = setOf()) driver(isDebug = true) { - startNode(getX500Name(O="Controller",OU="corda",L="London",C="UK"), setOf(ServiceInfo(ValidatingNotaryService.type))) + startNode(getX500Name(O="Controller",L="London",C="GB"), setOf(ServiceInfo(ValidatingNotaryService.type))) val (nodeA, nodeB, nodeC) = Futures.allAsList( - startNode(getX500Name(O="NodeA",L=London,C=UK"), rpcUsers = listOf(user)), - startNode(getX500Name(O="NodeB",L=New York,C=US"), rpcUsers = listOf(user)), - startNode(getX500Name(O="NodeC",L=Paris,C=FR"), rpcUsers = listOf(user))).getOrThrow() + startNode(getX500Name(O="PartyA",L=London,C=GB"), rpcUsers = listOf(user)), + startNode(getX500Name(O="PartyB",L=New York,C=US"), rpcUsers = listOf(user)), + startNode(getX500Name(O="PartyC",L=Paris,C=FR"), rpcUsers = listOf(user))).getOrThrow() startWebserver(nodeA) startWebserver(nodeB) @@ -592,14 +534,18 @@ Debugging is done via IntelliJ as follows: } 2. Select and run the “Run Example CorDapp” run configuration in IntelliJ + 3. IntelliJ will build and run the CorDapp. The remote debug ports for each node will be automatically generated and printed to the terminal. For example: .. sourcecode:: none - [INFO ] 15:27:59.533 [main] Node.logStartupInfo - Working Directory: /Users/joeldudley/cordapp-tutorial/build/20170707142746/NodeA + [INFO ] 15:27:59.533 [main] Node.logStartupInfo - Working Directory: /Users/joeldudley/cordapp-example/build/20170707142746/PartyA [INFO ] 15:27:59.533 [main] Node.logStartupInfo - Debug port: dt_socket:5007 4. Edit the “Debug CorDapp” run configuration with the port of the node you wish to connect to + 5. Run the “Debug CorDapp” run configuration -6. Set your breakpoints and start using your node. When your node hits a breakpoint, execution will pause + +6. Set your breakpoints and start interacting with the node you wish to connect to. When the node hits a breakpoint, + execution will pause \ No newline at end of file From 095d94f2c7c6c4983ca45e2bfcf3a7d9633e7cab Mon Sep 17 00:00:00 2001 From: Joel Dudley Date: Fri, 22 Sep 2017 17:11:22 +0100 Subject: [PATCH 044/230] Updates key types page. (#1616) * Updates key types page. * Adds ToC. * Addresses review feedback. --- .../net/corda/core/contracts/Structures.kt | 2 + docs/source/api-core-types.rst | 93 +++++++------------ 2 files changed, 34 insertions(+), 61 deletions(-) diff --git a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt index dfad6a6e89..31e2151dd9 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/Structures.kt @@ -15,10 +15,12 @@ import net.corda.core.utilities.OpaqueBytes import java.security.PublicKey import java.time.Instant +// DOCSTART 1 /** Implemented by anything that can be named by a secure hash value (e.g. transactions, attachments). */ interface NamedByHash { val id: SecureHash } +// DOCEND 1 /** * The [Issued] data class holds the details of an on ledger digital asset. diff --git a/docs/source/api-core-types.rst b/docs/source/api-core-types.rst index 31593f990a..e69c5d858d 100644 --- a/docs/source/api-core-types.rst +++ b/docs/source/api-core-types.rst @@ -1,61 +1,48 @@ API: Core types =============== -Corda provides a large standard library of data types used to represent the Corda data model. In addition, there are a -series of helper libraries which provide date manipulation, maths and cryptography functions. +.. contents:: -Cryptography and maths support ------------------------------- -The ``SecureHash`` class represents a secure hash of unknown algorithm. We currently define only a single subclass, -``SecureHash.SHA256``. There are utility methods to create them, parse them and so on. +Corda provides several more core classes as part of its API. -We also provide some mathematical utilities, in particular a set of interpolators and classes for working with -splines. These can be found in the `maths package `_. +SecureHash +---------- +The ``SecureHash`` class is used to uniquely identify objects such as transactions and attachments by their hash. +Any object that needs to be identified by its hash should implement the ``NamedByHash`` interface: -NamedByHash and UniqueIdentifier --------------------------------- -Things which are identified by their hash, like transactions and attachments, should implement the ``NamedByHash`` -interface which standardises how the ID is extracted. Note that a hash is *not* a globally unique identifier: it -is always a derivative summary of the contents of the underlying data. Sometimes this isn't what you want: -two deals that have exactly the same parameters and which are made simultaneously but which are logically different -can't be identified by hash because their contents would be identical. +.. container:: codeset -Instead you would use ``UniqueIdentifier``. This is a combination of a (Java) ``UUID`` representing a globally -unique 128 bit random number, and an arbitrary string which can be paired with it. For instance the string may -represent an existing "weak" (not guaranteed unique) identifier for convenience purposes. + .. literalinclude:: ../../core/src/main/kotlin/net/corda/core/contracts/Structures.kt + :language: kotlin + :start-after: DOCSTART 1 + :end-before: DOCEND 1 -Party and CompositeKey ----------------------- -Entities using the network are called *parties*. Parties can sign structures using keys, and a party may have many -keys under their control. +``SecureHash`` is a sealed class that only defines a single subclass, ``SecureHash.SHA256``. There are utility methods +to create and parse ``SecureHash.SHA256`` objects. -Parties can be represented either in full (including name) or pseudonymously, using the ``Party`` or ``AnonymousParty`` -classes respectively. For example, in a transaction sent to your node as part of a chain of custody it is important you -can convince yourself of the transaction's validity, but equally important that you don't learn anything about who was -involved in that transaction. In these cases ``AnonymousParty`` should be used, which contains a public key (may be a composite key) -without any identifying information about who owns it. In contrast, for internal processing where extended details of -a party are required, the ``Party`` class should be used. The identity service provides functionality for resolving -anonymous parties to full parties. +Party +----- +Identities on the network are represented by ``AbstractParty``. There are two types of ``AbstractParty``: -.. note:: These types are provisional and will change significantly in future as the identity framework becomes more -fleshed out. +* ``Party``, identified by a ``PublicKey`` and a ``CordaX500Name`` -CommandWithParties ------------------- -A ``CommandWithParties`` represents a command and the list of associated signers' identities. +* ``AnonymousParty``, identified by a ``PublicKey`` -Multi-signature support ------------------------ -Corda supports scenarios where more than one key or party is required to authorise a state object transition, for example: +For example, in a transaction sent to your node as part of a chain of custody it is important you can convince yourself +of the transaction's validity, but equally important that you don't learn anything about who was involved in that +transaction. In these cases ``AnonymousParty`` should be used. In contrast, for internal processing where extended +details of a party are required, the ``Party`` class should be used. The identity service provides functionality for +resolving anonymous parties to full parties. + +CompositeKey +------------ +Corda supports scenarios where more than one signature is required to authorise a state object transition. For example: "Either the CEO or 3 out of 5 of his assistants need to provide signatures". -.. _composite-keys: - -Composite Keys -^^^^^^^^^^^^^^ -This is achieved by public key composition, using a tree data structure ``CompositeKey``. A ``CompositeKey`` is a tree that -stores the cryptographic public key primitives in its leaves and the composition logic in the intermediary nodes. Every intermediary -node specifies a *threshold* of how many child signatures it requires. +This is achieved using a ``CompositeKey``, which uses public-key composition to organise the various public keys into a +tree data structure. A ``CompositeKey`` is a tree that stores the cryptographic public key primitives in its leaves and +the composition logic in the intermediary nodes. Every intermediary node specifies a *threshold* of how many child +signatures it requires. An illustration of an *"either Alice and Bob, or Charlie"* composite key: @@ -70,25 +57,9 @@ then specifies the minimum total weight of all children required. Our previous e :align: center :width: 300px -Verification -^^^^^^^^^^^^ Signature verification is performed in two stages: 1. Given a list of signatures, each signature is verified against the expected content. 2. The public keys corresponding to the signatures are matched against the leaves of the composite key tree in question, and the total combined weight of all children is calculated for every intermediary node. If all thresholds are satisfied, - the composite key requirement is considered to be met. - -Date support ------------- -There are a number of supporting interfaces and classes for use by contracts which deal with dates (especially in the -context of deadlines). As contract negotiation typically deals with deadlines in terms such as "overnight", "T+3", -etc., it's desirable to allow conversion of these terms to their equivalent deadline. ``Tenor`` models the interval -before a deadline, such as 3 days, etc., while ``DateRollConvention`` describes how deadlines are modified to take -into account bank holidays or other events that modify normal working days. - -Calculating the rollover of a deadline based on working days requires information on the bank holidays involved -(and where a contract's parties are in different countries, for example, this can involve multiple separate sets of -bank holidays). The ``BusinessCalendar`` class models these calendars of business holidays; currently it loads these -from files on disk, but in future this is likely to involve reference data oracles in order to ensure consensus on the -dates used. + the composite key requirement is considered to be met. \ No newline at end of file From 05e94e7425febb5f1e33a3b947a367e1479b9a26 Mon Sep 17 00:00:00 2001 From: Clinton Alexander Date: Fri, 22 Sep 2017 16:45:48 +0100 Subject: [PATCH 045/230] Corrected isolated.jar excludes for all projects and corrected some test dependencies. --- build.gradle | 14 ++++++++++---- client/jfx/build.gradle | 3 --- client/mock/build.gradle | 6 ------ client/rpc/build.gradle | 3 --- finance/isolated/build.gradle | 2 +- node-api/build.gradle | 10 ++-------- node/build.gradle | 3 --- testing/node-driver/build.gradle | 3 --- testing/test-utils/build.gradle | 6 ------ 9 files changed, 13 insertions(+), 37 deletions(-) diff --git a/build.gradle b/build.gradle index ba1bf0abf7..ac62af2c8b 100644 --- a/build.gradle +++ b/build.gradle @@ -146,10 +146,16 @@ allprojects { maven { url 'https://jitpack.io' } } - configurations.compile { - // We want to use SLF4J's version of these bindings: jcl-over-slf4j - // Remove any transitive dependency on Apache's version. - exclude group: 'commons-logging', module: 'commons-logging' + configurations { + compile { + // We want to use SLF4J's version of these bindings: jcl-over-slf4j + // Remove any transitive dependency on Apache's version. + exclude group: 'commons-logging', module: 'commons-logging' + } + runtime { + // We never want isolated.jar on classPath, since we want to test jar being dynamically loaded as an attachment + exclude module: 'isolated' + } } } diff --git a/client/jfx/build.gradle b/client/jfx/build.gradle index ef9602e810..7dd7878175 100644 --- a/client/jfx/build.gradle +++ b/client/jfx/build.gradle @@ -7,9 +7,6 @@ description 'Corda client JavaFX modules' //noinspection GroovyAssignabilityCheck configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' - integrationTestCompile.extendsFrom testCompile integrationTestRuntime.extendsFrom testRuntime } diff --git a/client/mock/build.gradle b/client/mock/build.gradle index 0c4a2efbb0..7432fdd312 100644 --- a/client/mock/build.gradle +++ b/client/mock/build.gradle @@ -5,12 +5,6 @@ apply plugin: 'com.jfrog.artifactory' description 'Corda client mock modules' -//noinspection GroovyAssignabilityCheck -configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' -} - // To find potential version conflicts, run "gradle htmlDependencyReport" and then look in // build/reports/project/dependencies/index.html for green highlighted parts of the tree. diff --git a/client/rpc/build.gradle b/client/rpc/build.gradle index 2b3c020f49..2f36d1c315 100644 --- a/client/rpc/build.gradle +++ b/client/rpc/build.gradle @@ -7,9 +7,6 @@ description 'Corda client RPC modules' //noinspection GroovyAssignabilityCheck configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' - integrationTestCompile.extendsFrom testCompile integrationTestRuntime.extendsFrom testRuntime diff --git a/finance/isolated/build.gradle b/finance/isolated/build.gradle index da4e0a9b12..44166a1102 100644 --- a/finance/isolated/build.gradle +++ b/finance/isolated/build.gradle @@ -2,5 +2,5 @@ apply plugin: 'kotlin' apply plugin: CanonicalizerPlugin dependencies { - compile project(':core') + compileOnly project(':core') } diff --git a/node-api/build.gradle b/node-api/build.gradle index 88892c4eff..be014cdc80 100644 --- a/node-api/build.gradle +++ b/node-api/build.gradle @@ -5,12 +5,6 @@ apply plugin: 'com.jfrog.artifactory' description 'Corda node Artemis API' -buildscript { - repositories { - mavenCentral() - } -} - dependencies { compile project(":core") @@ -36,8 +30,8 @@ dependencies { // Unit testing helpers. testCompile "junit:junit:$junit_version" - testCompile "org.assertj:assertj-core:${assertj_version}" - testCompile project(':test-utils') + testCompile "org.assertj:assertj-core:$assertj_version" + testCompile project(':node-driver') } jar { diff --git a/node/build.gradle b/node/build.gradle index a784504792..d6b76f8b45 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -11,9 +11,6 @@ description 'Corda node modules' //noinspection GroovyAssignabilityCheck configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' - compile { // We don't need these because we already include netty-all. exclude group: 'io.netty', module: 'netty-transport' diff --git a/testing/node-driver/build.gradle b/testing/node-driver/build.gradle index 8a9085d179..7dc2760f8f 100644 --- a/testing/node-driver/build.gradle +++ b/testing/node-driver/build.gradle @@ -6,9 +6,6 @@ apply plugin: 'com.jfrog.artifactory' //noinspection GroovyAssignabilityCheck configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' - integrationTestCompile.extendsFrom testCompile integrationTestRuntime.extendsFrom testRuntime } diff --git a/testing/test-utils/build.gradle b/testing/test-utils/build.gradle index 350a94d766..f2995b396a 100644 --- a/testing/test-utils/build.gradle +++ b/testing/test-utils/build.gradle @@ -6,12 +6,6 @@ apply plugin: 'com.jfrog.artifactory' description 'Testing utilities for Corda' -//noinspection GroovyAssignabilityCheck -configurations { - // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment - runtime.exclude module: 'isolated' -} - dependencies { compile project(':test-common') compile project(':core') From 0de6994ef59b651af031458b9feb9d742dca473c Mon Sep 17 00:00:00 2001 From: Clinton Alexander Date: Fri, 22 Sep 2017 16:56:23 +0100 Subject: [PATCH 046/230] Base types and changes required for the Contract Constraints work. --- .../net/corda/core/contracts/ContractAttachment.kt | 12 ++++++++++++ .../contracts/TransactionVerificationException.kt | 6 ++++++ .../corda/core/node/services/AttachmentStorage.kt | 6 ++++-- .../transactions/MissingContractAttachments.kt | 14 ++++++++++++++ .../internal/serialization/GeneratedAttachment.kt | 8 ++++++++ .../corda/testing/contracts/DummyLinearContract.kt | 2 +- .../net/corda/testing/node/MockAttachment.kt | 9 +++++++++ 7 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 core/src/main/kotlin/net/corda/core/contracts/ContractAttachment.kt create mode 100644 core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt create mode 100644 node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/GeneratedAttachment.kt create mode 100644 testing/test-utils/src/main/kotlin/net/corda/testing/node/MockAttachment.kt diff --git a/core/src/main/kotlin/net/corda/core/contracts/ContractAttachment.kt b/core/src/main/kotlin/net/corda/core/contracts/ContractAttachment.kt new file mode 100644 index 0000000000..161d58ea62 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/contracts/ContractAttachment.kt @@ -0,0 +1,12 @@ +package net.corda.core.contracts + +import net.corda.core.serialization.CordaSerializable + +/** + * Wrap an attachment in this if it is to be used as an executable contract attachment + * + * @property attachment The attachment representing the contract JAR + * @property contract The contract name contained within the JAR + */ +@CordaSerializable +class ContractAttachment(val attachment: Attachment, val contract: ContractClassName) : Attachment by attachment diff --git a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt index 5e5980d7a0..eb935965b3 100644 --- a/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt +++ b/core/src/main/kotlin/net/corda/core/contracts/TransactionVerificationException.kt @@ -16,6 +16,12 @@ sealed class TransactionVerificationException(val txId: SecureHash, message: Str class ContractRejection(txId: SecureHash, contract: Contract, cause: Throwable) : TransactionVerificationException(txId, "Contract verification failed: ${cause.message}, contract: $contract", cause) + class ContractConstraintRejection(txId: SecureHash, contractClass: String) + : TransactionVerificationException(txId, "Contract constraints failed for $contractClass", null) + + class MissingAttachmentRejection(txId: SecureHash, contractClass: String) + : TransactionVerificationException(txId, "Contract constraints failed, could not find attachment for: $contractClass", null) + class ContractCreationError(txId: SecureHash, contractClass: String, cause: Throwable) : TransactionVerificationException(txId, "Contract verification failed: ${cause.message}, could not create contract class: $contractClass", cause) diff --git a/core/src/main/kotlin/net/corda/core/node/services/AttachmentStorage.kt b/core/src/main/kotlin/net/corda/core/node/services/AttachmentStorage.kt index af542a2b43..4e038925c1 100644 --- a/core/src/main/kotlin/net/corda/core/node/services/AttachmentStorage.kt +++ b/core/src/main/kotlin/net/corda/core/node/services/AttachmentStorage.kt @@ -6,6 +6,8 @@ import java.io.IOException import java.io.InputStream import java.nio.file.FileAlreadyExistsException +typealias AttachmentId = SecureHash + /** * An attachment store records potentially large binary objects, identified by their hash. */ @@ -14,7 +16,7 @@ interface AttachmentStorage { * Returns a handle to a locally stored attachment, or null if it's not known. The handle can be used to open * a stream for the data, which will be a zip/jar file. */ - fun openAttachment(id: SecureHash): Attachment? + fun openAttachment(id: AttachmentId): Attachment? /** * Inserts the given attachment into the store, does *not* close the input stream. This can be an intensive @@ -28,6 +30,6 @@ interface AttachmentStorage { * @throws IOException if something went wrong. */ @Throws(FileAlreadyExistsException::class, IOException::class) - fun importAttachment(jar: InputStream): SecureHash + fun importAttachment(jar: InputStream): AttachmentId } diff --git a/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt new file mode 100644 index 0000000000..ac75722df9 --- /dev/null +++ b/core/src/main/kotlin/net/corda/core/transactions/MissingContractAttachments.kt @@ -0,0 +1,14 @@ +package net.corda.core.transactions + +import net.corda.core.contracts.ContractState +import net.corda.core.contracts.TransactionState +import net.corda.core.serialization.CordaSerializable + +/** + * A contract attachment was missing when trying to automatically attach all known contract attachments + * + * @property states States which have contracts that do not have corresponding attachments in the attachment store. + */ +@CordaSerializable +class MissingContractAttachments(val states: List>) + : Exception("Cannot find contract attachments for ${states.map { it.contract }.distinct() }") \ No newline at end of file diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/GeneratedAttachment.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/GeneratedAttachment.kt new file mode 100644 index 0000000000..e42f18ef4b --- /dev/null +++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/serialization/GeneratedAttachment.kt @@ -0,0 +1,8 @@ +package net.corda.nodeapi.internal.serialization + +import net.corda.core.crypto.sha256 +import net.corda.core.internal.AbstractAttachment + +class GeneratedAttachment(bytes: ByteArray) : AbstractAttachment({ bytes }) { + override val id = bytes.sha256() +} diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt index 1e95f64f17..17737f4caa 100644 --- a/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyLinearContract.kt @@ -15,7 +15,7 @@ import net.corda.testing.schemas.DummyLinearStateSchemaV2 import java.time.LocalDateTime import java.time.ZoneOffset.UTC -val DUMMY_LINEAR_CONTRACT_PROGRAM_ID = "net.corda.testing.contracts.DummyLinearContract" +const val DUMMY_LINEAR_CONTRACT_PROGRAM_ID = "net.corda.testing.contracts.DummyLinearContract" class DummyLinearContract : Contract { override fun verify(tx: LedgerTransaction) { diff --git a/testing/test-utils/src/main/kotlin/net/corda/testing/node/MockAttachment.kt b/testing/test-utils/src/main/kotlin/net/corda/testing/node/MockAttachment.kt new file mode 100644 index 0000000000..ac717da3e0 --- /dev/null +++ b/testing/test-utils/src/main/kotlin/net/corda/testing/node/MockAttachment.kt @@ -0,0 +1,9 @@ +package net.corda.testing.node + +import net.corda.core.crypto.SecureHash +import net.corda.core.internal.AbstractAttachment + +/** + * An attachment with only an ID and an empty data array + */ +class MockAttachment(override val id: SecureHash = SecureHash.zeroHash) : AbstractAttachment({ ByteArray(0) }) \ No newline at end of file From f43702fe3d6379f515a83f7ccb9f097ee1030d1a Mon Sep 17 00:00:00 2001 From: Viktor Kolomeyko Date: Fri, 22 Sep 2017 17:36:03 +0100 Subject: [PATCH 047/230] CORDA-611: Improve documentation for Node Explorer (#1615) Also align the name for run configuration for Node Explorer GUI --- .idea/runConfigurations/{explorer.xml => Explorer___GUI.xml} | 2 +- docs/source/node-explorer.rst | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) rename .idea/runConfigurations/{explorer.xml => Explorer___GUI.xml} (80%) diff --git a/.idea/runConfigurations/explorer.xml b/.idea/runConfigurations/Explorer___GUI.xml similarity index 80% rename from .idea/runConfigurations/explorer.xml rename to .idea/runConfigurations/Explorer___GUI.xml index df90329e1c..98113d92f5 100644 --- a/.idea/runConfigurations/explorer.xml +++ b/.idea/runConfigurations/Explorer___GUI.xml @@ -1,5 +1,5 @@ - +