Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit f9d92c6

Browse files
committed
Cleaned up new linter issues
1 parent bf3a40c commit f9d92c6

9 files changed

+191
-177
lines changed

best_quote_test.go

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"bytes"
55
"context"
66
"fmt"
7-
"io/ioutil"
7+
"io"
88
"net/http"
99
"testing"
1010

@@ -29,32 +29,32 @@ func (m *mockHTTPValidBestQuote) Do(req *http.Request) (*http.Response, error) {
2929
// Valid response
3030
if req.URL.String() == feeQuoteURLTaal {
3131
resp.StatusCode = http.StatusOK
32-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
32+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
3333
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T21:26:17.410Z\",\"expiryTime\":\"2020-10-09T21:36:17.410Z\",\"minerId\":\"03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270\",\"currentHighestBlockHash\":\"0000000000000000035c5f8c0294802a01e500fa7b95337963bb3640da3bd565\",\"currentHighestBlockHeight\":656169,\"minerReputation\":null,\"fees\":[{\"id\":1,\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":400,\"bytes\":1000},\"relayFee\":{\"satoshis\":250,\"bytes\":1000}},{\"id\":2,\"feeType\":\"data\",\"miningFee\":{\"satoshis\":500,\"bytes\":1000},\"relayFee\":{\"satoshis\":225,\"bytes\":1000}}]}",
3434
"signature": "3045022100eed49f6bf75d8f975f581271e3df658fbe8ec67e6301ea8fc25a72d18c92e30e022056af253f0d24db6a8fde4e2c1ee95e7a5ecf2c7cdc93246f8328c9e0ca582fc4",
35-
"publicKey": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
35+
"publicKey": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
3636
}
3737

3838
if req.URL.String() == feeQuoteURLMatterPool {
3939
resp.StatusCode = http.StatusOK
40-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
40+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
4141
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T22:08:26.236Z\",\"expiryTime\":\"2020-10-09T22:18:26.236Z\",\"minerId\":\"0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087\",\"currentHighestBlockHash\":\"0000000000000000028285a9168c95457521a743765f499de389c094e883f42a\",\"currentHighestBlockHeight\":656171,\"minerReputation\":null,\"fees\":[{\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":400,\"bytes\":1000},\"relayFee\":{\"satoshis\":100,\"bytes\":1000}},{\"feeType\":\"data\",\"miningFee\":{\"satoshis\":430,\"bytes\":1000},\"relayFee\":{\"satoshis\":110,\"bytes\":1000}}]}",
4242
"signature": "3044022011f90db2661726eb2659c3447ccaa9fd3368194f87d5d86a23e673c45d5d714502200c51eb600e3370b49d759aa4d441000286937b0803037a1d6de4c5a5c559d74c",
43-
"publicKey": "0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
43+
"publicKey": "0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
4444
}
4545

4646
if req.URL.String() == feeQuoteURLMempool {
4747
resp.StatusCode = http.StatusOK
48-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
48+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
4949
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T22:09:04.433Z\",\"expiryTime\":\"2020-10-09T22:19:04.433Z\",\"minerId\":null,\"currentHighestBlockHash\":\"0000000000000000028285a9168c95457521a743765f499de389c094e883f42a\",\"currentHighestBlockHeight\":656171,\"minerReputation\":null,\"fees\":[{\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":500,\"bytes\":1000},\"relayFee\":{\"satoshis\":250,\"bytes\":1000}},{\"feeType\":\"data\",\"miningFee\":{\"satoshis\":420,\"bytes\":1000},\"relayFee\":{\"satoshis\":150,\"bytes\":1000}}]}",
50-
"signature": null,"publicKey": null,"encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
50+
"signature": null,"publicKey": null,"encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
5151
}
5252

5353
if req.URL.String() == feeQuoteURLGorillaPool {
5454
resp.StatusCode = http.StatusOK
55-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
55+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
5656
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T22:09:04.433Z\",\"expiryTime\":\"2020-10-09T22:19:04.433Z\",\"minerId\":null,\"currentHighestBlockHash\":\"0000000000000000101c34c7cabadbff321f125fac9ba3c2b1294c4d81085f4a\",\"currentHighestBlockHeight\":713780,\"minerReputation\":null,\"fees\":[{\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":500,\"bytes\":1000},\"relayFee\":{\"satoshis\":250,\"bytes\":1000}},{\"feeType\":\"data\",\"miningFee\":{\"satoshis\":500,\"bytes\":1000},\"relayFee\":{\"satoshis\":250,\"bytes\":1000}}]}",
57-
"signature": null,"publicKey": null,"encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
57+
"signature": null,"publicKey": null,"encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
5858
}
5959

6060
// Default is valid
@@ -77,28 +77,28 @@ func (m *mockHTTPBadRate) Do(req *http.Request) (*http.Response, error) {
7777
// Valid response
7878
if req.URL.String() == feeQuoteURLTaal {
7979
resp.StatusCode = http.StatusOK
80-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
80+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
8181
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T21:26:17.410Z\",\"expiryTime\":\"2020-10-09T21:36:17.410Z\",\"minerId\":\"03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270\",\"currentHighestBlockHash\":\"0000000000000000035c5f8c0294802a01e500fa7b95337963bb3640da3bd565\",\"currentHighestBlockHeight\":656169,\"minerReputation\":null,\"fees\":[{\"id\":1,\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":0,\"bytes\":1000},\"relayFee\":{\"satoshis\":0,\"bytes\":1000}},{\"id\":2,\"feeType\":\"data\",\"miningFee\":{\"satoshis\":0,\"bytes\":1000},\"relayFee\":{\"satoshis\":0,\"bytes\":1000}}]}",
8282
"signature": "3045022100eed49f6bf75d8f975f581271e3df658fbe8ec67e6301ea8fc25a72d18c92e30e022056af253f0d24db6a8fde4e2c1ee95e7a5ecf2c7cdc93246f8328c9e0ca582fc4",
83-
"publicKey": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
83+
"publicKey": "03e92d3e5c3f7bd945dfbf48e7a99393b1bfb3f11f380ae30d286e7ff2aec5a270","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
8484
}
8585

8686
if req.URL.String() == feeQuoteURLMatterPool {
8787
resp.StatusCode = http.StatusOK
88-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{
88+
resp.Body = io.NopCloser(bytes.NewBufferString(`{
8989
"payload": "{\"apiVersion\":\"` + testAPIVersion + `\",\"timestamp\":\"2020-10-09T22:08:26.236Z\",\"expiryTime\":\"2020-10-09T22:18:26.236Z\",\"minerId\":\"0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087\",\"currentHighestBlockHash\":\"0000000000000000028285a9168c95457521a743765f499de389c094e883f42a\",\"currentHighestBlockHeight\":656171,\"minerReputation\":null,\"fees\":[{\"feeType\":\"standard\",\"miningFee\":{\"satoshis\":0,\"bytes\":1000},\"relayFee\":{\"satoshis\":0,\"bytes\":1000}},{\"feeType\":\"data\",\"miningFee\":{\"satoshis\":0,\"bytes\":1000},\"relayFee\":{\"satoshis\":0,\"bytes\":1000}}]}",
9090
"signature": "3044022011f90db2661726eb2659c3447ccaa9fd3368194f87d5d86a23e673c45d5d714502200c51eb600e3370b49d759aa4d441000286937b0803037a1d6de4c5a5c559d74c",
91-
"publicKey": "0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`)))
91+
"publicKey": "0211ccfc29e3058b770f3cf3eb34b0b2fd2293057a994d4d275121be4151cdf087","encoding": "` + testEncoding + `","mimetype": "` + testMimeType + `"}`))
9292
}
9393

9494
if req.URL.String() == feeQuoteURLMempool {
9595
resp.StatusCode = http.StatusBadRequest
96-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
96+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
9797
}
9898

9999
if req.URL.String() == feeQuoteURLGorillaPool {
100100
resp.StatusCode = http.StatusBadRequest
101-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
101+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
102102
}
103103

104104
// Default is valid
@@ -121,22 +121,22 @@ func (m *mockHTTPBestQuoteAllFailed) Do(req *http.Request) (*http.Response, erro
121121
// Valid response
122122
if req.URL.String() == feeQuoteURLTaal {
123123
resp.StatusCode = http.StatusBadRequest
124-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
124+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
125125
}
126126

127127
if req.URL.String() == feeQuoteURLMatterPool {
128128
resp.StatusCode = http.StatusBadRequest
129-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
129+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
130130
}
131131

132132
if req.URL.String() == feeQuoteURLMempool {
133133
resp.StatusCode = http.StatusBadRequest
134-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
134+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
135135
}
136136

137137
if req.URL.String() == feeQuoteURLGorillaPool {
138138
resp.StatusCode = http.StatusBadRequest
139-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(``)))
139+
resp.Body = io.NopCloser(bytes.NewBufferString(``))
140140
}
141141

142142
// Default is valid
@@ -161,7 +161,7 @@ func TestClient_BestQuote(t *testing.T) {
161161
assert.Equal(t, testMimeType, response.MimeType)
162162

163163
// Check that we got fees
164-
assert.Equal(t, 2, len(response.Quote.Fees))
164+
assert.Len(t, response.Quote.Fees, 2)
165165
})
166166

167167
t.Run("http error", func(t *testing.T) {
@@ -204,7 +204,7 @@ func TestClient_BestQuote(t *testing.T) {
204204
require.NotNil(t, response)
205205

206206
// Check that we got fees
207-
assert.Equal(t, 2, len(response.Quote.Fees))
207+
assert.Len(t, response.Quote.Fees, 2)
208208

209209
var fee uint64
210210
fee, err = response.Quote.CalculateFee(mapi.FeeCategoryRelay, mapi.FeeTypeData, 1000)
@@ -250,7 +250,7 @@ func TestClient_BestQuote(t *testing.T) {
250250

251251
// Create a req
252252
response, err := client.BestQuote(context.Background(), mapi.FeeCategoryMining, mapi.FeeTypeData)
253-
assert.Error(t, err)
253+
require.Error(t, err)
254254
assert.Nil(t, response)
255255
})
256256
}

client_test.go

Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package minercraft
33
import (
44
"bytes"
55
"fmt"
6-
"io/ioutil"
6+
"io"
77
"net/http"
88
"testing"
99
"time"
@@ -39,7 +39,7 @@ func (m *mockHTTPDefaultClient) Do(req *http.Request) (*http.Response, error) {
3939

4040
if req.URL.String() == "/test" {
4141
resp.StatusCode = http.StatusOK
42-
resp.Body = ioutil.NopCloser(bytes.NewBuffer([]byte(`{"message":"test"}`)))
42+
resp.Body = io.NopCloser(bytes.NewBufferString(`{"message":"test"}`))
4343
}
4444

4545
// Default is valid
@@ -60,22 +60,22 @@ func TestNewClient(t *testing.T) {
6060
t.Run("valid new client", func(t *testing.T) {
6161
client, err := NewClient(nil, nil, testAPIType, nil, nil)
6262
assert.NotNil(t, client)
63-
assert.NoError(t, err)
63+
require.NoError(t, err)
6464

6565
// Test default miners
66-
assert.Equal(t, 2, len(client.Miners()))
66+
assert.Len(t, client.Miners(), 2)
6767
})
6868

6969
t.Run("custom http client", func(t *testing.T) {
7070
client, err := NewClient(nil, http.DefaultClient, testAPIType, nil, nil)
7171
assert.NotNil(t, client)
72-
assert.NoError(t, err)
72+
require.NoError(t, err)
7373
})
7474

7575
t.Run("default miners", func(t *testing.T) {
7676
client, err := NewClient(nil, nil, testAPIType, nil, nil)
77-
assert.NotNil(t, client)
78-
assert.NoError(t, err)
77+
require.NotNil(t, client)
78+
require.NoError(t, err)
7979

8080
// Get Taal
8181
miner := client.MinerByName(MinerTaal)
@@ -104,13 +104,13 @@ func TestNewClient(t *testing.T) {
104104

105105
client, err := NewClient(nil, nil, testAPIType, miners, minerAPIs)
106106
assert.NotNil(t, client)
107-
assert.NoError(t, err)
107+
require.NoError(t, err)
108108

109109
// Get test miner
110110
miner := client.MinerByName(testMinerName)
111111
assert.Equal(t, testMinerName, miner.Name)
112112

113-
assert.Equal(t, 1, len(client.Miners()))
113+
assert.Len(t, client.Miners(), 1)
114114
})
115115
}
116116

@@ -141,7 +141,7 @@ func TestDefaultClientOptions(t *testing.T) {
141141
options := DefaultClientOptions()
142142

143143
assert.Equal(t, defaultUserAgent, options.UserAgent)
144-
assert.Equal(t, 2.0, options.BackOffExponentFactor)
144+
assert.InDelta(t, 2.0, options.BackOffExponentFactor, 0.001)
145145
assert.Equal(t, 2*time.Millisecond, options.BackOffInitialTimeout)
146146
assert.Equal(t, 2*time.Millisecond, options.BackOffMaximumJitterInterval)
147147
assert.Equal(t, 10*time.Millisecond, options.BackOffMaxTimeout)
@@ -160,7 +160,7 @@ func TestDefaultClientOptions(t *testing.T) {
160160
options.RequestRetryCount = 0
161161
client, err := NewClient(options, nil, testAPIType, nil, nil)
162162
assert.NotNil(t, client)
163-
assert.NoError(t, err)
163+
require.NoError(t, err)
164164
})
165165
}
166166

@@ -206,7 +206,7 @@ func TestClient_AddMiner(t *testing.T) {
206206
Name: "Test",
207207
},
208208
[]API{
209-
API{
209+
{
210210
Token: testMinerToken,
211211
URL: "https://testminer.com",
212212
Type: testAPIType,
@@ -222,7 +222,7 @@ func TestClient_AddMiner(t *testing.T) {
222222
for _, test := range tests {
223223
t.Run(test.testCase, func(t *testing.T) {
224224
err := client.AddMiner(test.inputMiner, test.inputAPIs)
225-
assert.NoError(t, err)
225+
require.NoError(t, err)
226226

227227
// Get the miner
228228
miner := client.MinerByName(test.inputMiner.Name)
@@ -330,8 +330,8 @@ func TestClient_AddMiner(t *testing.T) {
330330
client := newTestClient(&mockHTTPDefaultClient{})
331331

332332
// Add a miner to start
333-
err := client.AddMiner(Miner{MinerID: testMinerID, Name: "Test"}, []API{API{URL: testMinerURL, Type: testAPIType}})
334-
assert.NoError(t, err)
333+
err := client.AddMiner(Miner{MinerID: testMinerID, Name: "Test"}, []API{{URL: testMinerURL, Type: testAPIType}})
334+
require.NoError(t, err)
335335

336336
for _, test := range tests {
337337
t.Run(test.testCase, func(t *testing.T) {
@@ -380,7 +380,7 @@ func TestClient_MinerByName(t *testing.T) {
380380
err := client.AddMiner(Miner{
381381
Name: testMinerName,
382382
}, []API{{URL: testMinerURL, Type: testAPIType}})
383-
assert.NoError(t, err)
383+
require.NoError(t, err)
384384

385385
// Get valid miner
386386
miner := client.MinerByName(testMinerName)
@@ -395,7 +395,7 @@ func TestClient_MinerByName(t *testing.T) {
395395
Name: testMinerName,
396396
}, []API{{URL: testMinerURL, Type: testAPIType}},
397397
)
398-
assert.NoError(t, err)
398+
require.NoError(t, err)
399399

400400
// Get invalid miner
401401
miner := client.MinerByName("Unknown")
@@ -443,7 +443,7 @@ func TestClient_MinerByID(t *testing.T) {
443443
Name: testMinerName,
444444
MinerID: testMinerID,
445445
}, []API{{URL: testMinerURL, Type: testAPIType}})
446-
assert.NoError(t, err)
446+
require.NoError(t, err)
447447

448448
// Get valid miner
449449
miner := client.MinerByID(testMinerID)
@@ -458,7 +458,7 @@ func TestClient_MinerByID(t *testing.T) {
458458
Name: testMinerName,
459459
MinerID: testMinerID,
460460
}, []API{{URL: testMinerURL, Type: testAPIType}})
461-
assert.NoError(t, err)
461+
require.NoError(t, err)
462462

463463
// Get invalid miner
464464
miner := client.MinerByID("00000")
@@ -488,7 +488,9 @@ func ExampleClient_MinerByID() {
488488
// BenchmarkClient_MinerByID benchmarks the method MinerByID()
489489
func BenchmarkClient_MinerByID(b *testing.B) {
490490
client, _ := NewClient(nil, nil, testAPIType, nil, nil)
491-
_ = client.AddMiner(Miner{Name: testMinerName, MinerID: testMinerID}, []API{API{URL: testMinerURL, Type: testAPIType}})
491+
_ = client.AddMiner(
492+
Miner{Name: testMinerName, MinerID: testMinerID},
493+
[]API{{URL: testMinerURL, Type: testAPIType}})
492494
for i := 0; i < b.N; i++ {
493495
_ = client.MinerByID(testMinerID)
494496
}
@@ -506,15 +508,16 @@ func TestClient_MinerUpdateToken(t *testing.T) {
506508
Name: testMinerName,
507509
MinerID: testMinerID,
508510
}, []API{{URL: testMinerURL, Type: testAPIType, Token: testMinerToken}})
509-
assert.NoError(t, err)
511+
require.NoError(t, err)
510512

511513
// Update a valid miner token
512514
client.MinerUpdateToken(testMinerName, "99999", testAPIType)
513515

514516
// Get valid miner
515517
miner := client.MinerByID(testMinerID)
516-
api, err := client.MinerAPIByMinerID(testMinerID, testAPIType)
517-
assert.NoError(t, err)
518+
var api *API
519+
api, err = client.MinerAPIByMinerID(testMinerID, testAPIType)
520+
require.NoError(t, err)
518521
assert.NotNil(t, miner)
519522
assert.Equal(t, "99999", api.Token)
520523
})
@@ -526,8 +529,8 @@ func TestClient_MinerUpdateToken(t *testing.T) {
526529
err := client.AddMiner(Miner{
527530
Name: testMinerName,
528531
MinerID: testMinerID,
529-
}, []API{API{URL: testMinerURL, Type: testAPIType, Token: testMinerToken}})
530-
assert.NoError(t, err)
532+
}, []API{{URL: testMinerURL, Type: testAPIType, Token: testMinerToken}})
533+
require.NoError(t, err)
531534

532535
// Update a invalid miner token
533536
client.MinerUpdateToken("Unknown", "99999", testAPIType)
@@ -574,7 +577,7 @@ func TestClient_RemoveMiner(t *testing.T) {
574577

575578
// Remove miner
576579
removed := client.RemoveMiner(client.MinerByName(MinerTaal))
577-
assert.Equal(t, true, removed)
580+
assert.True(t, removed)
578581

579582
// Try to get the miner
580583
miner := client.MinerByName(MinerTaal)
@@ -592,7 +595,7 @@ func TestClient_RemoveMiner(t *testing.T) {
592595

593596
// Remove miner
594597
removed := client.RemoveMiner(dummyMiner)
595-
assert.Equal(t, false, removed)
598+
assert.False(t, removed)
596599
})
597600

598601
t.Run("remove a nil miner", func(t *testing.T) {
@@ -601,7 +604,7 @@ func TestClient_RemoveMiner(t *testing.T) {
601604
// Remove miner
602605
assert.Panics(t, func() {
603606
removed := client.RemoveMiner(nil)
604-
assert.Equal(t, false, removed)
607+
assert.False(t, removed)
605608
})
606609
})
607610
}
@@ -639,7 +642,7 @@ func TestDefaultMiners(t *testing.T) {
639642
require.NotNil(t, miners)
640643
// assert.Equal(t, MinerMempool, miners[1].Name)
641644
//assert.Equal(t, MinerMatterpool, miners[1].Name)
642-
assert.Equal(t, 2, len(miners))
645+
assert.Len(t, miners, 2)
643646
assert.Equal(t, MinerTaal, miners[0].Name)
644647
assert.Equal(t, MinerGorillaPool, miners[1].Name)
645648
})

0 commit comments

Comments
 (0)