Skip to content

Commit cd77f5c

Browse files
committed
Merge branch 'develop' of https://github.com/stacks-network/stacks-core into fix/clippy-ci-stacks-lib-needless-borrow
2 parents d892a89 + 9cacb22 commit cd77f5c

File tree

105 files changed

+320
-623
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

105 files changed

+320
-623
lines changed

clarity/src/libclarity.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,19 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
#![allow(unused_imports)]
1817
#![allow(dead_code)]
1918
#![allow(non_camel_case_types)]
2019
#![allow(non_snake_case)]
2120
#![allow(non_upper_case_globals)]
2221
#![cfg_attr(test, allow(unused_variables, unused_assignments))]
2322

23+
#[allow(unused_imports)]
2424
#[macro_use(o, slog_log, slog_trace, slog_debug, slog_info, slog_warn, slog_error)]
2525
extern crate slog;
2626

2727
#[macro_use]
2828
extern crate serde_derive;
2929

30-
#[macro_use]
3130
extern crate serde_json;
3231

3332
#[cfg(any(test, feature = "testing"))]

clarity/src/vm/analysis/analysis_db.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ use std::collections::{BTreeMap, BTreeSet};
1818

1919
use stacks_common::types::StacksEpochId;
2020

21-
use crate::vm::analysis::errors::{CheckError, CheckErrors, CheckResult};
21+
use crate::vm::analysis::errors::{CheckErrors, CheckResult};
2222
use crate::vm::analysis::type_checker::ContractAnalysis;
2323
use crate::vm::database::{
2424
ClarityBackingStore, ClarityDeserializable, ClaritySerializable, RollbackWrapper,
2525
};
2626
use crate::vm::representations::ClarityName;
2727
use crate::vm::types::signatures::FunctionSignature;
28-
use crate::vm::types::{FunctionType, QualifiedContractIdentifier, TraitIdentifier, TypeSignature};
28+
use crate::vm::types::{FunctionType, QualifiedContractIdentifier, TraitIdentifier};
2929
use crate::vm::ClarityVersion;
3030

3131
pub struct AnalysisDatabase<'a> {

clarity/src/vm/analysis/arithmetic_checker/mod.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,16 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
use hashbrown::HashMap;
18-
1917
pub use super::errors::{
2018
check_argument_count, check_arguments_at_least, CheckError, CheckErrors, CheckResult,
2119
};
22-
use super::AnalysisDatabase;
23-
use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis};
20+
use crate::vm::analysis::types::ContractAnalysis;
2421
use crate::vm::functions::define::{DefineFunctions, DefineFunctionsParsed};
25-
use crate::vm::functions::{tuples, NativeFunctions};
22+
use crate::vm::functions::NativeFunctions;
2623
use crate::vm::representations::SymbolicExpressionType::{
2724
Atom, AtomValue, Field, List, LiteralValue, TraitReference,
2825
};
29-
use crate::vm::representations::{ClarityName, SymbolicExpression, SymbolicExpressionType};
30-
use crate::vm::types::{
31-
parse_name_type_pairs, PrincipalData, TupleTypeSignature, TypeSignature, Value,
32-
};
26+
use crate::vm::representations::{ClarityName, SymbolicExpression};
3327
use crate::vm::variables::NativeVariables;
3428
use crate::vm::ClarityVersion;
3529

clarity/src/vm/analysis/read_only_checker/mod.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,12 @@ pub use super::errors::{
2323
use super::AnalysisDatabase;
2424
use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis};
2525
use crate::vm::functions::define::DefineFunctionsParsed;
26-
use crate::vm::functions::{tuples, NativeFunctions};
26+
use crate::vm::functions::NativeFunctions;
2727
use crate::vm::representations::SymbolicExpressionType::{
2828
Atom, AtomValue, Field, List, LiteralValue, TraitReference,
2929
};
3030
use crate::vm::representations::{ClarityName, SymbolicExpression, SymbolicExpressionType};
31-
use crate::vm::types::{
32-
parse_name_type_pairs, PrincipalData, TupleTypeSignature, TypeSignature, Value,
33-
};
34-
use crate::vm::variables::NativeVariables;
31+
use crate::vm::types::{PrincipalData, Value};
3532
use crate::vm::ClarityVersion;
3633

3734
#[cfg(test)]

clarity/src/vm/analysis/read_only_checker/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ use rstest_reuse::{self, *};
2121
use stacks_common::types::StacksEpochId;
2222

2323
use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check;
24-
use crate::vm::analysis::{type_check, CheckError, CheckErrors};
24+
use crate::vm::analysis::{type_check, CheckErrors};
2525
use crate::vm::ast::parse;
2626
use crate::vm::database::MemoryBackingStore;
2727
use crate::vm::tests::test_clarity_versions;

clarity/src/vm/analysis/tests/mod.rs

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@
1616

1717
use stacks_common::types::StacksEpochId;
1818

19-
use crate::vm::analysis::errors::CheckErrors;
19+
use crate::vm::analysis::mem_type_check as mem_run_analysis;
2020
use crate::vm::analysis::type_checker::v2_1::tests::mem_type_check;
21-
use crate::vm::analysis::{
22-
mem_type_check as mem_run_analysis, type_check, AnalysisDatabase, ContractAnalysis,
23-
};
24-
use crate::vm::ast::parse;
2521
use crate::vm::ClarityVersion;
2622

2723
#[test]

clarity/src/vm/analysis/trait_checker/mod.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,11 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
use hashbrown::HashMap;
1817
use stacks_common::types::StacksEpochId;
1918

20-
use crate::vm::analysis::errors::{CheckError, CheckErrors, CheckResult};
19+
use crate::vm::analysis::errors::{CheckErrors, CheckResult};
2120
use crate::vm::analysis::types::{AnalysisPass, ContractAnalysis};
2221
use crate::vm::analysis::AnalysisDatabase;
23-
use crate::vm::functions::define::{DefineFunctions, DefineFunctionsParsed};
24-
use crate::vm::functions::NativeFunctions;
25-
use crate::vm::representations::SymbolicExpressionType::{Atom, AtomValue, List, LiteralValue};
26-
use crate::vm::representations::{ClarityName, SymbolicExpression};
27-
use crate::vm::types::{FunctionType, TraitIdentifier, TypeSignature, Value};
2822

2923
pub struct TraitChecker {
3024
epoch: StacksEpochId,

clarity/src/vm/analysis/trait_checker/tests.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,8 @@ use rstest::rstest;
2020
use rstest_reuse::{self, *};
2121
use stacks_common::types::StacksEpochId;
2222

23-
use crate::vm::analysis::contract_interface_builder::build_contract_interface;
2423
use crate::vm::analysis::errors::CheckErrors;
25-
use crate::vm::analysis::{type_check, AnalysisDatabase, CheckError};
24+
use crate::vm::analysis::{type_check, CheckError};
2625
use crate::vm::ast::errors::ParseErrors;
2726
use crate::vm::ast::{build_ast, parse};
2827
use crate::vm::database::MemoryBackingStore;

clarity/src/vm/analysis/type_checker/mod.rs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,11 @@ pub mod v2_1;
2020

2121
use stacks_common::types::StacksEpochId;
2222

23-
use super::errors::{
24-
check_argument_count, check_arguments_at_least, check_arguments_at_most, CheckError,
25-
CheckErrors, CheckResult,
26-
};
23+
use super::errors::{CheckErrors, CheckResult};
2724
pub use super::types::{AnalysisPass, ContractAnalysis};
2825
use super::AnalysisDatabase;
29-
use crate::vm::costs::{analysis_typecheck_cost, CostTracker, LimitedCostTracker};
30-
use crate::vm::types::signatures::{
31-
CallableSubtype, FunctionArgSignature, FunctionReturnsSignature,
32-
};
33-
use crate::vm::types::{
34-
FixedFunction, FunctionType, PrincipalData, SequenceSubtype, StringSubtype, TypeSignature,
35-
};
26+
use crate::vm::costs::CostTracker;
27+
use crate::vm::types::{FunctionType, TypeSignature};
3628
use crate::vm::{ClarityVersion, Value};
3729

3830
impl FunctionType {

clarity/src/vm/analysis/type_checker/v2_05/contexts.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ use hashbrown::{HashMap, HashSet};
2020

2121
use crate::vm::analysis::errors::{CheckError, CheckErrors, CheckResult};
2222
use crate::vm::analysis::types::ContractAnalysis;
23-
use crate::vm::contexts::MAX_CONTEXT_DEPTH;
24-
use crate::vm::representations::{ClarityName, SymbolicExpression};
23+
use crate::vm::representations::ClarityName;
2524
use crate::vm::types::signatures::FunctionSignature;
2625
use crate::vm::types::{FunctionType, TraitIdentifier, TypeSignature};
2726

clarity/src/vm/analysis/type_checker/v2_05/mod.rs

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,34 +20,31 @@ pub mod natives;
2020

2121
use std::collections::BTreeMap;
2222

23-
use hashbrown::HashMap;
2423
use stacks_common::types::StacksEpochId;
2524

2625
use self::contexts::ContractContext;
2726
pub use self::natives::{SimpleNativeFunction, TypedNativeFunction};
2827
use super::contexts::{TypeMap, TypingContext};
29-
use super::{AnalysisPass, ContractAnalysis};
28+
use super::ContractAnalysis;
3029
pub use crate::vm::analysis::errors::{
3130
check_argument_count, check_arguments_at_least, CheckError, CheckErrors, CheckResult,
3231
};
3332
use crate::vm::analysis::AnalysisDatabase;
34-
use crate::vm::contexts::Environment;
3533
use crate::vm::costs::cost_functions::ClarityCostFunction;
3634
use crate::vm::costs::{
37-
analysis_typecheck_cost, cost_functions, runtime_cost, ClarityCostFunctionReference,
38-
CostErrors, CostOverflowingMath, CostTracker, ExecutionCost, LimitedCostTracker,
35+
analysis_typecheck_cost, runtime_cost, CostErrors, CostOverflowingMath, CostTracker,
36+
ExecutionCost, LimitedCostTracker,
3937
};
40-
use crate::vm::errors::InterpreterError;
4138
use crate::vm::functions::define::DefineFunctionsParsed;
4239
use crate::vm::functions::NativeFunctions;
4340
use crate::vm::representations::SymbolicExpressionType::{
4441
Atom, AtomValue, Field, List, LiteralValue, TraitReference,
4542
};
4643
use crate::vm::representations::{depth_traverse, ClarityName, SymbolicExpression};
47-
use crate::vm::types::signatures::{FunctionSignature, BUFF_20};
44+
use crate::vm::types::signatures::FunctionSignature;
4845
use crate::vm::types::{
4946
parse_name_type_pairs, FixedFunction, FunctionArg, FunctionType, PrincipalData,
50-
QualifiedContractIdentifier, TupleTypeSignature, TypeSignature, Value,
47+
QualifiedContractIdentifier, TypeSignature, Value,
5148
};
5249
use crate::vm::variables::NativeVariables;
5350
use crate::vm::ClarityVersion;

clarity/src/vm/analysis/type_checker/v2_05/natives/assets.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

17-
use super::{no_type, FunctionType, TypeChecker, TypeResult, TypingContext};
18-
use crate::vm::analysis::errors::{check_argument_count, CheckError, CheckErrors, CheckResult};
17+
use super::{TypeChecker, TypeResult, TypingContext};
18+
use crate::vm::analysis::errors::{check_argument_count, CheckErrors};
1919
use crate::vm::costs::cost_functions::ClarityCostFunction;
20-
use crate::vm::costs::{cost_functions, runtime_cost};
20+
use crate::vm::costs::runtime_cost;
2121
use crate::vm::representations::SymbolicExpression;
22-
use crate::vm::types::{BlockInfoProperty, TupleTypeSignature, TypeSignature, MAX_VALUE_SIZE};
22+
use crate::vm::types::TypeSignature;
2323

2424
pub fn check_special_get_owner(
2525
checker: &mut TypeChecker,

clarity/src/vm/analysis/type_checker/v2_05/natives/maps.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,13 @@
1616

1717
use stacks_common::types::StacksEpochId;
1818

19-
use super::check_special_tuple_cons;
2019
use crate::vm::analysis::type_checker::v2_05::{
21-
check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker, TypeResult,
22-
TypingContext,
20+
check_arguments_at_least, CheckError, CheckErrors, TypeChecker, TypeResult, TypingContext,
2321
};
2422
use crate::vm::costs::cost_functions::ClarityCostFunction;
25-
use crate::vm::costs::{analysis_typecheck_cost, cost_functions, runtime_cost};
26-
use crate::vm::functions::tuples;
27-
use crate::vm::representations::{SymbolicExpression, SymbolicExpressionType};
28-
use crate::vm::types::{PrincipalData, TypeSignature, Value};
23+
use crate::vm::costs::{analysis_typecheck_cost, runtime_cost};
24+
use crate::vm::representations::SymbolicExpression;
25+
use crate::vm::types::TypeSignature;
2926

3027
pub fn check_special_fetch_entry(
3128
checker: &mut TypeChecker,

clarity/src/vm/analysis/type_checker/v2_05/natives/mod.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,13 @@ use stacks_common::types::StacksEpochId;
1919
use super::{
2020
check_argument_count, check_arguments_at_least, no_type, TypeChecker, TypeResult, TypingContext,
2121
};
22-
use crate::vm::analysis::errors::{CheckError, CheckErrors, CheckResult};
22+
use crate::vm::analysis::errors::{CheckError, CheckErrors};
2323
use crate::vm::costs::cost_functions::ClarityCostFunction;
24-
use crate::vm::costs::{
25-
analysis_typecheck_cost, cost_functions, runtime_cost, CostOverflowingMath,
26-
};
27-
use crate::vm::errors::{Error as InterpError, InterpreterError, RuntimeErrorType};
24+
use crate::vm::costs::{analysis_typecheck_cost, runtime_cost};
2825
use crate::vm::functions::{handle_binding_list, NativeFunctions};
2926
use crate::vm::types::{
3027
BlockInfoProperty, FixedFunction, FunctionArg, FunctionSignature, FunctionType, PrincipalData,
3128
TupleTypeSignature, TypeSignature, Value, BUFF_20, BUFF_32, BUFF_33, BUFF_64, BUFF_65,
32-
MAX_VALUE_SIZE,
3329
};
3430
use crate::vm::{ClarityName, ClarityVersion, SymbolicExpression, SymbolicExpressionType};
3531

clarity/src/vm/analysis/type_checker/v2_05/natives/options.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,11 @@
1717
use stacks_common::types::StacksEpochId;
1818

1919
use crate::vm::analysis::type_checker::v2_05::{
20-
check_argument_count, check_arguments_at_least, no_type, CheckError, CheckErrors, TypeChecker,
21-
TypeResult, TypingContext,
20+
check_argument_count, check_arguments_at_least, no_type, CheckErrors, TypeChecker, TypeResult,
21+
TypingContext,
2222
};
2323
use crate::vm::costs::cost_functions::ClarityCostFunction;
24-
use crate::vm::costs::{analysis_typecheck_cost, cost_functions, runtime_cost};
24+
use crate::vm::costs::{analysis_typecheck_cost, runtime_cost};
2525
use crate::vm::representations::{ClarityName, SymbolicExpression};
2626
use crate::vm::types::TypeSignature;
2727

clarity/src/vm/analysis/type_checker/v2_05/natives/sequences.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,17 @@ use stacks_common::types::StacksEpochId;
1818

1919
use super::{SimpleNativeFunction, TypedNativeFunction};
2020
use crate::vm::analysis::type_checker::v2_05::{
21-
check_argument_count, check_arguments_at_least, no_type, CheckErrors, CheckResult, TypeChecker,
21+
check_argument_count, check_arguments_at_least, CheckErrors, CheckResult, TypeChecker,
2222
TypeResult, TypingContext,
2323
};
2424
use crate::vm::costs::cost_functions::ClarityCostFunction;
25-
use crate::vm::costs::{analysis_typecheck_cost, cost_functions, runtime_cost};
25+
use crate::vm::costs::{analysis_typecheck_cost, runtime_cost};
2626
use crate::vm::functions::NativeFunctions;
2727
use crate::vm::representations::{SymbolicExpression, SymbolicExpressionType};
2828
pub use crate::vm::types::signatures::{BufferLength, ListTypeData, StringUTF8Length, BUFF_1};
2929
use crate::vm::types::SequenceSubtype::*;
3030
use crate::vm::types::StringSubtype::*;
31-
use crate::vm::types::{FunctionType, TypeSignature, Value, MAX_VALUE_SIZE};
31+
use crate::vm::types::{FunctionType, TypeSignature, Value};
3232
use crate::vm::ClarityVersion;
3333

3434
fn get_simple_native_or_user_define(

clarity/src/vm/analysis/type_checker/v2_05/tests/assets.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use stacks_common::types::StacksEpochId;
1818

1919
use crate::vm::analysis::errors::CheckErrors;
20-
use crate::vm::analysis::AnalysisDatabase;
2120
use crate::vm::ast::parse;
2221
use crate::vm::database::MemoryBackingStore;
2322
use crate::vm::tooling::mem_type_check;
@@ -151,8 +150,6 @@ fn test_names_tokens_contracts() {
151150

152151
#[test]
153152
fn test_bad_asset_usage() {
154-
use crate::vm::analysis::type_check;
155-
156153
let bad_scripts = [
157154
"(ft-get-balance stackoos tx-sender)",
158155
"(ft-get-balance u1234 tx-sender)",

clarity/src/vm/analysis/type_checker/v2_05/tests/contracts.rs

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,11 @@ use {assert_json_diff, serde_json};
2020

2121
use crate::vm::analysis::contract_interface_builder::build_contract_interface;
2222
use crate::vm::analysis::errors::CheckErrors;
23-
use crate::vm::analysis::{
24-
mem_type_check, type_check, AnalysisDatabase, CheckError, ContractAnalysis,
25-
};
23+
use crate::vm::analysis::{mem_type_check, type_check};
2624
use crate::vm::ast::parse;
27-
use crate::vm::costs::LimitedCostTracker;
2825
use crate::vm::database::MemoryBackingStore;
2926
use crate::vm::types::QualifiedContractIdentifier;
30-
use crate::vm::{ClarityVersion, SymbolicExpression};
27+
use crate::vm::ClarityVersion;
3128

3229
const SIMPLE_TOKENS: &str = "(define-map tokens { account: principal } { balance: uint })
3330
(define-read-only (my-get-token-balance (account principal))
@@ -603,7 +600,6 @@ fn test_same_function_name() {
603600

604601
#[test]
605602
fn test_expects() {
606-
use crate::vm::analysis::type_check;
607603
let okay = "(define-map tokens { id: int } { balance: int })
608604
(define-private (my-get-token-balance)
609605
(let ((balance (unwrap!

clarity/src/vm/analysis/type_checker/v2_05/tests/mod.rs

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,15 @@
1717
use stacks_common::types::StacksEpochId;
1818

1919
use crate::vm::analysis::errors::CheckErrors;
20-
use crate::vm::analysis::type_checker::v2_05::{TypeChecker, TypeResult, TypingContext};
21-
use crate::vm::analysis::types::ContractAnalysis;
22-
use crate::vm::analysis::{mem_type_check, type_check, AnalysisDatabase};
20+
use crate::vm::analysis::mem_type_check;
21+
use crate::vm::analysis::type_checker::v2_05::TypeResult;
22+
use crate::vm::ast::build_ast;
2323
use crate::vm::ast::errors::ParseErrors;
24-
use crate::vm::ast::{build_ast, parse};
25-
use crate::vm::contexts::OwnedEnvironment;
26-
use crate::vm::database::MemoryBackingStore;
27-
use crate::vm::representations::SymbolicExpression;
2824
use crate::vm::types::SequenceSubtype::*;
2925
use crate::vm::types::StringSubtype::*;
30-
use crate::vm::types::TypeSignature::{BoolType, IntType, PrincipalType, SequenceType, UIntType};
26+
use crate::vm::types::TypeSignature::{BoolType, IntType, PrincipalType, UIntType};
3127
use crate::vm::types::{
32-
FixedFunction, FunctionType, PrincipalData, QualifiedContractIdentifier, TypeSignature, Value,
33-
BUFF_32, BUFF_64,
28+
FixedFunction, FunctionType, QualifiedContractIdentifier, TypeSignature, BUFF_32, BUFF_64,
3429
};
3530
use crate::vm::ClarityVersion;
3631

@@ -1437,8 +1432,6 @@ fn test_response_inference() {
14371432

14381433
#[test]
14391434
fn test_function_arg_names() {
1440-
use crate::vm::analysis::type_check;
1441-
14421435
let functions = [
14431436
"(define-private (test (x int)) (ok 0))
14441437
(define-public (test-pub (x int)) (ok 0))

clarity/src/vm/analysis/type_checker/v2_1/contexts.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,8 @@ use hashbrown::{HashMap, HashSet};
2121
use crate::vm::analysis::errors::{CheckError, CheckErrors, CheckResult};
2222
use crate::vm::analysis::type_checker::is_reserved_word;
2323
use crate::vm::analysis::types::ContractAnalysis;
24-
use crate::vm::contexts::MAX_CONTEXT_DEPTH;
25-
use crate::vm::representations::{ClarityName, SymbolicExpression};
26-
use crate::vm::types::signatures::{CallableSubtype, FunctionSignature};
24+
use crate::vm::representations::ClarityName;
25+
use crate::vm::types::signatures::FunctionSignature;
2726
use crate::vm::types::{FunctionType, QualifiedContractIdentifier, TraitIdentifier, TypeSignature};
2827
use crate::vm::ClarityVersion;
2928

0 commit comments

Comments
 (0)