mirror of
https://github.com/kmc7468/cs220.git
synced 2025-12-15 22:48:45 +00:00
Assignment 6 Done
This commit is contained in:
@@ -33,55 +33,55 @@ pub fn from_usize<T: Semiring>(value: usize) -> T {
|
|||||||
|
|
||||||
impl Semiring for u64 {
|
impl Semiring for u64 {
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
todo!()
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
todo!()
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&self, rhs: &Self) -> Self {
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self + rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul(&self, rhs: &Self) -> Self {
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Semiring for i64 {
|
impl Semiring for i64 {
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
todo!()
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
todo!()
|
1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&self, rhs: &Self) -> Self {
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self + rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul(&self, rhs: &Self) -> Self {
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Semiring for f64 {
|
impl Semiring for f64 {
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
todo!()
|
0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
todo!()
|
1.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&self, rhs: &Self) -> Self {
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self + rhs
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul(&self, rhs: &Self) -> Self {
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
self * rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -105,42 +105,91 @@ pub struct Polynomial<C: Semiring> {
|
|||||||
|
|
||||||
impl<C: Semiring> Semiring for Polynomial<C> {
|
impl<C: Semiring> Semiring for Polynomial<C> {
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
coefficients: HashMap::new(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
coefficients: HashMap::from([(0, C::one())]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add(&self, rhs: &Self) -> Self {
|
fn add(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
let mut coefficients = self.coefficients.clone();
|
||||||
|
|
||||||
|
for (deg, coef) in &rhs.coefficients {
|
||||||
|
_ = coefficients
|
||||||
|
.entry(*deg)
|
||||||
|
.and_modify(|value| *value = value.add(coef))
|
||||||
|
.or_insert(coef.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
coefficients.retain(|_, coef| *coef != C::zero());
|
||||||
|
|
||||||
|
Self { coefficients }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul(&self, rhs: &Self) -> Self {
|
fn mul(&self, rhs: &Self) -> Self {
|
||||||
todo!()
|
let mut coefficients: HashMap<u64, C> = HashMap::new();
|
||||||
|
|
||||||
|
for (ldeg, lcoef) in &self.coefficients {
|
||||||
|
for (rdeg, rcoef) in &rhs.coefficients {
|
||||||
|
let coef = lcoef.mul(rcoef);
|
||||||
|
_ = coefficients
|
||||||
|
.entry(ldeg + rdeg)
|
||||||
|
.and_modify(|value| *value = value.add(&coef))
|
||||||
|
.or_insert(coef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
coefficients.retain(|_, coef| *coef != C::zero());
|
||||||
|
|
||||||
|
Self { coefficients }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Semiring> Polynomial<C> {
|
impl<C: Semiring> Polynomial<C> {
|
||||||
/// Constructs polynomial `x`.
|
/// Constructs polynomial `x`.
|
||||||
pub fn x() -> Self {
|
pub fn x() -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
coefficients: HashMap::from([(1, C::one())]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Evaluates the polynomial with the given value.
|
/// Evaluates the polynomial with the given value.
|
||||||
pub fn eval(&self, value: C) -> C {
|
pub fn eval(&self, value: C) -> C {
|
||||||
todo!()
|
let mut result = C::zero();
|
||||||
|
|
||||||
|
for (deg, coef) in &self.coefficients {
|
||||||
|
let mut xn = C::one();
|
||||||
|
let mut n = 0;
|
||||||
|
|
||||||
|
while n < *deg {
|
||||||
|
xn = xn.mul(&value);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result.add(&coef.mul(&xn));
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Constructs polynomial `ax^n`.
|
/// Constructs polynomial `ax^n`.
|
||||||
pub fn term(a: C, n: u64) -> Self {
|
pub fn term(a: C, n: u64) -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
coefficients: HashMap::from([(n, a)]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Semiring> From<C> for Polynomial<C> {
|
impl<C: Semiring> From<C> for Polynomial<C> {
|
||||||
fn from(value: C) -> Self {
|
fn from(value: C) -> Self {
|
||||||
todo!()
|
Self {
|
||||||
|
coefficients: HashMap::from([(0, value)]),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +213,30 @@ impl<C: Semiring> std::str::FromStr for Polynomial<C> {
|
|||||||
type Err = (); // Ignore this for now...
|
type Err = (); // Ignore this for now...
|
||||||
|
|
||||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
todo!()
|
let mut coefficients: HashMap<u64, C> = HashMap::new();
|
||||||
|
|
||||||
|
for term in s.split(" + ") {
|
||||||
|
let has_x: bool = term.contains('x');
|
||||||
|
let has_power = term.contains('^');
|
||||||
|
|
||||||
|
let deg: u64 = if has_power {
|
||||||
|
term.split("^").nth(1).unwrap().parse().unwrap()
|
||||||
|
} else if has_x {
|
||||||
|
1
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
};
|
||||||
|
let coef: usize = if has_x && term.find("x").unwrap() == 0 {
|
||||||
|
1
|
||||||
|
} else if has_x {
|
||||||
|
term.split("x").nth(0).unwrap().parse().unwrap()
|
||||||
|
} else {
|
||||||
|
term.parse().unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
let _unused = coefficients.insert(deg, from_usize(coef));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { coefficients })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,11 +38,39 @@ impl Rational {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gcd(a: isize, b: isize) -> isize {
|
||||||
|
if b == 0 {
|
||||||
|
a
|
||||||
|
} else {
|
||||||
|
gcd(b, a % b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn lcm(a: isize, b: isize) -> isize {
|
||||||
|
(a * b) / gcd(a, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn normalize(r: &Rational) -> Rational {
|
||||||
|
let factor = if r.denominator < 0 { -1 } else { 1 };
|
||||||
|
Rational {
|
||||||
|
numerator: r.numerator * factor,
|
||||||
|
denominator: r.denominator * factor,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Add for Rational {
|
impl Add for Rational {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
todo!()
|
let lcm = lcm(self.denominator, rhs.denominator);
|
||||||
|
let num =
|
||||||
|
self.numerator * (lcm / self.denominator) + rhs.numerator * (lcm / rhs.denominator);
|
||||||
|
let gcd = gcd(num, lcm);
|
||||||
|
|
||||||
|
normalize(&Self {
|
||||||
|
numerator: num / gcd,
|
||||||
|
denominator: lcm / gcd,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +78,14 @@ impl Mul for Rational {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
todo!()
|
let num = self.numerator * rhs.numerator;
|
||||||
|
let den = self.denominator * rhs.denominator;
|
||||||
|
let gcd = gcd(num, den) * (if den < 0 { -1 } else { 1 });
|
||||||
|
|
||||||
|
normalize(&Self {
|
||||||
|
numerator: num / gcd,
|
||||||
|
denominator: den / gcd,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +93,7 @@ impl Sub for Rational {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> Self::Output {
|
fn sub(self, rhs: Self) -> Self::Output {
|
||||||
todo!()
|
self + (MINUS_ONE * rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +101,10 @@ impl Div for Rational {
|
|||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn div(self, rhs: Self) -> Self::Output {
|
fn div(self, rhs: Self) -> Self::Output {
|
||||||
todo!()
|
self.mul(Self {
|
||||||
|
numerator: rhs.denominator,
|
||||||
|
denominator: rhs.numerator,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +122,7 @@ pub trait Differentiable: Clone {
|
|||||||
impl Differentiable for Rational {
|
impl Differentiable for Rational {
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Constant_term_rule>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Constant_term_rule>
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
ZERO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,19 +146,31 @@ pub enum SingletonPolynomial {
|
|||||||
impl SingletonPolynomial {
|
impl SingletonPolynomial {
|
||||||
/// Creates a new const polynomial.
|
/// Creates a new const polynomial.
|
||||||
pub fn new_c(r: Rational) -> Self {
|
pub fn new_c(r: Rational) -> Self {
|
||||||
todo!()
|
SingletonPolynomial::Const(r)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new polynomial.
|
/// Creates a new polynomial.
|
||||||
pub fn new_poly(coeff: Rational, power: Rational) -> Self {
|
pub fn new_poly(coeff: Rational, power: Rational) -> Self {
|
||||||
todo!()
|
SingletonPolynomial::Polynomial { coeff, power }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Differentiable for SingletonPolynomial {
|
impl Differentiable for SingletonPolynomial {
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Power_rule>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Power_rule>
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Const(_) => Self::Const(ZERO),
|
||||||
|
Self::Polynomial { coeff, power } => {
|
||||||
|
if *power == ONE {
|
||||||
|
Self::Const(*coeff)
|
||||||
|
} else {
|
||||||
|
Self::Polynomial {
|
||||||
|
coeff: *coeff * *power,
|
||||||
|
power: *power - ONE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +181,7 @@ pub struct Exp;
|
|||||||
impl Exp {
|
impl Exp {
|
||||||
/// Creates a new exponential function.
|
/// Creates a new exponential function.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
todo!()
|
Exp {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +194,7 @@ impl Default for Exp {
|
|||||||
impl Differentiable for Exp {
|
impl Differentiable for Exp {
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_exponential_and_logarithmic_functions>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_exponential_and_logarithmic_functions>
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,19 +218,24 @@ pub enum Trignometric {
|
|||||||
impl Trignometric {
|
impl Trignometric {
|
||||||
/// Creates a new sine function.
|
/// Creates a new sine function.
|
||||||
pub fn new_sine(coeff: Rational) -> Self {
|
pub fn new_sine(coeff: Rational) -> Self {
|
||||||
todo!()
|
Trignometric::Sine { coeff }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new cosine function.
|
/// Creates a new cosine function.
|
||||||
pub fn new_cosine(coeff: Rational) -> Self {
|
pub fn new_cosine(coeff: Rational) -> Self {
|
||||||
todo!()
|
Trignometric::Cosine { coeff }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Differentiable for Trignometric {
|
impl Differentiable for Trignometric {
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_trigonometric_functions>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Derivatives_of_trigonometric_functions>
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Sine { coeff } => Self::Cosine { coeff: *coeff },
|
||||||
|
Self::Cosine { coeff } => Self::Sine {
|
||||||
|
coeff: MINUS_ONE * *coeff,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +254,12 @@ pub enum BaseFuncs {
|
|||||||
|
|
||||||
impl Differentiable for BaseFuncs {
|
impl Differentiable for BaseFuncs {
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Const(_) => Self::Const(ZERO),
|
||||||
|
Self::Poly(p) => Self::Poly(p.diff()),
|
||||||
|
Self::Exp(e) => Self::Exp(e.diff()),
|
||||||
|
Self::Trig(t) => Self::Trig(t.diff()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,14 +282,41 @@ pub enum ComplexFuncs<F> {
|
|||||||
|
|
||||||
impl<F: Differentiable> Differentiable for Box<F> {
|
impl<F: Differentiable> Differentiable for Box<F> {
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
Box::new(self.deref().diff())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Differentiable> Differentiable for ComplexFuncs<F> {
|
impl<F: Differentiable> Differentiable for ComplexFuncs<F> {
|
||||||
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Elementary_rules_of_differentiation>
|
/// HINT: Consult <https://en.wikipedia.org/wiki/Differentiation_rules#Elementary_rules_of_differentiation>
|
||||||
fn diff(&self) -> Self {
|
fn diff(&self) -> Self {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Func(f) => Self::Func(f.diff()),
|
||||||
|
Self::Add(lhs, rhs) => Self::Add(lhs.diff(), rhs.diff()),
|
||||||
|
Self::Sub(lhs, rhs) => Self::Sub(lhs.diff(), rhs.diff()),
|
||||||
|
Self::Mul(lhs, rhs) => {
|
||||||
|
let diff_lhs = lhs.diff();
|
||||||
|
let diff_rhs = rhs.diff();
|
||||||
|
Self::Add(
|
||||||
|
Box::new(Self::Mul(diff_lhs, rhs.clone())),
|
||||||
|
Box::new(Self::Mul(lhs.clone(), diff_rhs)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Self::Div(lhs, rhs) => {
|
||||||
|
let diff_lhs = lhs.diff();
|
||||||
|
let diff_rhs = rhs.diff();
|
||||||
|
Self::Div(
|
||||||
|
Box::new(Self::Sub(
|
||||||
|
Box::new(Self::Mul(diff_lhs, rhs.clone())),
|
||||||
|
Box::new(Self::Mul(lhs.clone(), diff_rhs)),
|
||||||
|
)),
|
||||||
|
Box::new(Self::Mul(rhs.clone(), rhs.clone())),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
Self::Comp(outer, inner) => Self::Mul(
|
||||||
|
Box::new(Self::Comp(outer.diff(), inner.clone())),
|
||||||
|
inner.diff(),
|
||||||
|
),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,37 +328,55 @@ pub trait Evaluate {
|
|||||||
|
|
||||||
impl Evaluate for Rational {
|
impl Evaluate for Rational {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
(self.numerator as f64) / (self.denominator as f64)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluate for SingletonPolynomial {
|
impl Evaluate for SingletonPolynomial {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Const(r) => r.evaluate(x),
|
||||||
|
Self::Polynomial { coeff, power } => x.powf(power.evaluate(x)) * coeff.evaluate(x),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluate for Exp {
|
impl Evaluate for Exp {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
x.exp()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluate for Trignometric {
|
impl Evaluate for Trignometric {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Sine { coeff } => coeff.evaluate(x) * x.sin(),
|
||||||
|
Self::Cosine { coeff } => coeff.evaluate(x) * x.cos(),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Evaluate for BaseFuncs {
|
impl Evaluate for BaseFuncs {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Const(r) => r.evaluate(x),
|
||||||
|
Self::Poly(p) => p.evaluate(x),
|
||||||
|
Self::Exp(e) => e.evaluate(x),
|
||||||
|
Self::Trig(t) => t.evaluate(x),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<F: Evaluate> Evaluate for ComplexFuncs<F> {
|
impl<F: Evaluate> Evaluate for ComplexFuncs<F> {
|
||||||
fn evaluate(&self, x: f64) -> f64 {
|
fn evaluate(&self, x: f64) -> f64 {
|
||||||
todo!()
|
match self {
|
||||||
|
Self::Func(f) => f.evaluate(x),
|
||||||
|
Self::Add(lhs, rhs) => lhs.evaluate(x) + rhs.evaluate(x),
|
||||||
|
Self::Sub(lhs, rhs) => lhs.evaluate(x) - rhs.evaluate(x),
|
||||||
|
Self::Mul(lhs, rhs) => lhs.evaluate(x) * rhs.evaluate(x),
|
||||||
|
Self::Div(lhs, rhs) => lhs.evaluate(x) / rhs.evaluate(x),
|
||||||
|
Self::Comp(outer, inner) => outer.evaluate(inner.evaluate(x)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user