Added RestaurantResponse class and ResponseDetails bar
This commit is contained in:
parent
ca1f7a6cd7
commit
613792fda3
7 changed files with 274 additions and 102 deletions
138
pom.xml
138
pom.xml
|
@ -1,50 +1,92 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
<modelVersion>4.0.0</modelVersion>
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<groupId>com.rohitawate</groupId>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<artifactId>RESTaurant</artifactId>
|
<groupId>com.rohitawate</groupId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<artifactId>RESTaurant</artifactId>
|
||||||
<packaging>jar</packaging>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<properties>
|
<packaging>jar</packaging>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
</properties>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
<dependencies>
|
</properties>
|
||||||
<!-- https://mvnrepository.com/artifact/com.jfoenix/jfoenix -->
|
<build>
|
||||||
<dependency>
|
<plugins>
|
||||||
<groupId>com.jfoenix</groupId>
|
<plugin>
|
||||||
<artifactId>jfoenix</artifactId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<version>1.4.0</version>
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
</dependency>
|
<configuration>
|
||||||
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
|
<archive>
|
||||||
<dependency>
|
<manifest>
|
||||||
<groupId>org.glassfish.jersey.core</groupId>
|
<mainClass>com.rohitawate.restaurant.main.Main</mainClass>
|
||||||
<artifactId>jersey-client</artifactId>
|
</manifest>
|
||||||
<version>2.26</version>
|
</archive>
|
||||||
</dependency>
|
</configuration>
|
||||||
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
</plugin>
|
||||||
<dependency>
|
<plugin>
|
||||||
<groupId>javax.ws.rs</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>javax.ws.rs-api</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.1</version>
|
<version>2.4</version>
|
||||||
</dependency>
|
<executions>
|
||||||
<dependency>
|
<execution>
|
||||||
<groupId>org.glassfish.jersey.inject</groupId>
|
<phase>package</phase>
|
||||||
<artifactId>jersey-hk2</artifactId>
|
<goals>
|
||||||
<version>2.26</version>
|
<goal>shade</goal>
|
||||||
</dependency>
|
</goals>
|
||||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
|
<configuration>
|
||||||
<dependency>
|
<minimizeJar>true</minimizeJar>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<createDependencyReducedPom>true</createDependencyReducedPom>
|
||||||
<artifactId>jackson-core</artifactId>
|
<dependencyReducedPomLocation>
|
||||||
<version>2.9.3</version>
|
${java.io.tmpdir}/dependency-reduced-pom.xml
|
||||||
</dependency>
|
</dependencyReducedPomLocation>
|
||||||
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
<relocations>
|
||||||
<dependency>
|
<relocation>
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
<pattern>com.acme.coyote</pattern>
|
||||||
<artifactId>jackson-databind</artifactId>
|
<shadedPattern>hidden.coyote</shadedPattern>
|
||||||
<version>2.9.3</version>
|
</relocation>
|
||||||
</dependency>
|
</relocations>
|
||||||
</dependencies>
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.jfoenix/jfoenix -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jfoenix</groupId>
|
||||||
|
<artifactId>jfoenix</artifactId>
|
||||||
|
<version>1.4.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.glassfish.jersey.core/jersey-client -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.core</groupId>
|
||||||
|
<artifactId>jersey-client</artifactId>
|
||||||
|
<version>2.26</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/javax.ws.rs/javax.ws.rs-api -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>javax.ws.rs</groupId>
|
||||||
|
<artifactId>javax.ws.rs-api</artifactId>
|
||||||
|
<version>2.1</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.glassfish.jersey.inject</groupId>
|
||||||
|
<artifactId>jersey-hk2</artifactId>
|
||||||
|
<version>2.26</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-core</artifactId>
|
||||||
|
<version>2.9.3</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fasterxml.jackson.core</groupId>
|
||||||
|
<artifactId>jackson-databind</artifactId>
|
||||||
|
<version>2.9.3</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
</project>
|
</project>
|
|
@ -16,25 +16,24 @@
|
||||||
package com.rohitawate.restaurant.dashboard;
|
package com.rohitawate.restaurant.dashboard;
|
||||||
|
|
||||||
import com.jfoenix.controls.JFXSnackbar;
|
import com.jfoenix.controls.JFXSnackbar;
|
||||||
|
import com.rohitawate.restaurant.models.RestaurantResponse;
|
||||||
import com.rohitawate.restaurant.requests.RequestManager;
|
import com.rohitawate.restaurant.requests.RequestManager;
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.Initializable;
|
||||||
|
import javafx.scene.control.ComboBox;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.TextArea;
|
||||||
|
import javafx.scene.control.TextField;
|
||||||
|
import javafx.scene.layout.BorderPane;
|
||||||
|
import javafx.scene.layout.HBox;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.logging.Level;
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
import javafx.fxml.FXML;
|
|
||||||
import javafx.fxml.Initializable;
|
|
||||||
import javafx.scene.control.ComboBox;
|
|
||||||
import javafx.scene.control.TextArea;
|
|
||||||
import javafx.scene.control.TextField;
|
|
||||||
import javafx.scene.layout.BorderPane;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* FXML Controller class
|
|
||||||
*
|
|
||||||
* @author Rohit Awate
|
|
||||||
*/
|
|
||||||
public class DashboardController implements Initializable {
|
public class DashboardController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private BorderPane dashboard;
|
private BorderPane dashboard;
|
||||||
|
@ -43,7 +42,13 @@ public class DashboardController implements Initializable {
|
||||||
@FXML
|
@FXML
|
||||||
private ComboBox<String> httpMethodBox;
|
private ComboBox<String> httpMethodBox;
|
||||||
@FXML
|
@FXML
|
||||||
private TextArea responseArea;
|
private VBox responseBox;
|
||||||
|
@FXML
|
||||||
|
private HBox responseDetails;
|
||||||
|
@FXML
|
||||||
|
private TextArea responseArea;
|
||||||
|
@FXML
|
||||||
|
private Label statusCode, statusCodeDescription, responseTime, responseSize;
|
||||||
|
|
||||||
private JFXSnackbar snackBar;
|
private JFXSnackbar snackBar;
|
||||||
private final String[] httpMethods = {"GET", "POST", "PUT", "DELETE", "PATCH"};
|
private final String[] httpMethods = {"GET", "POST", "PUT", "DELETE", "PATCH"};
|
||||||
|
@ -51,7 +56,8 @@ public class DashboardController implements Initializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL url, ResourceBundle rb) {
|
public void initialize(URL url, ResourceBundle rb) {
|
||||||
httpMethodBox.getItems().addAll(httpMethods);
|
responseBox.getChildren().remove(0);
|
||||||
|
httpMethodBox.getItems().addAll(httpMethods);
|
||||||
httpMethodBox.setValue("GET");
|
httpMethodBox.setValue("GET");
|
||||||
responseArea.wrapTextProperty().set(true);
|
responseArea.wrapTextProperty().set(true);
|
||||||
|
|
||||||
|
@ -67,14 +73,22 @@ public class DashboardController implements Initializable {
|
||||||
snackBar.show("Please enter a valid address", 7000);
|
snackBar.show("Please enter a valid address", 7000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
String response = "";
|
RestaurantResponse response;
|
||||||
URL url = new URL(address);
|
URL url = new URL(address);
|
||||||
switch (httpMethodBox.getValue()) {
|
switch (httpMethodBox.getValue()) {
|
||||||
case "GET":
|
case "GET":
|
||||||
response = requestManager.get(url);
|
response = requestManager.get(url);
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
response = new RestaurantResponse();
|
||||||
}
|
}
|
||||||
responseArea.setText(response);
|
responseArea.setText(response.getBody());
|
||||||
|
if (responseBox.getChildren().size() != 2)
|
||||||
|
responseBox.getChildren().add(0, responseDetails);
|
||||||
|
statusCode.setText(Integer.toString(response.getStatusCode()));
|
||||||
|
statusCodeDescription.setText(Response.Status.fromStatusCode(response.getStatusCode()).getReasonPhrase());
|
||||||
|
responseTime.setText(Long.toString(response.getTime()) + " ms");
|
||||||
|
responseSize.setText(Integer.toString(response.getSize()) + " B");
|
||||||
} catch (MalformedURLException ex) {
|
} catch (MalformedURLException ex) {
|
||||||
snackBar.show("Invalid URL. Please verify and try again.", 7000);
|
snackBar.show("Invalid URL. Please verify and try again.", 7000);
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
|
|
|
@ -21,10 +21,6 @@ import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Rohit Awate
|
|
||||||
*/
|
|
||||||
public class Main extends Application {
|
public class Main extends Application {
|
||||||
@Override
|
@Override
|
||||||
public void start(Stage primaryStage) throws Exception {
|
public void start(Stage primaryStage) throws Exception {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Rohit Awate.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.rohitawate.restaurant.models;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
public class RestaurantResponse {
|
||||||
|
private String body;
|
||||||
|
private int statusCode;
|
||||||
|
private long time;
|
||||||
|
private int size;
|
||||||
|
private MediaType mediaType;
|
||||||
|
|
||||||
|
public String getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setBody(String body) {
|
||||||
|
this.body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTime() {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTime(long initialTime, long finalTime) {
|
||||||
|
this.time = finalTime - initialTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSize() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSize(int size) {
|
||||||
|
this.size = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
public MediaType getMediaType() {
|
||||||
|
return mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMediaType(MediaType mediaType) {
|
||||||
|
this.mediaType = mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getStatusCode() {
|
||||||
|
return statusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatusCode(int statusCode) {
|
||||||
|
this.statusCode = statusCode;
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,48 +18,55 @@ package com.rohitawate.restaurant.requests;
|
||||||
import com.fasterxml.jackson.databind.JsonNode;
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||||
import java.io.IOException;
|
import com.rohitawate.restaurant.models.RestaurantResponse;
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import javax.ws.rs.client.Client;
|
import javax.ws.rs.client.Client;
|
||||||
import javax.ws.rs.client.ClientBuilder;
|
import javax.ws.rs.client.ClientBuilder;
|
||||||
import javax.ws.rs.client.WebTarget;
|
import javax.ws.rs.client.WebTarget;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Rohit Awate
|
|
||||||
*/
|
|
||||||
public class RequestManager {
|
public class RequestManager {
|
||||||
|
|
||||||
private final Client client;
|
private final Client client;
|
||||||
|
|
||||||
public RequestManager() {
|
public RequestManager() {
|
||||||
client = ClientBuilder.newClient();
|
client = ClientBuilder.newClient();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String get(URL url) throws MalformedURLException, IOException {
|
public RestaurantResponse get(URL url) throws IOException {
|
||||||
String responseBody;
|
RestaurantResponse response = new RestaurantResponse();
|
||||||
WebTarget target = client.target(url.toString());
|
WebTarget target = client.target(url.toString());
|
||||||
|
|
||||||
Response response = target.request().get();
|
long initialTime = System.currentTimeMillis();
|
||||||
String type = (String) response.getHeaders().getFirst("Content-type");
|
Response serverResponse = target.request().get();
|
||||||
System.out.println(type);
|
response.setTime(initialTime, System.currentTimeMillis());
|
||||||
responseBody = response.readEntity(String.class);
|
|
||||||
|
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
if (serverResponse == null)
|
||||||
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
throw new IOException();
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case "application/json":
|
|
||||||
JsonNode node = mapper.readTree(responseBody);
|
|
||||||
responseBody = mapper.writeValueAsString(node);
|
|
||||||
break;
|
|
||||||
case "application/xml":
|
|
||||||
responseBody = mapper.writeValueAsString(responseBody);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return responseBody;
|
String type = (String) serverResponse.getHeaders().getFirst("Content-type");
|
||||||
}
|
System.out.println(type);
|
||||||
|
String responseBody = serverResponse.readEntity(String.class);
|
||||||
|
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case "application/json":
|
||||||
|
JsonNode node = mapper.readTree(responseBody);
|
||||||
|
response.setBody(mapper.writeValueAsString(node));
|
||||||
|
break;
|
||||||
|
case "application/xml":
|
||||||
|
response.setBody(mapper.writeValueAsString(responseBody));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
response.setMediaType(serverResponse.getMediaType());
|
||||||
|
response.setStatusCode(serverResponse.getStatus());
|
||||||
|
response.setSize(responseBody.length());
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<?import com.jfoenix.controls.JFXButton?>
|
<?import com.jfoenix.controls.JFXButton?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.ComboBox?>
|
<?import javafx.scene.control.ComboBox?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
<?import javafx.scene.control.TextArea?>
|
<?import javafx.scene.control.TextArea?>
|
||||||
<?import javafx.scene.control.TextField?>
|
<?import javafx.scene.control.TextField?>
|
||||||
<?import javafx.scene.image.Image?>
|
<?import javafx.scene.image.Image?>
|
||||||
|
@ -55,7 +56,48 @@
|
||||||
<Insets bottom="20.0" top="20.0" />
|
<Insets bottom="20.0" top="20.0" />
|
||||||
</padding>
|
</padding>
|
||||||
</HBox>
|
</HBox>
|
||||||
<TextArea fx:id="responseArea" prefHeight="200.0" prefWidth="200.0" VBox.vgrow="ALWAYS" />
|
<VBox fx:id="responseBox" VBox.vgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<HBox fx:id="responseDetails" alignment="CENTER_RIGHT" maxHeight="50.0" minHeight="50.0">
|
||||||
|
<children>
|
||||||
|
<HBox alignment="CENTER_LEFT" HBox.hgrow="ALWAYS">
|
||||||
|
<children>
|
||||||
|
<Label fx:id="statusCode" text="404" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="35.0"/>
|
||||||
|
</font>
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets right="10.0"/>
|
||||||
|
</HBox.margin>
|
||||||
|
</Label>
|
||||||
|
<Label fx:id="statusCodeDescription" text="Not Found" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font size="30.0"/>
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
</HBox>
|
||||||
|
<Label fx:id="responseTime" text="151 ms" textFill="WHITE">
|
||||||
|
<HBox.margin>
|
||||||
|
<Insets right="30.0"/>
|
||||||
|
</HBox.margin>
|
||||||
|
<font>
|
||||||
|
<Font name="Liberation Mono" size="20.0"/>
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
<Label fx:id="responseSize" layoutX="1187.0" layoutY="23.0" text="1998 B" textFill="WHITE">
|
||||||
|
<font>
|
||||||
|
<Font name="Liberation Mono" size="20.0"/>
|
||||||
|
</font>
|
||||||
|
</Label>
|
||||||
|
</children>
|
||||||
|
<padding>
|
||||||
|
<Insets bottom="15.0" left="15.0" right="15.0" top="15.0"/>
|
||||||
|
</padding>
|
||||||
|
</HBox>
|
||||||
|
<TextArea fx:id="responseArea" wrapText="true" VBox.vgrow="ALWAYS"/>
|
||||||
|
</children>
|
||||||
|
</VBox>
|
||||||
</children>
|
</children>
|
||||||
<padding>
|
<padding>
|
||||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||||
|
|
|
@ -31,6 +31,10 @@
|
||||||
-fx-background-color: #c45015;
|
-fx-background-color: #c45015;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#responseDetails {
|
||||||
|
-fx-background-color: #1b1b1b;
|
||||||
|
}
|
||||||
|
|
||||||
#responseArea {
|
#responseArea {
|
||||||
-fx-font-family: 'Liberation Mono';
|
-fx-font-family: 'Liberation Mono';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue