This commit is contained in:
ajay74984 2020-03-07 15:21:31 +01:00
commit eedd3ff6ea
25 changed files with 825 additions and 18 deletions

View File

@ -39,6 +39,16 @@
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-commons</artifactId>
<version>${junit.platform.version}</version>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
@ -66,6 +76,8 @@
<commons-codec.version>1.11</commons-codec.version>
<commons-math3.version>3.6.1</commons-math3.version>
<guava.version>28.1-jre</guava.version>
<jackson.version>2.10.2</jackson.version>
<junit.platform.version>1.6.0</junit.platform.version>
</properties>
</project>

View File

@ -0,0 +1,61 @@
package com.baeldung.algorithms.boruvka;
public class BoruvkaMST {
private static Tree mst = new Tree();
private static int totalWeight;
public BoruvkaMST(Graph graph) {
DisjointSet dSet = new DisjointSet(graph.getNodes());
// repeat at most log N times or until we have N-1 edges
for (int t = 1; t < graph.getNodes() && mst.getEdgeCount() < graph.getNodes() - 1; t = t + t) {
// foreach tree in forest, find closest edge
Edge[] closestEdgeArray = new Edge[graph.getNodes()];
for (Edge edge : graph.getAllEdges()) {
int first = edge.getFirst();
int second = edge.getSecond();
int firstParent = dSet.getParent(first);
int secondParent = dSet.getParent(second);
if (firstParent == secondParent) {
continue; // same tree
}
if (closestEdgeArray[firstParent] == null || edge.getWeight() < closestEdgeArray[firstParent].getWeight()) {
closestEdgeArray[firstParent] = edge;
}
if (closestEdgeArray[secondParent] == null || edge.getWeight() < closestEdgeArray[secondParent].getWeight()) {
closestEdgeArray[secondParent] = edge;
}
}
// add newly discovered edges to MST
for (int i = 0; i < graph.getNodes(); i++) {
Edge edge = closestEdgeArray[i];
if (edge != null) {
int first = edge.getFirst();
int second = edge.getSecond();
// don't add the same edge twice
if (dSet.getParent(first) != dSet.getParent(second)) {
mst.addEdge(edge);
totalWeight += edge.getWeight();
dSet.union(first, second);
}
}
}
}
}
public Iterable<Edge> getMST() {
return mst;
}
public int getTotalWeight() {
return totalWeight;
}
public String toString() {
return "MST: " + mst.toString() + " | Total Weight: " + totalWeight;
}
}

View File

@ -0,0 +1,49 @@
package com.baeldung.algorithms.boruvka;
import java.util.Arrays;
public class DisjointSet {
private int[] nodeParents;
private int[] nodeRanks;
public DisjointSet(int n) {
nodeParents = new int[n];
nodeRanks = new int[n];
for (int i = 0; i < n; i++) {
nodeParents[i] = i;
nodeRanks[i] = 0;
}
}
public int getParent(int node) {
while (node != nodeParents[node]) {
node = nodeParents[node];
}
return node;
}
public void union(int node1, int node2) {
int node1Parent = getParent(node1);
int node2Parent = getParent(node2);
if (node1Parent == node2Parent) {
return;
}
if (nodeRanks[node1Parent] < nodeRanks[node2Parent]) {
nodeParents[node1Parent] = node2Parent;
}
else if (nodeRanks[node1Parent] > nodeRanks[node2Parent]) {
nodeParents[node2Parent] = node1Parent;
}
else {
nodeParents[node2Parent] = node1Parent;
nodeRanks[node1Parent]++;
}
}
public String toString() {
return "Parent: " + Arrays.toString(nodeParents) + "Rank: " + Arrays.toString(nodeRanks);
}
}

View File

@ -0,0 +1,40 @@
package com.baeldung.algorithms.boruvka;
public class Edge {
private final int first;
private final int second;
private final int weight;
public Edge(int first, int second, int weight) {
this.first = first;
this.second = second;
this.weight = weight;
}
public double getWeight() {
return weight;
}
public int getFirst() {
return first;
}
public int getSecond() {
return second;
}
public int getOtherNode(int firstNode) {
int secondNode = 0;
if (firstNode == first)
secondNode = second;
else if (firstNode == second)
secondNode = first;
return secondNode;
}
public String toString() {
return String.format("%d-%d %d", first, second, weight);
}
}

View File

@ -0,0 +1,64 @@
package com.baeldung.algorithms.boruvka;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
public class Graph {
private int nodes;
private int edges;
private Tree[] trees;
public Graph(Input jsonGraph) throws JsonParseException, JsonMappingException, IOException {
nodes = jsonGraph.getNodes();
trees = (Tree[]) new Tree[nodes];
for (int i = 0; i < nodes; i++) {
trees[i] = new Tree();
}
int edgesFromInput = jsonGraph.getEdges();
for (int i = 0; i < edgesFromInput; i++) {
int first = jsonGraph.getEdgeList()
.get(i)
.getFirst();
int second = jsonGraph.getEdgeList()
.get(i)
.getSecond();
int weight = jsonGraph.getEdgeList()
.get(i)
.getWeight();
Edge edge = new Edge(first, second, weight);
trees[first].addEdge(edge);
trees[second].addEdge(edge);
edges++;
}
}
public int getNodes() {
return nodes;
}
public int getEdges() {
return edges;
}
public Iterable<Edge> iterableTree(int i) {
return trees[i];
}
public Iterable<Edge> getAllEdges() {
Iterable<Edge> list = new Tree();
for (int i = 0; i < nodes; i++) {
for (Edge edge : iterableTree(i)) {
if (edge.getOtherNode(i) > i) {
((Tree) list).addEdge(edge);
}
}
}
return list;
}
}

View File

@ -0,0 +1,65 @@
package com.baeldung.algorithms.boruvka;
import java.util.List;
public class Input {
private int nodes;
private int edges;
private List<E> edgeList;
public int getNodes() {
return nodes;
}
public void setNodes(int nodes) {
this.nodes = nodes;
}
public int getEdges() {
return edges;
}
public void setEdges(int edges) {
this.edges = edges;
}
public List<E> getEdgeList() {
return edgeList;
}
public void setEdgeList(List<E> edgeList) {
this.edgeList = edgeList;
}
static class E {
private int first;
private int second;
private int weight;
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}
public int getSecond() {
return second;
}
public void setSecond(int second) {
this.second = second;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}
}

View File

@ -0,0 +1,63 @@
package com.baeldung.algorithms.boruvka;
import java.util.Iterator;
public class Tree implements Iterable<Edge> {
private Node root;
private int edgeCount;
private static class Node {
private Edge edge;
private Node next;
public String toString() {
String nextStr = next != null ? next.toString() : "";
return edge.toString() + " | " + nextStr;
}
}
public Tree() {
root = null;
edgeCount = 0;
}
public int getEdgeCount() {
return edgeCount;
}
public void addEdge(Edge edge) {
Node oldRoot = root;
root = new Node();
root.edge = edge;
root.next = oldRoot;
edgeCount++;
}
public String toString() {
String rootStr = root != null ? root.toString() : "";
return "Tree: " + rootStr + "Size: " + edgeCount;
}
public Iterator<Edge> iterator() {
return new LinkedIterator(root);
}
private class LinkedIterator implements Iterator<Edge> {
private Node current;
public LinkedIterator(Node root) {
current = root;
}
public boolean hasNext() {
return current != null;
}
public Edge next() {
Edge edge = current.edge;
current = current.next;
return edge;
}
}
}

View File

@ -0,0 +1,48 @@
package com.baeldung.algorithms.boruvka;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.junit.Before;
import org.junit.Test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class BoruvkaUnitTest {
private Input input;
private static String INPUT_JSON = "/input.json";
@Before
public void convertInputJsonToObject() throws JsonParseException, JsonMappingException, IOException {
ObjectMapper mapper = new ObjectMapper();
StringBuilder jsonStr = new StringBuilder();
try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(BoruvkaMST.class.getResourceAsStream(INPUT_JSON)))) {
String line;
while ((line = bufferedReader.readLine()) != null) {
jsonStr.append(line)
.append("\n");
}
}
input = mapper.readValue(jsonStr.toString(), Input.class);
}
@Test
public void givenInputGraph_whenBoruvkaPerformed_thenMinimumSpanningTree() throws JsonParseException, JsonMappingException, IOException {
Graph graph = new Graph(input);
BoruvkaMST boruvkaMST = new BoruvkaMST(graph);
Tree mst = (Tree) boruvkaMST.getMST();
assertEquals(30, boruvkaMST.getTotalWeight());
assertEquals(4, mst.getEdgeCount());
}
}

View File

@ -0,0 +1,41 @@
{
"nodes": 5,
"edges": 7,
"edgeList": [
{
"first": 0,
"second": 1,
"weight": 8
},
{
"first": 0,
"second": 2,
"weight": 5
},
{
"first": 1,
"second": 2,
"weight": 9
},
{
"first": 1,
"second": 3,
"weight": 11
},
{
"first": 2,
"second": 3,
"weight": 15
},
{
"first": 2,
"second": 4,
"weight": 10
},
{
"first": 3,
"second": 4,
"weight": 7
}
]
}

43
apache-beam/pom.xml Normal file
View File

@ -0,0 +1,43 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<groupId>com.baeldung.apache</groupId>
<artifactId>apache-beam</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-sdks-java-core</artifactId>
<version>${beam.version}</version>
</dependency>
<!-- runtime scoped -->
<dependency>
<groupId>org.apache.beam</groupId>
<artifactId>beam-runners-direct-java</artifactId>
<version>${beam.version}</version>
<scope>runtime</scope>
</dependency>
<!-- test scoped -->
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>${assertj.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<beam.version>2.19.0</beam.version>
<assertj.version>3.6.1</assertj.version>
</properties>
</project>

View File

@ -0,0 +1,71 @@
package com.baeldung.apache.beam.intro;
import java.util.Arrays;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.TextIO;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.transforms.Count;
import org.apache.beam.sdk.transforms.Filter;
import org.apache.beam.sdk.transforms.FlatMapElements;
import org.apache.beam.sdk.transforms.MapElements;
import org.apache.beam.sdk.values.KV;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.sdk.values.TypeDescriptors;
public class WordCount {
public static boolean wordCount(String inputFilePath, String outputFilePath) {
// We use default options
PipelineOptions options = PipelineOptionsFactory.create();
// to create the pipeline
Pipeline p = Pipeline.create(options);
// Here is our workflow graph
PCollection<KV<String, Long>> wordCount = p
.apply("(1) Read all lines", TextIO.read().from(inputFilePath))
.apply("(2) Flatmap to a list of words", FlatMapElements.into(TypeDescriptors.strings())
.via(line -> Arrays.asList(line.split("\\s"))))
.apply("(3) Lowercase all", MapElements.into(TypeDescriptors.strings())
.via(word -> word.toLowerCase()))
.apply("(4) Trim punctuations", MapElements.into(TypeDescriptors.strings())
.via(word -> trim(word)))
.apply("(5) Filter stopwords", Filter.by(word -> !isStopWord(word)))
.apply("(6) Count words", Count.perElement());
// We convert the PCollection to String so that we can write it to file
wordCount.apply(MapElements.into(TypeDescriptors.strings())
.via(count -> count.getKey() + " --> " + count.getValue()))
.apply(TextIO.write().to(outputFilePath));
// Finally we must run the pipeline, otherwise it's only a definition
p.run().waitUntilFinish();
return true;
}
public static boolean isStopWord(String word) {
String[] stopwords = {"am", "are", "is", "i", "you", "me",
"he", "she", "they", "them", "was",
"were", "from", "in", "of", "to", "be",
"him", "her", "us", "and", "or"};
for (String stopword : stopwords) {
if (stopword.compareTo(word) == 0) {
return true;
}
}
return false;
}
public static String trim(String word) {
return word.replace("(","")
.replace(")", "")
.replace(",", "")
.replace(".", "")
.replace("\"", "")
.replace("'", "")
.replace(":", "")
.replace(";", "")
.replace("-", "")
.replace("?", "")
.replace("!", "");
}
}

View File

@ -0,0 +1,19 @@
package com.baeldung.apache.beam.intro;
import static org.junit.Assert.assertTrue;
import org.junit.Ignore;
import org.junit.Test;
import com.baeldung.apache.beam.intro.WordCount;
public class WordCountUnitTest {
@Test
// @Ignore
public void givenInputFile_whenWordCountRuns_thenJobFinishWithoutError() {
boolean jobDone = WordCount.wordCount("src/test/resources/wordcount.txt", "target/output");
assertTrue(jobDone);
}
}

View File

@ -0,0 +1,16 @@
We've all heard the scare stories about North Korea: the homemade nuclear arsenal built while their people starve and then aimed imprecisely at the rest of the world, a
leader so deluded he makes L Ron Hubbard look like a man excessively overburdened with self-doubt and their deep-seated belief that foreign capitalists will invade at any
moment and steal all their bauxite.
The popular portrayal of this Marxist nation is something like one of the more harrowing episodes of M*A*S*H, only with the cast of wacky characters replaced by twitchy,
heavily armed Stalinist meth addicts
Cracked would like to take a moment to celebrate the good things about North Korea though, the things that the country's enemies prefer to suppress as part of their politically
motivated jealousy. Like how no different to you and me, there's nothing every North Korean likes more after an 18 hour shift at the phosphorus plant than a nice beer to go with
his dried fish ration. Ever attentive to its people's needs and in the twinkling of a decade, North Korea's leadership bought, disassembled, transported and rebuilt a British
brewery in order to discover and reproduce the secrets of beer and then brew the sweet nectar for its hardworking people, up to 18 bottles at a time. And with minimal fatalities.
When was the last time YOUR leader got a beer for YOU, American? (NB do not answer this question if you are Henry Louis Gates).
Or how about the fried chicken restaurant that downtown Pyongyang boasts? Yes real chicken, fried and then delivered to your sleeping cube, with optional beer if you like! You
don't even have to remove the feathers or pull out the gizzard yourself. Mostly. Americans must eat their fried chicken from a bucket, like swine, sold by a company so secretive
that even the very blend of seasoning used is intentionally kept from them. And they call North Korea paranoid?
And how many nations would entertain the syphilitic, bourgeois ramblings of Bill Clinton let alone permit him anywhere near their proud womenfolk? Only wise Kim Jong Il could see
past Bill's many, many imperfections and treat him with the pity and kindness he deserves, accepting his feeble pleas to pardon the American spies rightly convicted of photographing
the nation's sensitive beetroot fields.

View File

@ -0,0 +1,28 @@
package com.baeldung.threaddump;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public class ThreadDump {
public static void main(String[] args) throws IOException {
threadDump(true, true);
}
private static void threadDump(boolean lockedMonitors, boolean lockedSynchronizers) throws IOException {
Path threadDumpFile = Paths.get("ThreadDump.txt");
StringBuffer threadDump = new StringBuffer(System.lineSeparator());
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
for(ThreadInfo threadInfo : threadMXBean.dumpAllThreads(lockedMonitors, lockedSynchronizers)) {
threadDump.append(threadInfo.toString());
}
Files.write(threadDumpFile, threadDump.toString().getBytes());
}
}

View File

@ -862,6 +862,7 @@
<module>antlr</module>
<module>apache-avro</module>
<module>apache-beam</module>
<module>apache-bval</module>
<module>apache-curator</module>
<module>apache-cxf</module>

View File

@ -0,0 +1,20 @@
package com.baeldung.version;
import org.springframework.boot.system.JavaVersion;
import org.springframework.boot.system.SystemProperties;
import org.springframework.core.SpringVersion;
public class VersionObtainer {
public String getSpringVersion() {
return SpringVersion.getVersion();
}
public String getJavaVersion() {
return JavaVersion.getJavaVersion().toString();
}
public String getJdkVersion() {
return SystemProperties.get("java.version");
}
}

View File

@ -0,0 +1,30 @@
package com.baeldung.version;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest(classes = VersionObtainer.class)
public class VersionObtainerUnitTest {
public VersionObtainer version = new VersionObtainer();
@Test
public void testGetSpringVersion() {
String res = version.getSpringVersion();
assertThat(res).isNotEmpty();
}
@Test
public void testGetJdkVersion() {
String res = version.getJdkVersion();
assertThat(res).isNotEmpty();
}
@Test
public void testGetJavaVersion() {
String res = version.getJavaVersion();
assertThat(res).isNotEmpty();
}
}

View File

@ -13,6 +13,7 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<dependencies>

View File

@ -0,0 +1,22 @@
# Inject a value to a static field
## How to run
```sh
mvn clean install
mvn spring-boot:run
```
## Request
**GET**
http://localhost:8080/properties
## Response
```json
[
"Inject a value to a static field",
"Inject a value to a static field",
null
]
```

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.baeldung</groupId>
<artifactId>static.value.injection</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>static.value.injection</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,13 @@
package com.baeldung;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

View File

@ -0,0 +1,31 @@
package com.baeldung.controller;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Arrays;
import java.util.List;
@RestController
public class PropertyController {
@Value("${name}")
private String name;
@Value("${name}")
private static String NAME_NULL;
private static String NAME_STATIC;
@Value("${name}")
public void setNameStatic(String name){
PropertyController.NAME_STATIC = name;
}
@GetMapping("/properties")
public List<String> getProperties(){
return Arrays.asList(this.name, NAME_STATIC, NAME_NULL) ;
}
}

View File

@ -0,0 +1 @@
name = Inject a value to a static field

View File

@ -0,0 +1,13 @@
package com.baeldung;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class ApplicationTests {
@Test
void contextLoads() {
}
}

View File

@ -16,48 +16,51 @@ public class MockitoVoidMethodsUnitTest {
@Test
public void whenAddCalledVerified() {
MyList mockVoid = mock(MyList.class);
mockVoid.add(0, "");
verify(mockVoid, times(1)).add(0, "");
MyList myList = mock(MyList.class);
myList.add(0, "");
verify(myList, times(1)).add(0, "");
}
@Test(expected = Exception.class)
public void givenNull_addThrows() {
MyList mockVoid = mock(MyList.class);
doThrow().when(mockVoid).add(isA(Integer.class), isNull());
mockVoid.add(0, null);
MyList myList = mock(MyList.class);
doThrow().when(myList).add(isA(Integer.class), isNull());
myList.add(0, null);
}
@Test
public void whenAddCalledValueCaptured() {
MyList mockVoid = mock(MyList.class);
MyList myList = mock(MyList.class);
ArgumentCaptor<String> valueCapture = ArgumentCaptor.forClass(String.class);
doNothing().when(mockVoid).add(any(Integer.class), valueCapture.capture());
mockVoid.add(0, "captured");
doNothing().when(myList).add(any(Integer.class), valueCapture.capture());
myList.add(0, "captured");
assertEquals("captured", valueCapture.getValue());
}
@Test
public void whenAddCalledAnswered() {
MyList mockVoid = mock(MyList.class);
doAnswer((Answer<Void>) invocation -> {
MyList myList = mock(MyList.class);
doAnswer(invocation -> {
Object arg0 = invocation.getArgument(0);
Object arg1 = invocation.getArgument(1);
//do something with the arguments here
assertEquals(3, arg0);
assertEquals("answer me", arg1);
return null;
}).when(mockVoid).add(any(Integer.class), any(String.class));
mockVoid.add(3, "answer me");
}).when(myList).add(any(Integer.class), any(String.class));
myList.add(3, "answer me");
}
@Test
public void whenAddCalledRealMethodCalled() {
MyList mockVoid = mock(MyList.class);
doCallRealMethod().when(mockVoid).add(any(Integer.class), any(String.class));
mockVoid.add(1, "real");
verify(mockVoid, times(1)).add(1, "real");
MyList myList = mock(MyList.class);
doCallRealMethod().when(myList).add(any(Integer.class), any(String.class));
myList.add(1, "real");
verify(myList, times(1)).add(1, "real");
}
}