diff --git a/src/main/java/Main.java b/src/main/java/Main.java new file mode 100644 index 00000000..3069888d --- /dev/null +++ b/src/main/java/Main.java @@ -0,0 +1,20 @@ +import coordinate.PointMaker; +import coordinate.GeometricElement; +import coordinate.GeometricFactory; +import coordinate.Point; +import util.Plate; +import util.Terminal; + +import java.io.IOException; + +public class Main { + public static void main(String[] args) throws IOException { + String in = Terminal.in("좌표를 입력하세요." + System.lineSeparator()); + Point[] points = PointMaker.toPoints(in); + Plate plate = new Plate(); + plate.drawPoints(points); + plate.print(); + GeometricElement geometricElement = GeometricFactory.getGeometricElement(points); + geometricElement.printCalculateResult(); + } +} diff --git a/src/main/java/coordinate/GeometricElement.java b/src/main/java/coordinate/GeometricElement.java new file mode 100644 index 00000000..97f99772 --- /dev/null +++ b/src/main/java/coordinate/GeometricElement.java @@ -0,0 +1,7 @@ +package coordinate; + +public interface GeometricElement { + double calculate(); + + void printCalculateResult(); +} diff --git a/src/main/java/coordinate/GeometricFactory.java b/src/main/java/coordinate/GeometricFactory.java new file mode 100644 index 00000000..e64c98c4 --- /dev/null +++ b/src/main/java/coordinate/GeometricFactory.java @@ -0,0 +1,35 @@ +package coordinate; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.Map; + +import static exception.ExceptionMessage.NO_LINE_OR_SHAPE; + +public class GeometricFactory { + + private final static Map> GEOMETRIC_ELEMENTS = new HashMap<>(); + + static { + int linesPointCount = 2; + int rectanglesPointCount = 4; + int trianglesPointCount = 3; + + GEOMETRIC_ELEMENTS.put(linesPointCount, Line.class); + GEOMETRIC_ELEMENTS.put(rectanglesPointCount, Rectangle.class); + GEOMETRIC_ELEMENTS.put(trianglesPointCount, Triangle.class); + } + + public static GeometricElement getGeometricElement(Point[] points) { + if (!GEOMETRIC_ELEMENTS.containsKey(points.length)) { + throw new ArithmeticException(NO_LINE_OR_SHAPE.getMessage()); + } + + try { + Class geometricElementClass = GEOMETRIC_ELEMENTS.get(points.length); + return geometricElementClass.getDeclaredConstructor(Point[].class).newInstance((Object) points); + } catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) { + throw new RuntimeException(e); + } + } +} diff --git a/src/main/java/coordinate/Line.java b/src/main/java/coordinate/Line.java new file mode 100644 index 00000000..38a0a013 --- /dev/null +++ b/src/main/java/coordinate/Line.java @@ -0,0 +1,35 @@ +package coordinate; + +import util.Terminal; + +import java.util.Arrays; + +public class Line implements GeometricElement { + private final Point[] points; + + protected Line(Point[] in) { + points = Arrays.copyOf(in, 2); + } + + public Line(Point point1, Point point2) { + this(new Point[]{point1, point2}); + } + + public Point[] getEndPoints() { + return Arrays.copyOf(points, 2); + } + + @Override + public double calculate() { + int dx = points[0].getX() - points[1].getX(); + int dy = points[0].getY() - points[1].getY(); + + return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); + } + + @Override + public void printCalculateResult() { + String message = String.format("두 점 사이의 거리는 %.6f", this.calculate()); + Terminal.out(message); + } +} diff --git a/src/main/java/coordinate/Point.java b/src/main/java/coordinate/Point.java new file mode 100644 index 00000000..bc8de8e9 --- /dev/null +++ b/src/main/java/coordinate/Point.java @@ -0,0 +1,37 @@ +package coordinate; + +public class Point { + private final int x; + private final int y; + + public Point(int x, int y) { + this.x = x; + this.y = y; + } + + public int getX() { + return this.x; + } + + public int getY() { + return this.y; + } + + @Override + public int hashCode() { + int result = 17; + result = 37 * result + this.x; + result = 37 * result + this.y; + return result; + } + + @Override + public boolean equals(Object obj) { + if (obj.getClass() != Point.class) { + return false; + } + + Point compare = (Point) obj; + return compare.x == this.x && compare.y == this.y; + } +} diff --git a/src/main/java/coordinate/PointMaker.java b/src/main/java/coordinate/PointMaker.java new file mode 100644 index 00000000..13aac50f --- /dev/null +++ b/src/main/java/coordinate/PointMaker.java @@ -0,0 +1,69 @@ +package coordinate; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import static exception.ExceptionMessage.*; + +public class PointMaker { + + public static Point[] toPoints(String input) { + if (isBlank(input)) { + throw new IllegalArgumentException(NO_INPUT.getMessage()); + } + + Pattern pattern = Pattern.compile("\\(([^)]+)\\)"); + Matcher matcher = pattern.matcher(input); + + int hit = 0; + while (matcher.find()) { + hit++; + } + Point[] result = new Point[hit]; + + matcher.reset(); + for (int i = 0; i < result.length && matcher.find(); i++) { + String[] coordinate = matcher.group().replaceAll("[()]", "") + .split(","); + + if (coordinate.length != 2 || isBlank(coordinate[0]) || isBlank(coordinate[1])) { + throw new ArithmeticException(NO_TWO_DIMENSION_POINT.getMessage()); + } + + int x = validationNumberAndGet(coordinate[0]); + int y = validationNumberAndGet(coordinate[1]); + result[i] = new Point(x, y); + } + + return result; + } + + private static boolean isBlank(String in) { + return in == null || in.trim().isEmpty(); + } + + private static int validationNumberAndGet(String in) { + in = in.trim(); + // "-" 부호만 입력 했을 때는 0으로 간주됨 + if (in.charAt(0) != '-' && !Character.isDigit(in.charAt(0))) { + throw new ArithmeticException(INPUT_NOT_NUMBER.getMessage()); + } + + for (int i = 1; i < in.length(); i++) { + boolean isDigit = Character.isDigit(in.charAt(i)); + if (!isDigit) { + throw new ArithmeticException(INPUT_NOT_NUMBER.getMessage()); + } + } + + int rangeMin = 1; + int rangeMax = 24; + + int num = Integer.parseInt(in); + if (num < rangeMin || num > rangeMax) { + throw new IllegalArgumentException(String.format(INPUT_OUT_OF_RANGE.getMessage(), rangeMin, rangeMax)); + } + + return num; + } +} diff --git a/src/main/java/coordinate/Rectangle.java b/src/main/java/coordinate/Rectangle.java new file mode 100644 index 00000000..c80a8fd0 --- /dev/null +++ b/src/main/java/coordinate/Rectangle.java @@ -0,0 +1,102 @@ +package coordinate; + +import util.Terminal; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static exception.ExceptionMessage.NO_SHAPE; + +public class Rectangle extends Shape implements GeometricElement { + + protected Rectangle(Point[] in) { + super(in); + List points = new ArrayList<>(4); + Collections.addAll(points, in); + getSortedVertexes(points); + validate(); + } + + /** + * 네 점을 다음과 같이 대칭 점끼리 묶어서 정렬 + * 1. 한 점을 고른다 + * 2. 다른 세 점 중 앞서 정한 한 점과 가장 멀리 있는 한점을 찾는다 (고른 점과 대칭점) + * 3. 위의 두 점을 순서 대로 배열에 저장 + * 4. 나머지 두 점을 이어서 배열에 저장 (나머지 두점은 또 서로의 대칭점) + * @param points 입력 받은 점들 + */ + private void getSortedVertexes(List points) { + Point base = points.get(0); + points.remove(base); + + Point opposite = points.get(0); + double maxLength = new Line(base, opposite).calculate(); + for (int i = 1; i < points.size(); i++) { + double compareLength = new Line(base, points.get(i)).calculate(); + + if (maxLength < compareLength) { + maxLength = compareLength; + opposite = points.get(i); + } + } + + points.remove(opposite); + + vertexes[0] = base; + vertexes[1] = opposite; + vertexes[2] = points.get(0); + vertexes[3] = points.get(1); + } + + @Override + public void validate() { + boolean result1; + boolean result2; + + result1 = isRightAngle(new Line(vertexes[0], vertexes[2]), new Line(vertexes[0], vertexes[3])); + result2 = isRightAngle(new Line(vertexes[1], vertexes[2]), new Line(vertexes[1], vertexes[3])); + + if (!(result1 && result2)) { + throw new ArithmeticException(String.format(NO_SHAPE.getMessage(), this.getClass().getSimpleName())); + } + } + + private boolean isRightAngle(Line line1, Line line2) { + Point[] p1 = line1.getEndPoints(); + double angle1 = getAngle(p1[0], p1[1]); + + Point[] p2 = line2.getEndPoints(); + double angle2 = getAngle(p2[0], p2[1]); + + double betweenAngle = Math.abs(angle1 - angle2); + return betweenAngle == 90; + } + + private double getAngle(Point start, Point end) { + double dx = start.getX() - end.getX(); + double dy = start.getY() - end.getY(); + + double angle = Math.atan2(dy, dx) * (180.0 / Math.PI); + return Math.abs(angle); + } + + @Override + public Point[] getVertex() { + return Arrays.copyOf(vertexes, 4); + } + + @Override + public double calculate() { + int width = vertexes[0].getX() - vertexes[2].getX(); + int height = vertexes[0].getY() - vertexes[3].getY(); + return width * height; + } + + @Override + public void printCalculateResult() { + String message = String.format("사각형 넓이는 %.0f", this.calculate()); + Terminal.out(message); + } +} diff --git a/src/main/java/coordinate/Shape.java b/src/main/java/coordinate/Shape.java new file mode 100644 index 00000000..a3e678ca --- /dev/null +++ b/src/main/java/coordinate/Shape.java @@ -0,0 +1,14 @@ +package coordinate; + +public abstract class Shape { + + protected final Point[] vertexes; + + protected Shape(Point[] in) { + this.vertexes = new Point[in.length]; + } + + abstract void validate(); + + abstract Point[] getVertex(); +} diff --git a/src/main/java/coordinate/Triangle.java b/src/main/java/coordinate/Triangle.java new file mode 100644 index 00000000..70967ffa --- /dev/null +++ b/src/main/java/coordinate/Triangle.java @@ -0,0 +1,55 @@ +package coordinate; + +import util.Terminal; + +import java.util.Arrays; + +import static exception.ExceptionMessage.NO_SHAPE; + +public class Triangle extends Shape implements GeometricElement { + + protected Triangle(Point[] in) { + super(in); + System.arraycopy(in, 0, vertexes, 0, in.length); + validate(); + } + + @Override + public double calculate() { + double a = new Line(vertexes[0], vertexes[1]).calculate(); + double b = new Line(vertexes[0], vertexes[2]).calculate(); + double c = new Line(vertexes[1], vertexes[2]).calculate(); + + double s = (a + b + c) / 2; + + return Math.sqrt(s * (s - a) * (s - b) * (s - c)); + } + + @Override + public void printCalculateResult() { + String message = String.format("삼각형 넓이는 %.1f", this.calculate()); + Terminal.out(message); + } + + @Override + public void validate() { + int dx = vertexes[0].getX() - vertexes[1].getX(); + int dy = vertexes[0].getY() - vertexes[1].getY(); + + double slope1 = Math.abs((double) dy / dx); + + dx = vertexes[0].getX() - vertexes[2].getX(); + dy = vertexes[0].getY() - vertexes[2].getY(); + + double slope2 = Math.abs((double) dy / dx); + + if (slope1 == slope2) { + throw new ArithmeticException(String.format(NO_SHAPE.getMessage(), this.getClass().getSimpleName())); + } + } + + @Override + public Point[] getVertex() { + return Arrays.copyOf(vertexes, 3); + } +} diff --git a/src/main/java/exception/ExceptionMessage.java b/src/main/java/exception/ExceptionMessage.java new file mode 100644 index 00000000..08dfbaa3 --- /dev/null +++ b/src/main/java/exception/ExceptionMessage.java @@ -0,0 +1,22 @@ +package exception; + +public enum ExceptionMessage { + NO_INPUT("No Input."), + NO_TWO_DIMENSION_POINT("The input is not a two dimension point."), + INPUT_NOT_NUMBER("The input is not a number."), + INPUT_OUT_OF_RANGE("allow range for input is from %d to %d."), + NO_LINE_OR_SHAPE("No Line or Shape."), + NO_SHAPE("No %s."); + + + private final String message; + + ExceptionMessage(String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } + +} diff --git a/src/main/java/util/Plate.java b/src/main/java/util/Plate.java new file mode 100644 index 00000000..c7e813b4 --- /dev/null +++ b/src/main/java/util/Plate.java @@ -0,0 +1,61 @@ +package util; + +import coordinate.Point; + +import java.util.Arrays; + +public class Plate { + private final String[][] plate; + + public Plate() { + this.plate = new String[26][26]; + for (int i = 0; i < plate.length; i++) { + String[] row = new String[27]; + Arrays.fill(row, " "); + plate[i] = row; + } + + for (int i = 0; i < 24; i++) { + plate[i][1] = "|"; + if ((24 - i) % 2 == 0) { + plate[i][0] = " "; + } else { + plate[i][0] = String.format("%2d", 24 - i); + } + } + + plate[24][0] = " "; + plate[24][1] = "+"; + plate[25][0] = " 0"; + + for (int i = 2; i < 26; i++) { + plate[24][i] = "---"; + if ((24 - i) % 2 != 0) { + plate[25][i] = " "; + } else { + plate[25][i] = String.format(" %-2d", i - 1); + } + } + + plate[24][1] = "+"; + plate[25][1] = " "; + } + + public void drawPoints(Point[] points) { + for (Point point : points) { + plate[24 - point.getX()][point.getY() + 1] = " * "; + } + } + + public void print() { + StringBuilder painter = new StringBuilder(); + for (String[] row : plate) { + for (String data : row) { + painter.append(data); + } + painter.append(System.lineSeparator()); + } + + Terminal.out(painter.toString()); + } +} diff --git a/src/main/java/util/Terminal.java b/src/main/java/util/Terminal.java new file mode 100644 index 00000000..de10119f --- /dev/null +++ b/src/main/java/util/Terminal.java @@ -0,0 +1,19 @@ +package util; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class Terminal { + + private static final BufferedReader BUFFERED_READER = new BufferedReader(new InputStreamReader(System.in)); + + public static String in(String message) throws IOException { + System.out.print(message); + return BUFFERED_READER.readLine(); + } + + public static void out(String message) { + System.out.println(message); + } +} diff --git a/src/test/java/coordinate/GeometricElementFactoryTest.java b/src/test/java/coordinate/GeometricElementFactoryTest.java new file mode 100644 index 00000000..438d7c13 --- /dev/null +++ b/src/test/java/coordinate/GeometricElementFactoryTest.java @@ -0,0 +1,53 @@ +package coordinate; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +public class GeometricElementFactoryTest { + + @Test + void 좌표_두개_입력() { + // given + Point[] points = new Point[2]; + points[0] = new Point(10, 10); + points[1] = new Point(14, 15); + + // when + GeometricElement result = GeometricFactory.getGeometricElement(points); + + // then + assertThat(result.getClass()).isEqualTo(Line.class); + } + + @Test + void 좌표_네개_입력() { + // given + Point[] points = new Point[4]; + points[0] = new Point(10, 10); + points[1] = new Point(22, 10); + points[2] = new Point(22, 18); + points[3] = new Point(10, 18); + + // when + GeometricElement result = GeometricFactory.getGeometricElement(points); + + // then + assertThat(result.getClass()).isEqualTo(Rectangle.class); + } + + @Test + void 좌표_세개_입력() { + // given + Point[] points = new Point[3]; + points[0] = new Point(10, 10); + points[1] = new Point(14, 15); + points[2] = new Point(20, 8); + + // when + GeometricElement result = GeometricFactory.getGeometricElement(points); + + // then + assertThat(result.getClass()).isEqualTo(Triangle.class); + } +} diff --git a/src/test/java/coordinate/LineTest.java b/src/test/java/coordinate/LineTest.java new file mode 100644 index 00000000..e3cfa5f6 --- /dev/null +++ b/src/test/java/coordinate/LineTest.java @@ -0,0 +1,39 @@ +package coordinate; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static coordinate.PointConverter.getPoints; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; + +class LineTest { + + @ParameterizedTest + @CsvSource(value = {"[10,14]:[14,15]"}, delimiter = ':') + void 생성(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + Line line = new Line(points); + + // when + Point[] result = line.getEndPoints(); + + // then + assertThat(result).containsExactly(points); + } + + @ParameterizedTest + @CsvSource(value = {"[10,14]:[10,15]"}, delimiter = ':') + void 거리_계산(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + Line line = new Line(points); + + // when + double result = line.calculate(); + + // then + assertThat(result).isEqualTo(6.403, offset(0.009)); + } +} \ No newline at end of file diff --git a/src/test/java/coordinate/PointConverter.java b/src/test/java/coordinate/PointConverter.java new file mode 100644 index 00000000..3cb354ea --- /dev/null +++ b/src/test/java/coordinate/PointConverter.java @@ -0,0 +1,25 @@ +package coordinate; + +import java.util.Arrays; + +public class PointConverter { + + public static Point[] getPoints(String xStr, String yStr) { + int[] x = getArray(xStr); + int[] y = getArray(yStr); + + Point[] points = new Point[x.length]; + for (int i = 0; i < x.length; i++) { + Point point = new Point(x[i], y[i]); + points[i] = point; + } + + return points; + } + + public static int[] getArray(String s) { + return Arrays.stream(s.replace("[", "").replace("]", "").split(",")) + .mapToInt(c -> Integer.parseInt(c.trim())) + .toArray(); + } +} diff --git a/src/test/java/coordinate/PointMakerTest.java b/src/test/java/coordinate/PointMakerTest.java new file mode 100644 index 00000000..f0b0035b --- /dev/null +++ b/src/test/java/coordinate/PointMakerTest.java @@ -0,0 +1,59 @@ +package coordinate; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.ValueSource; + +import static coordinate.PointConverter.getPoints; +import static org.assertj.core.api.Assertions.assertThat; + +public class PointMakerTest { + + @ParameterizedTest + @ValueSource(strings = {"(25,10)-(10,25)", "(0,13)-(23,0)", "(-1,17)-(8,-1)"}) + void 좌표_입력_테스트_범위_초과(String input) { + // when + // then + IllegalArgumentException result = Assertions.assertThrows(IllegalArgumentException.class, () -> PointMaker.toPoints(input)); + + assertThat(result.getMessage()).contains("input is from 1 to 24"); + } + + @ParameterizedTest + @ValueSource(strings = {"(ㄱ,10)-(10,3)", "(4,A)-(23,5)", "(10,17)-(8,$)"}) + void 좌표_입력_테스트_숫자가_아님(String input) { + // when + // then + ArithmeticException result = Assertions.assertThrows(ArithmeticException.class, () -> PointMaker.toPoints(input)); + + assertThat(result.getMessage()).contains("The input is not a number"); + } + + @ParameterizedTest + @ValueSource(strings = {"(,3)-(5,2)", "(4,1)-(2,)", "(4,1)-( ,5)", "(5, )-(2,3)"}) + void 좌표_입력_테스트_공백_입력됨(String input) { + // when + // then + ArithmeticException result = Assertions.assertThrows(ArithmeticException.class, () -> PointMaker.toPoints(input)); + + assertThat(result.getMessage()).contains("The input is not a two dimension point."); + } + + @ParameterizedTest + @CsvSource(value = { + "(10,10)-(14,15):[10,14]:[10,15]", + "(24,10)-(10,24):[24,10]:[10,24]", + "(1,5)-(5,1):[1,5]:[5,1]" + }, delimiter = ':') + void 좌표_입력_테스트(String input, String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + + // when + Point[] result = PointMaker.toPoints(input); + + // then + assertThat(result).containsExactly(points); + } +} \ No newline at end of file diff --git a/src/test/java/coordinate/RectangleTest.java b/src/test/java/coordinate/RectangleTest.java new file mode 100644 index 00000000..9ec60ef6 --- /dev/null +++ b/src/test/java/coordinate/RectangleTest.java @@ -0,0 +1,54 @@ +package coordinate; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static coordinate.PointConverter.getPoints; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class RectangleTest { + + @ParameterizedTest + @CsvSource(value = {"[10,22,22,10]:[10,10,18,18]"}, delimiter = ':') + void 생성_성공(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + + // when + Rectangle rectangle = new Rectangle(points); + Point[] result = rectangle.getVertex(); + + // then + assertThat(result).contains(points); + } + + @ParameterizedTest + @CsvSource(value = {"[10,22,22,10]:[10,10,19,18]"}, delimiter = ':') + void 생성_실패(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + + // when + // then + ArithmeticException result = assertThrows(ArithmeticException.class, + () -> new Rectangle(points)); + + assertThat(result.getMessage()).contains("No Rectangle"); + } + + @ParameterizedTest + @CsvSource(value = {"[10,22,22,10]:[10,10,18,18]"}, delimiter = ':') + void 넓이_계산(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + Rectangle rectangle = new Rectangle(points); + + // when + double result = rectangle.calculate(); + + // then + assertThat(result).isEqualTo(96, offset(0.1)); + } +} diff --git a/src/test/java/coordinate/TriangleTest.java b/src/test/java/coordinate/TriangleTest.java new file mode 100644 index 00000000..e07408ba --- /dev/null +++ b/src/test/java/coordinate/TriangleTest.java @@ -0,0 +1,54 @@ +package coordinate; + +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; + +import static coordinate.PointConverter.getPoints; +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class TriangleTest { + + @ParameterizedTest + @CsvSource(value = {"[10,14,20]:[10,15,8]"}, delimiter = ':') + void 생성_성공(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + + // when + Triangle triangle = new Triangle(points); + Point[] result = triangle.getVertex(); + + // then + assertThat(result).contains(points); + } + + @ParameterizedTest + @CsvSource(value = {"[10,10,10]:[10,15,8]"}, delimiter = ':') + void 생성_실패(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + + // when + // then + ArithmeticException result = assertThrows(ArithmeticException.class, + () -> new Triangle(points)); + + assertThat(result.getMessage()).contains("No Triangle"); + } + + @ParameterizedTest + @CsvSource(value = {"[10,14,20]:[10,15,8]"}, delimiter = ':') + void 넓이_계산(String xStr, String yStr) { + // given + Point[] points = getPoints(xStr, yStr); + Triangle triangle = new Triangle(points); + + // when + double result = triangle.calculate(); + + // then + assertThat(result).isEqualTo(29, offset(0.1)); + } +}