├── .github
└── workflows
│ ├── jekyll-docker.yml
│ └── maven-publish.yml
├── Dockerfile
├── LICENSE
├── README.md
├── docker-compose.yml
├── images
└── logo.png
├── pom.xml
└── src
└── main
├── java
└── dev
│ └── leons
│ └── ward
│ ├── Ward.java
│ ├── components
│ ├── ServletComponent.java
│ └── UtilitiesComponent.java
│ ├── configurations
│ └── BeanConfiguration.java
│ ├── controllers
│ ├── ErrorController.java
│ ├── IndexController.java
│ ├── InfoController.java
│ ├── SetupController.java
│ ├── UptimeController.java
│ └── UsageController.java
│ ├── dto
│ ├── ErrorDto.java
│ ├── InfoDto.java
│ ├── MachineDto.java
│ ├── ProcessorDto.java
│ ├── ResponseDto.java
│ ├── SetupDto.java
│ ├── StorageDto.java
│ ├── UptimeDto.java
│ └── UsageDto.java
│ ├── exceptions
│ ├── ApplicationAlreadyConfiguredException.java
│ └── ApplicationNotConfiguredException.java
│ ├── handlers
│ └── ControllerExceptionHandler.java
│ └── services
│ ├── ErrorService.java
│ ├── IndexService.java
│ ├── InfoService.java
│ ├── SetupService.java
│ ├── UptimeService.java
│ └── UsageService.java
└── resources
├── static
├── css
│ ├── animations.css
│ ├── assets
│ │ ├── bootstrap.min.css
│ │ ├── dhtmlx.dark.min.css
│ │ └── dhtmlx.light.min.css
│ ├── colors.css
│ ├── dimensions.css
│ ├── fonts.css
│ ├── gradients.css
│ ├── layout.css
│ ├── shadows.css
│ └── themes.css
├── fonts
│ └── roboto
│ │ ├── bold.woff2
│ │ └── regular.woff2
├── img
│ ├── error
│ │ ├── 404.gif
│ │ └── 500.gif
│ ├── ico
│ │ └── favicon.ico
│ ├── icons
│ │ ├── disk.png
│ │ ├── memory.png
│ │ └── processor.png
│ └── logo
│ │ ├── background.png
│ │ └── clouds
│ │ ├── left.png
│ │ └── right.png
└── js
│ ├── assets
│ ├── chart.min.js
│ ├── dhtmlx.min.js
│ ├── three.min.js
│ └── vanta.min.js
│ ├── background.js
│ ├── chart.js
│ ├── globals.js
│ ├── index.js
│ ├── labels.js
│ └── setup.js
└── templates
├── error
├── 404.html
└── 500.html
├── index.html
└── setup.html
/.github/workflows/jekyll-docker.yml:
--------------------------------------------------------------------------------
1 | name: docker-image
2 | on:
3 | release:
4 | types: [published]
5 | jobs:
6 | build-and-push:
7 | runs-on: ubuntu-latest
8 | steps:
9 | - name: Checkout
10 | uses: actions/checkout@v4
11 | - name: Set up QEMU
12 | uses: docker/setup-qemu-action@v3
13 | - name: Set up Docker Buildx
14 | uses: docker/setup-buildx-action@v3
15 | - name: Login to DockerHub
16 | uses: docker/login-action@v3
17 | with:
18 | username: ${{ secrets.DOCKER_USERNAME }}
19 | password: ${{ secrets.DOCKER_TOKEN }}
20 | - name: Get the tag name
21 | run: echo "TAG=${GITHUB_REF/refs\/tags\//}" >> $GITHUB_ENV
22 | - name: Build and push Docker images
23 | uses: docker/build-push-action@v6.7.0
24 | with:
25 | context: .
26 | push: true
27 | platforms: linux/amd64,linux/arm64,linux/s390x,linux/ppc64le
28 | tags: antonyleons/ward:latest,antonyleons/ward:${{ env.TAG }}
29 |
--------------------------------------------------------------------------------
/.github/workflows/maven-publish.yml:
--------------------------------------------------------------------------------
1 | name: build-jar
2 | on: pull_request
3 | jobs:
4 | build-and-upload:
5 | runs-on: ubuntu-latest
6 | steps:
7 | - uses: actions/checkout@v4
8 | - uses: actions/setup-java@v4
9 | with:
10 | java-version: '17'
11 | distribution: 'temurin'
12 | - run: mvn clean install
13 | - run: mvn clean package
14 | - uses: actions/upload-artifact@v4
15 | with:
16 | name: Ward.jar
17 | path: target/*.jar
18 |
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
1 | # Base image with maven installed already
2 | FROM maven:3.9-eclipse-temurin-17 as builder
3 |
4 | # Copy whole project inside docker
5 | COPY . .
6 |
7 | # Build project
8 | RUN mvn clean package
9 |
10 |
11 | # Base image containing OpenJDK 17
12 | FROM eclipse-temurin:17-jre
13 |
14 | # Copy jar and pom from builder image to working directory
15 | COPY --from=builder target/*.jar /ward.jar
16 | COPY --from=builder pom.xml /pom.xml
17 |
18 | EXPOSE 4000
19 |
20 | # Run jar as sudo user on entry point
21 | ENTRYPOINT java -jar ward.jar
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 B-Software
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Ward_CN
2 | Ward性能监控的中文版本
3 | 原项目:https://github.com/AntonyLeons/Ward
4 |
5 | ### 关于
6 |
7 | Ward是一个简单而简约的服务器监控工具。Ward支持自适应设计系统。此外,它还支持黑暗主题。
8 | 它只显示主要信息,如果你想看到漂亮的仪表板,而不是看一堆数字和图表,可以使用它。
9 | Ward在所有流行的操作系统上都运行良好,因为它使用[OSHI](https://github.com/oshi/oshi).
10 |
11 | **所有功能都在以下平台上进行了测试:**“Windows”Linux`
12 |
13 | 
14 |
15 |
16 | ---
17 |
18 | ### 安装
19 |
20 | 创建你的jar
21 |
22 | • 克隆项目
23 | • 将IDE中的项目作为Maven项目导入
24 | • mvn 构建
25 |
26 |
27 |
28 | 运行jar文件
29 |
30 | 1.如上所述创建自己的罐子
31 | 2.使用管理权限在Windows或Linux上执行jar
32 | 3.输入localhost:4000并设置应用程序
33 |
34 |
35 |
36 | 用Docker构建
37 |
38 | 1. 克隆项目
39 | 2. docker build --tag ward
40 | 3. docker run --restart unless-stopped -it -d --name ward -p 4000:4000 -e WARD_PORT=4000 -e WARD_THEME=dark --privileged ward
41 | 4. 输入localhost:4000并设置应用程序
42 |
43 | ### Config
44 |
45 | 如果你想更改Ward的配置,你可以编辑`setup.ini `。使用Docker时,使用环境变量“WARD_NAME”、“WARD_THEME”和“WARD_PORT”在启动时自动重新生成此文件。使用列出的任何环境变量都将启用下面的默认值,并在没有GUI设置的情况下立即启动Ward。
46 |
47 | | 设置 | 变量 | 描述 | 默认 |
48 | |-----------------|-----------------|----------------------------------------------|---------|
49 | | serverName | WARD_NAME | 服务器的名称. | Ward |
50 | | port | WARD_PORT | 运行端口. | 4000 |
51 | | theme | WARD_THEME | 要么是“亮”,要么是“暗”. | light |
52 | | enableFog | WARD_FOG | 要么是“true”,要么是“false”. | true |
53 | | backgroundColor | WARD_BACKGROUND | 禁用雾时背景为HexColor. | default |
54 |
55 | 环境变量具有优先权,并将使用您的变量重新生成此文件。如果没有设置环境变量,则导航到Ward的网页并完成初始设置后,将生成“setup.ini”。您也可以在启动Ward之前自己制作此文件,并将其放置在同一目录中。
56 |
57 | 例如:
58 |
59 | ```ini
60 | [setup]
61 | serverName = my-server
62 | theme = dark
63 | port = 8200
64 | enableFog = true
65 | backgroundColor = #303030
66 | ```
67 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.3'
2 | services:
3 | run:
4 | restart: unless-stopped
5 | container_name: ward
6 | ports:
7 | - '4000:4000'
8 | environment:
9 | - WARD_PORT=4000
10 | - WARD_THEME=dark
11 | - WARD_NAME=leons-server
12 | - WARD_FOG=false
13 | - WARD_BACKGROUND=#3c3c3c
14 | privileged: true
15 | image: antonyleons/ward
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/images/logo.png
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | 4.0.0
7 | dev.leons
8 | ward
9 | 2.5.2
10 | jar
11 |
12 |
13 |
14 | org.springframework.boot
15 | spring-boot-starter-parent
16 | 3.1.10
17 |
18 |
19 |
20 |
21 |
22 | 6.6.0
23 | 5.14.0
24 | 1.18.32
25 | 0.5.4
26 |
27 |
28 |
29 |
30 |
31 | org.springframework.boot
32 | spring-boot-starter-web
33 |
34 |
35 | org.springframework.boot
36 | spring-boot-starter-thymeleaf
37 |
38 |
39 | org.springframework.boot
40 | spring-boot-starter-validation
41 |
42 |
43 | jakarta.validation
44 | jakarta.validation-api
45 | 3.0.2
46 |
47 |
48 | com.github.oshi
49 | oshi-core
50 | ${oshiVersion}
51 |
52 |
53 | net.java.dev.jna
54 | jna
55 | ${jnaVersion}
56 |
57 |
58 | net.java.dev.jna
59 | jna-platform
60 | ${jnaVersion}
61 |
62 |
63 | org.projectlombok
64 | lombok
65 | ${lombokVersion}
66 |
67 |
68 | org.ini4j
69 | ini4j
70 | ${ini4jVersion}
71 |
72 |
73 |
74 |
75 |
76 | ${project.basedir}/target
77 | ${project.build.directory}/classes
78 |
79 |
80 | org.springframework.boot
81 | spring-boot-maven-plugin
82 |
83 |
84 |
85 |
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/Ward.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward;
2 |
3 | import dev.leons.ward.services.SetupService;
4 | import lombok.Getter;
5 | import org.springframework.boot.ApplicationArguments;
6 | import org.springframework.boot.SpringApplication;
7 | import org.springframework.boot.autoconfigure.SpringBootApplication;
8 | import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
9 | import org.springframework.context.ConfigurableApplicationContext;
10 |
11 | import java.io.File;
12 |
13 | /**
14 | * Ward is a Spring Boot application class
15 | *
16 | * @author Rudolf Barbu
17 | * @version 1.0.4
18 | */
19 | @SpringBootApplication
20 | public class Ward extends SpringBootServletInitializer {
21 | /**
22 | * Constant for determine settings file name
23 | */
24 | public static final String SETUP_FILE_PATH = "setup.ini";
25 |
26 | /**
27 | * Constant for determine initial application port
28 | */
29 | public static final int INITIAL_PORT = 4000;
30 |
31 | /**
32 | * Holder for determine first launch of application
33 | */
34 | @Getter
35 | private static boolean isFirstLaunch;
36 |
37 | /**
38 | * Holder for application context
39 | */
40 | private static ConfigurableApplicationContext configurableApplicationContext;
41 |
42 | /**
43 | * Entry point of Ward application
44 | *
45 | * @param args Spring Boot application arguments
46 | */
47 | public static void main(final String[] args) {
48 |
49 | isFirstLaunch = true;
50 | configurableApplicationContext = SpringApplication.run(Ward.class, args);
51 |
52 | File setupFile = new File(Ward.SETUP_FILE_PATH);
53 |
54 | if (System.getenv("WARD_NAME") != null || (System.getenv("WARD_THEME") != null) || (System.getenv("WARD_PORT") != null) || (System.getenv("WARD_FOG") != null)) {
55 | SetupService.envSetup();
56 | } else if (setupFile.exists()) {
57 | restart();
58 | }
59 | }
60 |
61 | /**
62 | * Restarts application
63 | */
64 | public static void restart() {
65 | isFirstLaunch = false;
66 | ApplicationArguments args = configurableApplicationContext.getBean(ApplicationArguments.class);
67 |
68 | Thread thread = new Thread(() ->
69 | {
70 | configurableApplicationContext.close();
71 | configurableApplicationContext = SpringApplication.run(Ward.class, args.getSourceArgs());
72 | });
73 |
74 | thread.setDaemon(false);
75 | thread.start();
76 | }
77 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/components/ServletComponent.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.components;
2 |
3 | import dev.leons.ward.Ward;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
6 | import org.springframework.boot.web.server.WebServerFactoryCustomizer;
7 | import org.springframework.stereotype.Component;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * ServletComponent used for application port changing
13 | * @author Rudolf Barbu
14 | * @version 1.0.3
15 | */
16 | @Component
17 | public class ServletComponent implements WebServerFactoryCustomizer
18 | {
19 | /**
20 | * Autowired UtilitiesComponent object
21 | * Used for various utility functions
22 | */
23 | @Autowired
24 | private UtilitiesComponent utilitiesComponent;
25 |
26 | /**
27 | * Customizes port of application
28 | *
29 | * @param tomcatServletWebServerFactory servlet factory
30 | */
31 | @Override
32 | public void customize(final TomcatServletWebServerFactory tomcatServletWebServerFactory)
33 | {
34 | if (!Ward.isFirstLaunch())
35 | {
36 | try
37 | {
38 | tomcatServletWebServerFactory.setPort(Integer.parseInt(utilitiesComponent.getFromIniFile("port")));
39 | }
40 | catch (IOException exception)
41 | {
42 | exception.printStackTrace();
43 | }
44 | }
45 | else
46 | {
47 | tomcatServletWebServerFactory.setPort(Ward.INITIAL_PORT);
48 | }
49 | }
50 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/components/UtilitiesComponent.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.components;
2 |
3 | import dev.leons.ward.Ward;
4 | import org.ini4j.Ini;
5 | import org.springframework.stereotype.Component;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 |
10 | /**
11 | * UtilitiesComponent provides various functions, which are used in different classes
12 | *
13 | * @author Rudolf Barbu
14 | * @version 1.0.2
15 | */
16 | @Component
17 | public class UtilitiesComponent {
18 | /**
19 | * Constant, that providing setup section name
20 | */
21 | private static final String SECTION_NAME = "setup";
22 |
23 | /**
24 | * Gets string data from ini file
25 | *
26 | * @param optionName option in section
27 | * @return String wth parsed data
28 | * @throws IOException if file does not exist
29 | */
30 | @SuppressWarnings(value = "MismatchedQueryAndUpdateOfCollection")
31 | public String getFromIniFile(final String optionName) throws IOException {
32 | final File file = new File(Ward.SETUP_FILE_PATH);
33 |
34 | if (file.exists()) {
35 | final Ini ini = new Ini(file);
36 | return ini.get(SECTION_NAME, optionName, String.class);
37 | }
38 |
39 | return null;
40 | }
41 |
42 | /**
43 | * Sets string data to the ini file
44 | *
45 | * @param optionName option in section
46 | * @param value value to put
47 | * @throws IOException if file does not exist
48 | */
49 | public void putInIniFile(final String optionName, final String value) throws IOException {
50 | final File file = new File(Ward.SETUP_FILE_PATH);
51 |
52 | if (file.exists()) {
53 | final Ini ini = new Ini(file);
54 | ini.put(SECTION_NAME, optionName, value);
55 | ini.store();
56 | } else {
57 | throw new IOException();
58 | }
59 | }
60 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/configurations/BeanConfiguration.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.configurations;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import oshi.SystemInfo;
6 |
7 | /**
8 | * BeanConfiguration provides bean configuration for classes, which are not components
9 | *
10 | * @author Rudolf Barbu
11 | * @version 1.0.2
12 | */
13 | @Configuration
14 | public class BeanConfiguration
15 | {
16 | /**
17 | * @return SystemInfo object
18 | */
19 | @Bean
20 | public SystemInfo systemInfo()
21 | {
22 | return new SystemInfo();
23 | }
24 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/ErrorController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.services.ErrorService;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Controller;
6 | import org.springframework.ui.Model;
7 | import org.springframework.web.bind.annotation.GetMapping;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 |
10 | import java.io.IOException;
11 |
12 | /**
13 | * ErrorController displays error pages of Ward application
14 | *
15 | * @author Rudolf Barbu
16 | * @version 1.0.2
17 | */
18 | @Controller
19 | @RequestMapping(value = "/error")
20 | public class ErrorController implements org.springframework.boot.web.servlet.error.ErrorController
21 | {
22 | /**
23 | * Autowired ErrorService object
24 | * Used to determine error page
25 | */
26 | @Autowired
27 | private ErrorService errorService;
28 |
29 | /**
30 | * Get request to display error page, which corresponds status code
31 | *
32 | * @return String name of html template
33 | */
34 | @GetMapping
35 | public String getError(final Model model) throws IOException
36 | {
37 | return errorService.getError(model);
38 | }
39 |
40 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/IndexController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
4 | import dev.leons.ward.services.IndexService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Controller;
7 | import org.springframework.ui.Model;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 |
11 | import java.io.IOException;
12 |
13 | /**
14 | * IndexController displays index page of Ward application
15 | *
16 | * @author Rudolf Barbu
17 | * @version 1.0.2
18 | */
19 | @Controller
20 | @RequestMapping(value = "/")
21 | public class IndexController
22 | {
23 | /**
24 | * Autowired IndexService object
25 | * Used for getting index page template
26 | */
27 | @Autowired
28 | private IndexService indexService;
29 |
30 | /**
31 | * Get request to display index page
32 | *
33 | * @param model used for providing values in to html template
34 | * @return String name of html template with values from model param
35 | */
36 | @GetMapping
37 | public String getIndex(final Model model) throws IOException, ApplicationNotConfiguredException
38 | {
39 | return indexService.getIndex(model);
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/InfoController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.dto.InfoDto;
4 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
5 | import dev.leons.ward.services.InfoService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.http.HttpStatus;
8 | import org.springframework.http.ResponseEntity;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * InfoController displays responses from rest API, about server
15 | *
16 | * @author Rudolf Barbu
17 | * @version 1.0.1
18 | */
19 | @RestController
20 | @RequestMapping(value = "/api/info")
21 | public class InfoController
22 | {
23 | /**
24 | * Autowired InfoService object
25 | * Used for getting information about server
26 | */
27 | @Autowired
28 | private InfoService infoService;
29 |
30 | /**
31 | * Get request to display current usage information for processor, RAM and storage
32 | *
33 | * @return ResponseEntity to servlet
34 | */
35 | @GetMapping
36 | public ResponseEntity getInfo() throws ApplicationNotConfiguredException
37 | {
38 | return new ResponseEntity<>(infoService.getInfo(), HttpStatus.OK);
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/SetupController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.dto.ResponseDto;
4 | import dev.leons.ward.exceptions.ApplicationAlreadyConfiguredException;
5 | import dev.leons.ward.services.SetupService;
6 | import dev.leons.ward.dto.SetupDto;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.ResponseEntity;
10 | import org.springframework.web.bind.annotation.PostMapping;
11 | import org.springframework.web.bind.annotation.RequestBody;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RestController;
14 |
15 | import jakarta.validation.Valid;
16 | import java.io.IOException;
17 |
18 | /**
19 | * SetupController displays responses from rest API
20 | *
21 | * @author Rudolf Barbu
22 | * @version 1.0.1
23 | */
24 | @RestController
25 | @RequestMapping(value = "/api/setup")
26 | public class SetupController
27 | {
28 | /**
29 | * Autowired SetupService object
30 | * Used for posting settings information in ini file
31 | */
32 | @Autowired
33 | private SetupService setupService;
34 |
35 | /**
36 | * Posting setup info in database
37 | *
38 | * @param setupDto dto with data
39 | * @return ResponseEntity to servlet
40 | */
41 | @PostMapping
42 | public ResponseEntity postSetup(@RequestBody @Valid final SetupDto setupDto) throws IOException, ApplicationAlreadyConfiguredException
43 | {
44 | return new ResponseEntity<>(setupService.postSetup(setupDto), HttpStatus.OK);
45 | }
46 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/UptimeController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.dto.UptimeDto;
4 | import dev.leons.ward.services.UptimeService;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.http.HttpStatus;
7 | import org.springframework.http.ResponseEntity;
8 | import org.springframework.web.bind.annotation.GetMapping;
9 | import org.springframework.web.bind.annotation.RequestMapping;
10 | import org.springframework.web.bind.annotation.RestController;
11 |
12 | /**
13 | * SetupController displays responses from rest API
14 | *
15 | * @author Rudolf Barbu
16 | * @version 1.0.0
17 | */
18 | @RestController
19 | @RequestMapping(value = "/api/uptime")
20 | public class UptimeController
21 | {
22 | /**
23 | * Autowired UptimeService object
24 | * Used for getting uptime information
25 | */
26 | @Autowired
27 | private UptimeService uptimeService;
28 |
29 | /**
30 | * Get request to display uptime information
31 | *
32 | * @return ResponseEntity to servlet
33 | */
34 | @GetMapping
35 | public ResponseEntity getUptime()
36 | {
37 | return new ResponseEntity<>(uptimeService.getUptime(), HttpStatus.OK);
38 | }
39 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/controllers/UsageController.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.controllers;
2 |
3 | import dev.leons.ward.dto.UsageDto;
4 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
5 | import dev.leons.ward.services.UsageService;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.http.HttpStatus;
8 | import org.springframework.http.ResponseEntity;
9 | import org.springframework.web.bind.annotation.GetMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RestController;
12 |
13 | /**
14 | * UsageController displays responses from rest API
15 | *
16 | * @author Rudolf Barbu
17 | * @version 1.0.1
18 | */
19 | @RestController
20 | @RequestMapping(value = "/api/usage")
21 | public class UsageController
22 | {
23 | /**
24 | * Autowired UsageService object
25 | * Used for getting usage information
26 | */
27 | @Autowired
28 | private UsageService usageService;
29 |
30 | /**
31 | * Get request to display current usage information for processor, RAM and storage
32 | *
33 | * @return ResponseEntity to servlet
34 | */
35 | @GetMapping
36 | public ResponseEntity getUsage() throws ApplicationNotConfiguredException
37 | {
38 | return new ResponseEntity<>(usageService.getUsage(), HttpStatus.OK);
39 | }
40 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/ErrorDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 |
5 | import java.time.LocalDateTime;
6 |
7 | /**
8 | * ErrorDto is a container for error response
9 | *
10 | * @author Rudolf Barbu
11 | * @version 1.0.1
12 | */
13 | @Getter
14 | public final class ErrorDto
15 | {
16 | /**
17 | * Error timestamp field
18 | */
19 | private final String timestamp = LocalDateTime.now().toString();
20 |
21 | /**
22 | * Error message field
23 | */
24 | private final String errMessage;
25 |
26 | /**
27 | * Exception name field
28 | */
29 | private final String exceptionName;
30 |
31 | /**
32 | * Setter for errMessage and exceptionName fields
33 | *
34 | * @param exception thrown exception
35 | */
36 | public ErrorDto(final Exception exception)
37 | {
38 | this.errMessage = exception.getMessage();
39 | this.exceptionName = exception.getClass().getName();
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/InfoDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * InfoDto is a container for other info objects
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.1
11 | */
12 | @Getter
13 | @Setter
14 | public class InfoDto
15 | {
16 | /**
17 | * Processor info dto field
18 | */
19 | private ProcessorDto processor;
20 |
21 | /**
22 | * machine info dto field
23 | */
24 | private MachineDto machine;
25 |
26 | /**
27 | * Storage info dto field
28 | */
29 | private StorageDto storage;
30 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/MachineDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * MachineDto is a values container for presenting machine principal information
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.0
11 | */
12 | @Getter
13 | @Setter
14 | public class MachineDto
15 | {
16 | /**
17 | * OS info field
18 | */
19 | private String operatingSystem;
20 |
21 | /**
22 | * Amount of total installed ram field
23 | */
24 | private String totalRam;
25 |
26 | /**
27 | * Ram generation field
28 | */
29 | private String ramTypeOrOSBitDepth;
30 |
31 | /**
32 | * Processes count field
33 | */
34 | private String procCount;
35 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/ProcessorDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * ProcessorDto is a values container for presenting processor principal information
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.0
11 | */
12 | @Getter
13 | @Setter
14 | public class ProcessorDto
15 | {
16 | /**
17 | * Processor name field
18 | */
19 | private String name;
20 |
21 | /**
22 | * Core count field
23 | */
24 | private String coreCount;
25 |
26 | /**
27 | * Processor max frequency field
28 | */
29 | private String clockSpeed;
30 |
31 | /**
32 | * Processor architecture field
33 | */
34 | private String bitDepth;
35 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/ResponseDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 |
5 | /**
6 | * ResponseDto is a values container for presenting response info
7 | *
8 | * @author Rudolf Barbu
9 | * @version 1.0.0
10 | */
11 | @Getter
12 | public final class ResponseDto
13 | {
14 | /**
15 | * Response message field
16 | */
17 | private final String message;
18 |
19 | /**
20 | * Setter for message field
21 | *
22 | * @param message message to display
23 | */
24 | public ResponseDto(final String message)
25 | {
26 | this.message = message;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/SetupDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import jakarta.validation.constraints.Max;
4 | import jakarta.validation.constraints.Min;
5 | import jakarta.validation.constraints.NotEmpty;
6 | import jakarta.validation.constraints.NotNull;
7 | import jakarta.validation.constraints.Pattern;
8 | import jakarta.validation.constraints.Size;
9 | import lombok.Getter;
10 | import lombok.Setter;
11 |
12 | /**
13 | * SetupDto is a values container for setup data
14 | *
15 | * @author Rudolf Barbu
16 | * @version 1.0.3
17 | */
18 | @Getter
19 | @Setter
20 | public class SetupDto
21 | {
22 | /**
23 | * Server name Field
24 | */
25 | @NotNull
26 | @Size(min = 0, max = 10)
27 | private String serverName;
28 |
29 | /**
30 | * Theme name field
31 | */
32 | @NotNull
33 | @NotEmpty
34 | @Pattern(regexp = "light|dark")
35 | private String theme;
36 |
37 | /**
38 | * Port port field
39 | */
40 | @NotNull
41 | @NotEmpty
42 | @Min(value = 10)
43 | @Max(value = 65535)
44 | private String port;
45 |
46 | /**
47 | * Enable fog field
48 | */
49 | @NotNull
50 | @NotEmpty
51 | @Pattern(regexp = "true|false")
52 | private String enableFog;
53 |
54 | /**
55 | * Background Color field
56 | */
57 | @NotEmpty
58 | @Pattern(regexp = "^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$|default")
59 | private String backgroundColor;
60 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/StorageDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * StorageDto is a values container for presenting storage principal information
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.0
11 | */
12 | @Getter
13 | @Setter
14 | public class StorageDto
15 | {
16 | /**
17 | * Host0 storage name field
18 | */
19 | private String mainStorage;
20 |
21 | /**
22 | * Amount of total installed storage field
23 | */
24 | private String total;
25 |
26 | /**
27 | * Disk count field
28 | */
29 | private String diskCount;
30 |
31 | /**
32 | * Total amount of virtual memory (Swap on Linux) field
33 | */
34 | private String swapAmount;
35 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/UptimeDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * UptimeDto is a values container for presenting uptime principal information
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.0
11 | */
12 | @Getter
13 | @Setter
14 | public class UptimeDto
15 | {
16 | /**
17 | * Uptime days field
18 | */
19 | private String days;
20 |
21 | /**
22 | * Uptime hours field
23 | */
24 | private String hours;
25 |
26 | /**
27 | * Uptime minutes field
28 | */
29 | private String minutes;
30 |
31 | /**
32 | * Uptime seconds field
33 | */
34 | private String seconds;
35 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/dto/UsageDto.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.dto;
2 |
3 | import lombok.Getter;
4 | import lombok.Setter;
5 |
6 | /**
7 | * UsageDto is a values container for presenting server usage
8 | *
9 | * @author Rudolf Barbu
10 | * @version 1.0.1
11 | */
12 | @Getter
13 | @Setter
14 | public class UsageDto
15 | {
16 | /**
17 | * Processor usage field
18 | */
19 | private int processor;
20 |
21 | /**
22 | * Ram usage field
23 | */
24 | private int ram;
25 |
26 | /**
27 | * Storage usage field
28 | */
29 | private int storage;
30 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/exceptions/ApplicationAlreadyConfiguredException.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.exceptions;
2 |
3 | /**
4 | * ApplicationAlreadyConfiguredException indicates that user tried to access api, when application is already configured
5 | *
6 | * @author Rudolf Barbu
7 | * @version 1.0.0
8 | */
9 | public class ApplicationAlreadyConfiguredException extends Exception
10 | {
11 | /**
12 | * Call super class with exception message
13 | */
14 | public ApplicationAlreadyConfiguredException()
15 | {
16 | super("Application already configured");
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/exceptions/ApplicationNotConfiguredException.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.exceptions;
2 |
3 | /**
4 | * ApplicationNotSetUpException indicates that user tried to access api, without setting up the application
5 | *
6 | * @author Rudolf Barbu
7 | * @version 1.0.0
8 | */
9 | public final class ApplicationNotConfiguredException extends Exception
10 | {
11 | /**
12 | * Call super class with exception message
13 | */
14 | public ApplicationNotConfiguredException()
15 | {
16 | super("Set up application first");
17 | }
18 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/handlers/ControllerExceptionHandler.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.handlers;
2 |
3 | import dev.leons.ward.components.UtilitiesComponent;
4 | import dev.leons.ward.dto.ErrorDto;
5 | import dev.leons.ward.exceptions.ApplicationAlreadyConfiguredException;
6 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.core.Ordered;
9 | import org.springframework.core.annotation.Order;
10 | import org.springframework.http.HttpStatus;
11 | import org.springframework.http.ResponseEntity;
12 | import org.springframework.http.converter.HttpMessageNotReadableException;
13 | import org.springframework.ui.Model;
14 | import org.springframework.web.HttpRequestMethodNotSupportedException;
15 | import org.springframework.web.bind.MethodArgumentNotValidException;
16 | import org.springframework.web.bind.annotation.ControllerAdvice;
17 | import org.springframework.web.bind.annotation.ExceptionHandler;
18 | import org.springframework.web.bind.annotation.ResponseBody;
19 |
20 | import java.io.IOException;
21 |
22 | /**
23 | * ControllerExceptionHandler is standard exception handler for rest api, and white labels
24 | *
25 | * @author Rudolf Barbu
26 | * @version 1.0.0
27 | */
28 | @ControllerAdvice
29 | @Order(value = Ordered.HIGHEST_PRECEDENCE)
30 | public class ControllerExceptionHandler
31 | {
32 | /**
33 | * Autowired UtilitiesComponent object
34 | * Used for various utility functions
35 | */
36 | @Autowired
37 | private UtilitiesComponent utilitiesComponent;
38 |
39 | /**
40 | * Handles exceptions with BAD_REQUEST status, then they thrown
41 | */
42 | @ResponseBody
43 | @ExceptionHandler(value = {ApplicationNotConfiguredException.class, ApplicationAlreadyConfiguredException.class})
44 | public ResponseEntity applicationNotSetUpExceptionHandler(final Exception exception)
45 | {
46 | return new ResponseEntity<>(new ErrorDto(exception), HttpStatus.BAD_REQUEST);
47 | }
48 |
49 | /**
50 | * Handles exceptions with UNPROCESSABLE_ENTITY status, then they thrown
51 | */
52 | @ResponseBody
53 | @ExceptionHandler(value = {MethodArgumentNotValidException.class, HttpMessageNotReadableException.class})
54 | public ResponseEntity methodArgumentNotValidExceptionHandler(final Exception exception)
55 | {
56 | return new ResponseEntity<>(new ErrorDto(exception), HttpStatus.UNPROCESSABLE_ENTITY);
57 | }
58 |
59 | /**
60 | * Handles MethodArgumentNotValidException, then it thrown
61 | * Also handles all other servlet exceptions, which were not handled by others handlers
62 | *
63 | * @throws IOException if ini file is unreachable
64 | */
65 | @ExceptionHandler(value = Exception.class)
66 | public String exceptionHandler(final Exception exception, final Model model) throws IOException
67 | {
68 | model.addAttribute("theme", utilitiesComponent.getFromIniFile("theme"));
69 | System.out.println(exception.getMessage());
70 | return (exception instanceof HttpRequestMethodNotSupportedException) ? "error/404" : "error/500";
71 | }
72 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/ErrorService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.Ward;
4 | import dev.leons.ward.components.UtilitiesComponent;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.stereotype.Service;
7 | import org.springframework.ui.Model;
8 |
9 | import java.io.IOException;
10 |
11 | /**
12 | * ErrorService displays error pages of Ward application
13 | *
14 | * @author Rudolf Barbu
15 | * @version 1.0.1
16 | */
17 | @Service
18 | public class ErrorService
19 | {
20 | /**
21 | * Autowired UtilitiesComponent object
22 | * Used for various utility functions
23 | */
24 | @Autowired
25 | private UtilitiesComponent utilitiesComponent;
26 |
27 | /**
28 | * Returns 404 error page
29 | *
30 | * @param model container for strings
31 | * @return template name
32 | * @throws IOException if ini file is unreachable
33 | */
34 | public String getError(final Model model) throws IOException
35 | {
36 | if (Ward.isFirstLaunch())
37 | {
38 | return "setup";
39 | }
40 |
41 | model.addAttribute("theme", utilitiesComponent.getFromIniFile("theme"));
42 | return "error/404";
43 | }
44 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/IndexService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.Ward;
4 | import dev.leons.ward.components.UtilitiesComponent;
5 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 | import org.springframework.ui.Model;
9 |
10 | import java.io.IOException;
11 | import java.io.InputStream;
12 | import java.util.Properties;
13 |
14 | /**
15 | * IndexService displays index page of Ward application
16 | *
17 | * @author Rudolf Barbu
18 | * @version 1.0.1
19 | */
20 | @Service
21 | public class IndexService
22 | {
23 | /**
24 | * Autowired InfoService object
25 | * Used for getting machine information for html template
26 | */
27 | @Autowired
28 | private InfoService infoService;
29 |
30 | /**
31 | * Autowired UptimeService object
32 | * Used for getting uptime for html template
33 | */
34 | @Autowired
35 | private UptimeService uptimeService;
36 |
37 | /**
38 | * Autowired UtilitiesComponent object
39 | * Used for various utility functions
40 | */
41 | @Autowired
42 | private UtilitiesComponent utilitiesComponent;
43 |
44 | /**
45 | * Gets project version information
46 | *
47 | * @return MavenDto with filled field
48 | * @throws IOException if file does not exists
49 | */
50 | private String getVersion() throws IOException
51 | {
52 | Properties properties = new Properties();
53 | InputStream inputStream = getClass().getResourceAsStream("/META-INF/maven/dev.leons/ward/pom.properties");
54 |
55 | if (inputStream != null)
56 | {
57 | properties.load(inputStream);
58 | String version = properties.getProperty("version");
59 |
60 | return "Ward: v" + version;
61 | }
62 | else
63 | {
64 | return "Developer mode";
65 | }
66 | }
67 |
68 | /**
69 | * Fills model and returns template name
70 | *
71 | * @param model strings container
72 | * @return template name
73 | */
74 | public String getIndex(final Model model) throws IOException, ApplicationNotConfiguredException
75 | {
76 | if (Ward.isFirstLaunch())
77 | {
78 | return "setup";
79 | }
80 |
81 | updateDefaultsInSetupFile();
82 |
83 | model.addAttribute("theme", utilitiesComponent.getFromIniFile("theme"));
84 | model.addAttribute("serverName", utilitiesComponent.getFromIniFile("serverName"));
85 | model.addAttribute("enableFog", utilitiesComponent.getFromIniFile("enableFog"));
86 | model.addAttribute("backgroundColor", utilitiesComponent.getFromIniFile("backgroundColor"));
87 |
88 | model.addAttribute("info", infoService.getInfo());
89 | model.addAttribute("uptime", uptimeService.getUptime());
90 | model.addAttribute("version", getVersion());
91 |
92 | return "index";
93 | }
94 |
95 | private void updateDefaultsInSetupFile() throws IOException {
96 | if (utilitiesComponent.getFromIniFile("enableFog") == null) {
97 | utilitiesComponent.putInIniFile("enableFog", "true");
98 | }
99 | if (utilitiesComponent.getFromIniFile("backgroundColor") == null) {
100 | utilitiesComponent.putInIniFile("backgroundColor", "#303030");
101 | }
102 | }
103 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/InfoService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.Ward;
4 | import dev.leons.ward.dto.InfoDto;
5 | import dev.leons.ward.dto.MachineDto;
6 | import dev.leons.ward.dto.ProcessorDto;
7 | import dev.leons.ward.dto.StorageDto;
8 | import dev.leons.ward.components.UtilitiesComponent;
9 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.stereotype.Service;
12 | import oshi.SystemInfo;
13 | import oshi.hardware.CentralProcessor;
14 | import oshi.hardware.GlobalMemory;
15 | import oshi.hardware.HWDiskStore;
16 | import oshi.hardware.PhysicalMemory;
17 | import oshi.software.os.OperatingSystem;
18 |
19 | import java.util.Arrays;
20 | import java.util.List;
21 | import java.util.Optional;
22 |
23 | /**
24 | * InfoService provides various information about machine, such as processor name, core count, Ram amount, etc.
25 | *
26 | * @author Rudolf Barbu
27 | * @version 1.0.2
28 | */
29 | @Service
30 | public class InfoService
31 | {
32 | /**
33 | * Autowired SystemInfo object
34 | * Used for getting machine information
35 | */
36 | @Autowired
37 | private SystemInfo systemInfo;
38 |
39 | /**
40 | * Autowired UtilitiesComponent object
41 | * Used for various utility functions
42 | */
43 | @Autowired
44 | private UtilitiesComponent utilitiesComponent;
45 |
46 | /**
47 | * Converts frequency to most readable format
48 | *
49 | * @param hertzArray raw frequency array values in hertz for each logical processor
50 | * @return String with formatted frequency and postfix
51 | */
52 | private String getConvertedFrequency(final long[] hertzArray)
53 | {
54 | long totalFrequency = Arrays.stream(hertzArray).sum();
55 | long hertz = totalFrequency / hertzArray.length;
56 |
57 | if ((hertz / 1E+6) > 999)
58 | {
59 | return (Math.round((hertz / 1E+9) * 10.0) / 10.0) + " GHz";
60 | }
61 | else
62 | {
63 | return Math.round(hertz / 1E+6) + " MHz";
64 | }
65 | }
66 |
67 | /**
68 | * Converts capacity to most readable format
69 | *
70 | * @param bits raw capacity value in bits
71 | * @return String with formatted capacity and postfix
72 | */
73 | private String getConvertedCapacity(final long bits)
74 | {
75 | if ((bits / 1.049E+6) > 999)
76 | {
77 | if ((bits / 1.074E+9) > 999)
78 | {
79 | return (Math.round((bits / 1.1E+12) * 10.0) / 10.0) + " TiB";
80 | }
81 | else
82 | {
83 | return Math.round(bits / 1.074E+9) + " GiB";
84 | }
85 | }
86 | else
87 | {
88 | return Math.round(bits / 1.049E+6) + " MiB";
89 | }
90 | }
91 |
92 | /**
93 | * Gets processor information
94 | *
95 | * @return ProcessorDto with filled fields
96 | */
97 | private ProcessorDto getProcessor() {
98 | ProcessorDto processorDto = new ProcessorDto();
99 | CentralProcessor centralProcessor = systemInfo.getHardware().getProcessor();
100 |
101 | // Extract processor name
102 | String name = centralProcessor.getProcessorIdentifier().getName().split("@")[0].trim();
103 | processorDto.setName(name);
104 |
105 | // Set core count
106 | int coreCount = centralProcessor.getLogicalProcessorCount();
107 | processorDto.setCoreCount(coreCount + (coreCount > 1 ? " Cores" : " Core"));
108 |
109 | // Set clock speed
110 | processorDto.setClockSpeed(getConvertedFrequency(centralProcessor.getCurrentFreq()));
111 |
112 | // Set bit depth
113 | String bitDepth = centralProcessor.getProcessorIdentifier().isCpu64bit() ? "64-bit" : "32-bit";
114 | processorDto.setBitDepth(bitDepth);
115 |
116 | return processorDto;
117 | }
118 |
119 | /**
120 | * Gets machine information
121 | *
122 | * @return MachineDto with filled fields
123 | */
124 | private MachineDto getMachine() {
125 | MachineDto machineDto = new MachineDto();
126 |
127 | OperatingSystem operatingSystem = systemInfo.getOperatingSystem();
128 | OperatingSystem.OSVersionInfo osVersionInfo = operatingSystem.getVersionInfo();
129 | GlobalMemory globalMemory = systemInfo.getHardware().getMemory();
130 |
131 | String osDescription = operatingSystem.getFamily() + " " + osVersionInfo.getVersion();
132 | machineDto.setOperatingSystem(osDescription);
133 |
134 | long totalRam = globalMemory.getTotal();
135 | machineDto.setTotalRam(getConvertedCapacity(totalRam) + " RAM");
136 |
137 | Optional physicalMemoryOptional = globalMemory.getPhysicalMemory().stream().findFirst();
138 | String ramTypeOrOSBitDepth;
139 | if (physicalMemoryOptional.isPresent()) {
140 | ramTypeOrOSBitDepth = physicalMemoryOptional.get().getMemoryType();
141 | } else {
142 | ramTypeOrOSBitDepth = operatingSystem.getBitness() + "-bit";
143 | }
144 | machineDto.setRamTypeOrOSBitDepth(ramTypeOrOSBitDepth);
145 |
146 | int processCount = operatingSystem.getProcessCount();
147 | String procCount = processCount + ((processCount > 1) ? " Procs" : " Proc");
148 | machineDto.setProcCount(procCount);
149 |
150 | return machineDto;
151 | }
152 |
153 | /**
154 | * Gets storage information
155 | *
156 | * @return StorageDto with filled fields
157 | */
158 | private StorageDto getStorage()
159 | {
160 | StorageDto storageDto = new StorageDto();
161 | List hwDiskStores = systemInfo.getHardware().getDiskStores();
162 | GlobalMemory globalMemory = systemInfo.getHardware().getMemory();
163 |
164 | // Retrieve main storage model
165 | String mainStorage = hwDiskStores.isEmpty() ? "Undefined"
166 | : hwDiskStores.get(0).getModel().replaceAll("\\(.+?\\)", "").trim();
167 | storageDto.setMainStorage(mainStorage);
168 |
169 | long total = hwDiskStores.stream().mapToLong(HWDiskStore::getSize).sum();
170 | storageDto.setTotal(getConvertedCapacity(total) + " Total");
171 |
172 | int diskCount = hwDiskStores.size();
173 | storageDto.setDiskCount(diskCount + (diskCount > 1 ? " Disks" : " Disk"));
174 |
175 | storageDto.setSwapAmount(getConvertedCapacity(globalMemory.getVirtualMemory().getSwapTotal()) + " Swap");
176 |
177 | return storageDto;
178 | }
179 |
180 | /**
181 | * Used to deliver dto to corresponding controller
182 | *
183 | * @return InfoDto filled with server info
184 | */
185 | public InfoDto getInfo() throws ApplicationNotConfiguredException
186 | {
187 | if (!Ward.isFirstLaunch())
188 | {
189 | InfoDto infoDto = new InfoDto();
190 |
191 | infoDto.setProcessor(getProcessor());
192 | infoDto.setMachine(getMachine());
193 | infoDto.setStorage(getStorage());
194 |
195 | return infoDto;
196 | }
197 | else
198 | {
199 | throw new ApplicationNotConfiguredException();
200 | }
201 | }
202 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/SetupService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.Ward;
4 | import dev.leons.ward.dto.ResponseDto;
5 | import dev.leons.ward.dto.SetupDto;
6 | import dev.leons.ward.exceptions.ApplicationAlreadyConfiguredException;
7 | import org.ini4j.Ini;
8 | import org.springframework.stereotype.Service;
9 |
10 | import java.io.File;
11 | import java.io.IOException;
12 |
13 | /**
14 | * SetupService manipulating setup data
15 | *
16 | * @author Rudolf Barbu
17 | * @version 1.0.2
18 | */
19 | @Service
20 | public class SetupService {
21 | /**
22 | * Constant, that providing setup section name
23 | */
24 | private static final String SECTION_NAME = "setup";
25 |
26 | /**
27 | * Puts new data in ini file
28 | *
29 | * @param file ini file
30 | * @param optionName option in section
31 | * @throws IOException if file does not exists
32 | */
33 | private static void putInIniFile(final File file, final String optionName, final String value) throws IOException {
34 | Ini ini = new Ini(file);
35 | ini.put(SECTION_NAME, optionName, value);
36 | ini.store();
37 | }
38 |
39 | /**
40 | * Fills setup data in ini file
41 | *
42 | * @param setupDto user settings data
43 | * @return ResponseEntityWrapperAsset filled with ResponseDto
44 | * @throws IOException IoException if file is fot found, and cant be created
45 | */
46 | public ResponseDto postSetup(final SetupDto setupDto) throws IOException, ApplicationAlreadyConfiguredException {
47 | if (Ward.isFirstLaunch()) {
48 | File file = new File(Ward.SETUP_FILE_PATH);
49 |
50 | if (file.createNewFile()) {
51 | putInIniFile(file, "serverName", setupDto.getServerName());
52 | putInIniFile(file, "theme", setupDto.getTheme());
53 | putInIniFile(file, "port", setupDto.getPort());
54 | putInIniFile(file, "enableFog", setupDto.getEnableFog());
55 | putInIniFile(file, "backgroundColor", setupDto.getBackgroundColor());
56 |
57 | Ward.restart();
58 | } else {
59 | throw new IOException();
60 | }
61 | } else {
62 | throw new ApplicationAlreadyConfiguredException();
63 | }
64 |
65 | return new ResponseDto("Settings saved correctly");
66 | }
67 |
68 | public static ResponseDto envSetup() {
69 | if (Ward.isFirstLaunch()) {
70 | try {
71 | File file = new File(Ward.SETUP_FILE_PATH);
72 | if (file.exists()) {
73 | file.delete();
74 | }
75 | if (file.createNewFile()) {
76 | String servername = (System.getenv("WARD_NAME") != null) ? System.getenv("WARD_NAME") : "Ward";
77 | String theme = (System.getenv("WARD_THEME") != null) ? System.getenv("WARD_THEME").toLowerCase() : "light";
78 | String port = (System.getenv("WARD_PORT") != null) ? System.getenv("WARD_PORT") : "4000";
79 | String enableFog = (System.getenv("WARD_FOG") != null) ? System.getenv("WARD_FOG") : "true";
80 | String backgroundColor = (System.getenv("WARD_BACKGROUND") != null) ? System.getenv("WARD_BACKGROUND") : "default";
81 |
82 | putInIniFile(file, "serverName", servername);
83 | putInIniFile(file, "theme", theme);
84 | putInIniFile(file, "port", port);
85 | putInIniFile(file, "enableFog", enableFog);
86 | putInIniFile(file, "backgroundColor", backgroundColor);
87 |
88 | Ward.restart();
89 | } else {
90 | throw new IOException();
91 | }
92 |
93 | } catch (IOException e) {
94 | e.printStackTrace();
95 | }
96 | }
97 |
98 | return new ResponseDto("Settings saved correctly");
99 | }
100 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/UptimeService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.dto.UptimeDto;
4 | import org.springframework.beans.factory.annotation.Autowired;
5 | import org.springframework.stereotype.Service;
6 | import oshi.SystemInfo;
7 |
8 | @Service
9 | public class UptimeService
10 | {
11 | @Autowired
12 | private SystemInfo systemInfo;
13 |
14 | /**
15 | * Gets uptime information
16 | *
17 | * @return UptimeDto with filled fields
18 | */
19 | public UptimeDto getUptime()
20 | {
21 | UptimeDto uptimeDto = new UptimeDto();
22 |
23 | long uptimeInSeconds = systemInfo.getOperatingSystem().getSystemUptime();
24 |
25 | uptimeDto.setDays(String.format("%02d", (int) uptimeInSeconds / 86400));
26 | uptimeDto.setHours(String.format("%02d", (int) (uptimeInSeconds % 86400) / 3600));
27 | uptimeDto.setMinutes(String.format("%02d", (int) (uptimeInSeconds / 60) % 60));
28 | uptimeDto.setSeconds(String.format("%02d", (int) uptimeInSeconds % 60));
29 |
30 | return uptimeDto;
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/dev/leons/ward/services/UsageService.java:
--------------------------------------------------------------------------------
1 | package dev.leons.ward.services;
2 |
3 | import dev.leons.ward.Ward;
4 | import dev.leons.ward.dto.UsageDto;
5 | import dev.leons.ward.exceptions.ApplicationNotConfiguredException;
6 | import org.springframework.beans.factory.annotation.Autowired;
7 | import org.springframework.stereotype.Service;
8 | import oshi.SystemInfo;
9 | import oshi.hardware.CentralProcessor;
10 | import oshi.hardware.GlobalMemory;
11 | import oshi.software.os.FileSystem;
12 | import oshi.software.os.OSFileStore;
13 | import oshi.util.Util;
14 |
15 | import java.util.Arrays;
16 |
17 | /**
18 | * UsageService provides principal information of processor, RAM and storage usage to rest controller
19 | *
20 | * @author Rudolf Barbu
21 | * @version 1.0.3
22 | */
23 | @Service
24 | public class UsageService
25 | {
26 | /**
27 | * Autowired SystemInfo object
28 | * Used for getting usage information
29 | */
30 | @Autowired
31 | private SystemInfo systemInfo;
32 |
33 | /**
34 | * Gets processor usage
35 | *
36 | * @return int that display processor usage
37 | */
38 | private int getProcessor() {
39 | CentralProcessor centralProcessor = systemInfo.getHardware().getProcessor();
40 | long[] prevTicksArray = centralProcessor.getSystemCpuLoadTicks();
41 | long prevTotalTicks = Arrays.stream(prevTicksArray).sum();
42 | long prevIdleTicks = prevTicksArray[CentralProcessor.TickType.IDLE.getIndex()];
43 |
44 | Util.sleep(1000);
45 |
46 | long[] currTicksArray = centralProcessor.getSystemCpuLoadTicks();
47 | long currTotalTicks = Arrays.stream(currTicksArray).sum();
48 | long currIdleTicks = currTicksArray[CentralProcessor.TickType.IDLE.getIndex()];
49 |
50 | long idleTicksDelta = currIdleTicks - prevIdleTicks;
51 | long totalTicksDelta = currTotalTicks - prevTotalTicks;
52 |
53 | // Handle possible division by zero
54 | if (totalTicksDelta == 0) {
55 | return 0; // or handle in a way suitable for your application
56 | }
57 |
58 | // Calculate CPU usage percentage
59 | return (int) ((1 - (double) idleTicksDelta / totalTicksDelta) * 100);
60 | }
61 |
62 | /**
63 | * Gets ram usage
64 | *
65 | * @return int that display ram usage
66 | */
67 | private int getRam() {
68 | GlobalMemory globalMemory = systemInfo.getHardware().getMemory();
69 | long totalMemory = globalMemory.getTotal();
70 | long availableMemory = globalMemory.getAvailable();
71 |
72 | // Handle possible division by zero
73 | if (totalMemory == 0) {
74 | return 0; // or handle in a way suitable for your application
75 | }
76 |
77 | // Calculate RAM usage percentage
78 | return (int) (100 - ((double) availableMemory / totalMemory * 100));
79 | }
80 |
81 | /**
82 | * Gets storage usage
83 | *
84 | * @return int that display storage usage
85 | */
86 | private int getStorage() {
87 | FileSystem fileSystem = systemInfo.getOperatingSystem().getFileSystem();
88 |
89 | // Calculate total storage and free storage for all drives
90 | long totalStorage = 0;
91 | long freeStorage = 0;
92 | for (OSFileStore fileStore : fileSystem.getFileStores()) {
93 | totalStorage += fileStore.getTotalSpace();
94 | freeStorage += fileStore.getFreeSpace();
95 | }
96 |
97 | // Handle possible division by zero
98 | if (totalStorage == 0) {
99 | return 0; // or handle in a way suitable for your application
100 | }
101 |
102 | // Calculate total storage usage percentage for all drives
103 | return (int) Math.round(((double) (totalStorage - freeStorage) / totalStorage) * 100);
104 | }
105 |
106 | /**
107 | * Used to deliver dto to corresponding controller
108 | *
109 | * @return ResponseEntityWrapperAsset filled with usageDto
110 | */
111 | public UsageDto getUsage() throws ApplicationNotConfiguredException
112 | {
113 | if (!Ward.isFirstLaunch())
114 | {
115 | UsageDto usageDto = new UsageDto();
116 |
117 | usageDto.setProcessor(getProcessor());
118 | usageDto.setRam(getRam());
119 | usageDto.setStorage(getStorage());
120 |
121 | return usageDto;
122 | }
123 | else
124 | {
125 | throw new ApplicationNotConfiguredException();
126 | }
127 | }
128 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/animations.css:
--------------------------------------------------------------------------------
1 | /*
2 | Animations file
3 | Used for define animations of project
4 |
5 | Every category must follow convention:
6 | * Category must begins with "animation" word
7 | * Further should be followed by animation property name
8 |
9 | Every entry must follow convention:
10 | * Must begins with category name
11 | * Further should be followed by tag/class/id/animation name/etc.
12 |
13 | By example: --animation-duration-wiggle
14 | */
15 |
16 | :root
17 | {
18 | /* animation-duration */
19 | --animation-duration-fade-in-setup-div: 0.4s;
20 | --animation-duration-fade-in-square: 0.5s;
21 | --animation-duration-wiggle-usage-value: 0.6s;
22 | --animation-duration-fade-in-triangle: 0.5s;
23 | --animation-duration-fade-in-error-div: 0.8s;
24 |
25 | /* animation-delay */
26 | --animation-delay-chart-triangle-grid-div: 1s;
27 | --animation-delay-usage-value-first: 0.2s;
28 | --animation-delay-usage-value-second: 0.4s;
29 | --animation-delay-usage-value-third: 0.6s;
30 | }
31 |
32 | @keyframes fade-in-setup-div
33 | {
34 | 0%
35 | {
36 | opacity: 0;
37 | }
38 | 100%
39 | {
40 | opacity: 1;
41 | }
42 | }
43 |
44 | @keyframes fade-in-square
45 | {
46 | 0%
47 | {
48 | top: 0.000rem;
49 | opacity: 0;
50 | }
51 | 100%
52 | {
53 | top: 0.563rem;
54 | opacity: 1;
55 | }
56 | }
57 |
58 | @keyframes fade-out-square
59 | {
60 | 0%
61 | {
62 | top: 0.563rem;
63 | opacity: 1;
64 | }
65 | 100%
66 | {
67 | top: 0.000rem;
68 | opacity: 0;
69 | }
70 | }
71 |
72 | @keyframes wiggle-usage-value
73 | {
74 | 0%
75 | {
76 | top: 0.000rem;
77 | }
78 | 50%
79 | {
80 | top: -2rem;
81 | }
82 | 100%
83 | {
84 | top: 0.000rem;
85 | }
86 | }
87 |
88 | @keyframes fade-in-cloud-left
89 | {
90 | 0%
91 | {
92 | left: -5.000rem;
93 | }
94 | 100%
95 | {
96 | left: 0.000rem;
97 | }
98 | }
99 |
100 | @keyframes fade-out-cloud-left
101 | {
102 | 0%
103 | {
104 | left: 0.000rem;
105 | }
106 | 100%
107 | {
108 | left: -5.000rem;
109 | }
110 | }
111 |
112 | @keyframes fade-in-cloud-right
113 | {
114 | 0%
115 | {
116 | left: 17.875rem;
117 | }
118 | 100%
119 | {
120 | left: 12.875rem;
121 | }
122 | }
123 |
124 | @keyframes fade-out-cloud-right
125 | {
126 | 0%
127 | {
128 | left: 12.875rem;
129 | }
130 | 100%
131 | {
132 | left: 17.875rem;
133 | }
134 | }
135 |
136 | @keyframes fade-in-triangle
137 | {
138 | 0%
139 | {
140 | top: 0.000rem;
141 | opacity: 0;
142 | }
143 | 100%
144 | {
145 | top: 0.563rem;
146 | opacity: 1;
147 | }
148 | }
149 |
150 | @keyframes fade-out-triangle
151 | {
152 | 0%
153 | {
154 | top: 0.563rem;
155 | opacity: 1;
156 | }
157 | 100%
158 | {
159 | top: 0.000rem;
160 | opacity: 0;
161 | }
162 | }
163 |
164 | @keyframes fade-in-error-div
165 | {
166 | 0%
167 | {
168 | bottom: 3.125rem;
169 | opacity: 0;
170 | }
171 | 100%
172 | {
173 | bottom: 7.500rem;
174 | opacity: 1;
175 | }
176 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/assets/dhtmlx.dark.min.css:
--------------------------------------------------------------------------------
1 | .dhtmlx_message_area{position:fixed;right:5px;width:250px;z-index:1000}.dhtmlx-info{min-width:350px;min-height:35px;padding:4px 4px 4px 20px;font-family:Tahoma;z-index:10000;margin:5px;margin-bottom:10px;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease}.dhtmlx-info.hidden{height:0;min-height:0;padding-top:0;padding-bottom:0;border-width:0;margin-top:0;margin-bottom:0;overflow:hidden}.dhtmlx_modal_box{overflow:hidden;display:inline-block;min-width:300px;width:300px;text-align:center;position:fixed;background-color:#fff;background:-webkit-linear-gradient(top,#fff 1%,#d0d0d0 99%);background:-moz-linear-gradient(top,#fff 1%,#d0d0d0 99%);box-shadow:0 0 14px #888;font-family:Tahoma;z-index:20000;border-radius:6px;border:1px solid #fff}.dhtmlx_popup_title{border-top-left-radius:5px;border-top-right-radius:5px;border-width:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAoCAMAAAAIaGBFAAAAhFBMVEVwcHBubm5sbGxqampoaGhmZmZlZWVjY2NhYWFfX19dXV1bW1taWlpYWFhWVlZUVFRSUlJRUVFPT09NTU1LS0tJSUlHR0dGRkZERERCQkJAQEA+Pj49PT09PT0+Pj5AQEBBQUFDQ0NERERGRkZHR0dJSUlKSkpMTExMTEw5OTk5OTk5OTkny8YEAAAAQklEQVQImQXBCRJCAAAAwKVSQqdyjSPXNP7/QLsIhA6OTiJnF7GrRCpzc/fw9PKW+/gqlCq1RqvTG/yMJrPF6m/bAVEhAxxnHG0oAAAAAElFTkSuQmCC);background-image:-webkit-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%);background-image:-moz-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%)}.dhtmlx-info,.dhtmlx_button,.dhtmlx_popup_button{user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:pointer}.dhtmlx_popup_text{overflow:hidden}.dhtmlx_popup_controls{border-radius:6px;padding:5px}.dhtmlx_button,.dhtmlx_popup_button{height:30px;line-height:30px;display:inline-block;margin:0 5px;border-radius:6px;color:#fff}.dhtmlx_popup_button{min-width:120px}div.dhx_modal_cover{background-color:#000;cursor:default;opacity:.2;position:fixed;z-index:19999;left:0;top:0;width:100%;height:100%;border:none;zoom:1}.dhtmlx-info img,.dhtmlx_modal_box img{float:left;margin-right:20px}.dhtmlx-info img{margin-left:-10px}.dhtmlx-alert-error .dhtmlx_popup_title,.dhtmlx-confirm-error .dhtmlx_popup_title{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAsCAIAAAArRUU2AAAATklEQVR4nIWLuw2AMBBDjVuQiBT2oWbRDATrnB0KQOJoqPzRe3BrHI6dcBASYREKovtK6/6DsDOX+stN+3H1YX9ciRgnYq5EWYhS2dftBIuLT4JyIrPCAAAAAElFTkSuQmCC)}.dhtmlx-alert-error,.dhtmlx-confirm-error{border:1px solid red}.dhtmlx_button,.dhtmlx_popup_button{box-shadow:0 0 4px #888;border:1px solid #838383}.dhtmlx_button input,.dhtmlx_popup_button div{border:1px solid #fff;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAMAAADaS4T1AAAAYFBMVEVwcHBtbW1ra2toaGhmZmZjY2NhYWFeXl5cXFxaWlpXV1dVVVVSUlJQUFBNTU1LS0tJSUlGRkZERERBQUE/Pz88PDw9PT0+Pj5AQEBCQkJDQ0NFRUVHR0dISEhKSkpMTEzqthaMAAAAMklEQVQImQXBhQ2AMAAAsOIMlwWH/8+kRSKVyRVKlVrQaHV6g9FktlhFm93hdLk9Xt8PIfgBvdUqyskAAAAASUVORK5CYII=);background-image:-webkit-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 99%);background-image:-moz-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 99%);border-radius:6px;font-size:15px;-moz-box-sizing:content-box;box-sizing:content-box;color:#fff;padding:0;margin:0;vertical-align:top;height:28px;line-height:28px}.dhtmlx_button input:active,.dhtmlx_button input:focus,.dhtmlx_popup_button div:active,.dhtmlx_popup_button div:focus{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAMAAADaS4T1AAAAXVBMVEVwcHBubm5tbW1sbGxra2tpaWloaGhnZ2dmZmZlZWVjY2NiYmJhYWFgYGBfX19dXV1cXFxbW1taWlpZWVlXV1dWVlZVVVVUVFRTU1NRUVFQUFBPT09OTk5NTU1LS0tT9SY0AAAAMUlEQVQImQXBhQGAMAAAIGxnx2z9/00BiVQmVyhVakGj1ekNRpPZYhVtdofT5fZ4fT8hpwG05JjexgAAAABJRU5ErkJggg==);background-image:-webkit-linear-gradient(top,#707070 1%,#4c4c4c 99%);background-image:-moz-linear-gradient(top,#707070 1%,#4c4c4c 99%)}.dhtmlx_popup_title{color:#fff;text-shadow:1px 1px #000;height:40px;line-height:40px;font-size:20px}.dhtmlx_popup_text{margin:15px 15px 5px 15px;font-size:14px;color:#000;min-height:30px;border-radius:6px}.dhtmlx-error,.dhtmlx-info{font-size:14px;color:#fff;box-shadow:0 4px 4px -4px #000;border-radius:5px;background-color:#000;background-color:rgba(0,0,0,.8)}.dhtmlx-error{color:red}
--------------------------------------------------------------------------------
/src/main/resources/static/css/assets/dhtmlx.light.min.css:
--------------------------------------------------------------------------------
1 | .dhtmlx_message_area{position:fixed;right:5px;width:250px;z-index:1000}.dhtmlx-info{min-width:350px;min-height:30px;padding:4px 4px 4px 20px;font-family:Tahoma;z-index:10000;margin:5px;margin-bottom:10px;-webkit-transition:all .5s ease;-moz-transition:all .5s ease;-o-transition:all .5s ease;transition:all .5s ease}.dhtmlx-info.hidden{height:0;min-height:0;padding-top:0;padding-bottom:0;border-width:0;margin-top:0;margin-bottom:0;overflow:hidden}.dhtmlx_modal_box{overflow:hidden;display:inline-block;min-width:300px;width:300px;text-align:center;position:fixed;background-color:#fff;background:-webkit-linear-gradient(top,#fff 1%,#d0d0d0 99%);background:-moz-linear-gradient(top,#fff 1%,#d0d0d0 99%);box-shadow:0 0 14px #888;font-family:Tahoma;z-index:20000;border-radius:6px;border:1px solid #fff}.dhtmlx_popup_title{border-top-left-radius:5px;border-top-right-radius:5px;border-width:0;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAoCAMAAAAIaGBFAAAAhFBMVEVwcHBubm5sbGxqampoaGhmZmZlZWVjY2NhYWFfX19dXV1bW1taWlpYWFhWVlZUVFRSUlJRUVFPT09NTU1LS0tJSUlHR0dGRkZERERCQkJAQEA+Pj49PT09PT0+Pj5AQEBBQUFDQ0NERERGRkZHR0dJSUlKSkpMTExMTEw5OTk5OTk5OTkny8YEAAAAQklEQVQImQXBCRJCAAAAwKVSQqdyjSPXNP7/QLsIhA6OTiJnF7GrRCpzc/fw9PKW+/gqlCq1RqvTG/yMJrPF6m/bAVEhAxxnHG0oAAAAAElFTkSuQmCC);background-image:-webkit-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%);background-image:-moz-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 97%,#393939 97%)}.dhtmlx-info,.dhtmlx_button,.dhtmlx_popup_button{user-select:none;-webkit-user-select:none;-moz-user-select:-moz-none;cursor:pointer}.dhtmlx_popup_text{overflow:hidden}.dhtmlx_popup_controls{border-radius:6px;padding:5px}.dhtmlx_button,.dhtmlx_popup_button{height:30px;line-height:30px;display:inline-block;margin:0 5px;border-radius:6px;color:#fff}.dhtmlx_popup_button{min-width:120px}div.dhx_modal_cover{background-color:#000;cursor:default;opacity:.2;position:fixed;z-index:19999;left:0;top:0;width:100%;height:100%;border:none;zoom:1}.dhtmlx-info img,.dhtmlx_modal_box img{float:left;margin-right:20px}.dhtmlx-alert-error .dhtmlx_popup_title,.dhtmlx-confirm-error .dhtmlx_popup_title{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAsCAIAAAArRUU2AAAATklEQVR4nIWLuw2AMBBDjVuQiBT2oWbRDATrnB0KQOJoqPzRe3BrHI6dcBASYREKovtK6/6DsDOX+stN+3H1YX9ciRgnYq5EWYhS2dftBIuLT4JyIrPCAAAAAElFTkSuQmCC)}.dhtmlx-alert-error,.dhtmlx-confirm-error{border:1px solid red}.dhtmlx_button,.dhtmlx_popup_button{box-shadow:0 0 4px #888;border:1px solid #838383}.dhtmlx_button input,.dhtmlx_popup_button div{border:1px solid #fff;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAMAAADaS4T1AAAAYFBMVEVwcHBtbW1ra2toaGhmZmZjY2NhYWFeXl5cXFxaWlpXV1dVVVVSUlJQUFBNTU1LS0tJSUlGRkZERERBQUE/Pz88PDw9PT0+Pj5AQEBCQkJDQ0NFRUVHR0dISEhKSkpMTEzqthaMAAAAMklEQVQImQXBhQ2AMAAAsOIMlwWH/8+kRSKVyRVKlVrQaHV6g9FktlhFm93hdLk9Xt8PIfgBvdUqyskAAAAASUVORK5CYII=);background-image:-webkit-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 99%);background-image:-moz-linear-gradient(top,#707070 1%,#3d3d3d 70%,#4c4c4c 99%);border-radius:6px;font-size:15px;font-weight:400;-moz-box-sizing:content-box;box-sizing:content-box;color:#fff;padding:0;margin:0;vertical-align:top;height:28px;line-height:28px}.dhtmlx_button input:active,.dhtmlx_button input:focus,.dhtmlx_popup_button div:active,.dhtmlx_popup_button div:focus{background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAMAAADaS4T1AAAAXVBMVEVwcHBubm5tbW1sbGxra2tpaWloaGhnZ2dmZmZlZWVjY2NiYmJhYWFgYGBfX19dXV1cXFxbW1taWlpZWVlXV1dWVlZVVVVUVFRTU1NRUVFQUFBPT09OTk5NTU1LS0tT9SY0AAAAMUlEQVQImQXBhQGAMAAAIGxnx2z9/00BiVQmVyhVakGj1ekNRpPZYhVtdofT5fZ4fT8hpwG05JjexgAAAABJRU5ErkJggg==);background-image:-webkit-linear-gradient(top,#707070 1%,#4c4c4c 99%);background-image:-moz-linear-gradient(top,#707070 1%,#4c4c4c 99%)}.dhtmlx_popup_title{color:#fff;text-shadow:1px 1px #000;height:40px;line-height:40px;font-size:20px}.dhtmlx_popup_text{margin:15px 15px 5px 15px;font-size:14px;color:#000;min-height:30px;border-radius:6px}.dhtmlx-error,.dhtmlx-info{font-size:14px;color:#000;box-shadow:0 0 10px #888;padding:0;background-color:#fff;border-radius:3px;border:1px solid #fff}.dhtmlx-info div{padding:5px 10px 5px 10px;background-color:#fff;border-radius:3px}.dhtmlx-error{background-color:#d81b1b;border:1px solid #ff3c3c;box-shadow:0 0 10px #000}.dhtmlx-error div{background-color:#d81b1b;border:1px solid #940000;color:#fff}
--------------------------------------------------------------------------------
/src/main/resources/static/css/colors.css:
--------------------------------------------------------------------------------
1 | /*
2 | Colors file
3 | Used for define colors of project
4 |
5 | Every category must follow convention:
6 | * Category must contain only color name
7 |
8 | Every entry must follow convention:
9 | * Must begins with category name
10 | * Further should be followed by tint/opacity/etc.
11 |
12 | By example: --grey-light
13 | */
14 |
15 | :root
16 | {
17 | /* white */
18 | --white: rgba(255, 255, 255, 1);
19 | --white-opacity-40: rgba(255, 255, 255, 0.4);
20 | --white-opacity-70: rgba(255, 255, 255, 0.7);
21 | --white-opacity-90: rgba(255, 255, 255, 0.9);
22 |
23 | /* black */
24 | --black: rgba(0, 0, 0, 1);
25 | --black-opacity-10: rgba(0, 0, 0, 0.1);
26 |
27 | /* grey */
28 | --grey-light: rgba(188, 188, 188, 1);
29 | --grey: rgba(121, 121, 121, 1);
30 | --grey-opacity-90: rgba(121, 121, 121, 0.9);
31 | --grey-opacity-70: rgba(121, 121, 121, 0.7);
32 | --grey-dimmed: rgba(90, 90, 90, 1);
33 | --grey-dark: rgba(60, 60, 60, 1);
34 |
35 | /* blue */
36 | --blue-light: rgba(121, 131, 247, 1);
37 | --blue-form: rgba(230, 232, 254, 1);
38 | --blue: rgba(89, 101, 249, 1);
39 |
40 | /* red */
41 | --red-light: rgba(255, 117, 117, 1);
42 | --red-form: rgba(249, 226, 226, 1);
43 | --red: rgba(255, 89, 89, 1);
44 |
45 | /* green */
46 | --green-light: rgba(70, 191, 157, 1);
47 | --green-form: rgba(212, 242, 225, 1);
48 | --green: rgba(8, 193, 141, 1);
49 |
50 | /* purple */
51 | --purple-light: rgba(228, 227, 239, 1);
52 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/dimensions.css:
--------------------------------------------------------------------------------
1 | /*
2 | Dimensions file
3 | Used for define dimensions of project
4 |
5 | Every category must follow convention:
6 | * Category must contain only css property name
7 |
8 | Every entry must follow convention:
9 | * Must begins with category name
10 | * Further should be followed by tag/class/id/etc.
11 |
12 | By example: --height-body
13 | */
14 |
15 | :root {
16 | /* top */
17 | --top-logo: 2.188rem;
18 | --top-logo-description: 5.3rem;
19 | --top-clouds-first: 2.875rem;
20 | --top-clouds-second: 2.875rem;
21 | --top-main-settings-input: 0.125rem;
22 | --top-main-settings-underline: 0.313rem;
23 | --top-main-settings-select: 0.938rem;
24 | --top-label-additional-settings: 2.3rem;
25 | --top-additional-settings: 1rem;
26 | --top-theme-buttons-input: 1.938rem;
27 | --top-background-settings: 2.938rem;
28 | --top-button-squares-grid: 0.222rem;
29 | --top-port: 2.7rem;
30 | --top-header: 1.5rem;
31 | --top-label-hw-info: 0.562rem;
32 | --top-info-label: 4.188rem;
33 | --top-inner-dot: 0.375rem;
34 | --top-detailed-hw-info-div: 1.168rem;
35 | --top-announcement: 3.813rem;
36 | --top-uptime-rectangle-grid: 1.925rem;
37 | --top-chart-label: 1.5rem;
38 | --top-chart-triangle-grid: 0.5rem;
39 | --top-chart-rectangle-grid: 1.906rem;
40 | --top-chart-container: 3.375rem;
41 | --top-code: 1.813rem;
42 | --top-title: 3.5rem;
43 | --top-explanation: 6.688rem;
44 |
45 | /* bottom */
46 | --bottom-form-squares-grid: 0.813rem;
47 | --bottom-submit: 1.125rem;
48 | --bottom-usage: 4.625rem;
49 | --bottom-hw-usage-div: 0.25rem;
50 | --bottom-values-grid-div-p: 0.25rem;
51 | --bottom-project-version: 1.25rem;
52 | --bottom-error-div: 7.5rem;
53 | --bottom-advice: 0.563rem;
54 |
55 | /* left */
56 | --left-clouds-second: 12.875rem;
57 | --left-form-squares-grid: 9.25rem;
58 | --left-main-settings: 1.5rem;
59 | --left-button-squares-grid-first: 1.5rem;
60 | --left-button-squares-grid-second: 19.688rem;
61 | --left-background-settings: 1.5rem;
62 | --left-theme-buttons-first: 1.5rem;
63 | --left-background-settings-color-selector: 1.5rem;
64 | --left-port: 1.5rem;
65 | --left-submit: 6.563rem;
66 | --left-header: 1.5rem;
67 | --left-label-hw-info: 4.375rem;
68 | --left-usage: 1.5rem;
69 | --left-inner-dot: 0.375rem;
70 | --left-detailed-hw-info-first: 0.822rem;
71 | --left-detailed-hw-info-second: 8.104rem;
72 | --left-detailed-hw-info-third: 15.385rem;
73 | --left-dividers-first: 7.313rem;
74 | --left-dividers-second: 14.563rem;
75 | --left-uptime-rectangle-grid: 2.23rem;
76 | --left-chart-label: 1.5rem;
77 | --left-chart-triangle-grid-first: 34.375rem;
78 | --left-chart-triangle-grid-second: 38.25rem;
79 | --left-chart-triangle-grid-third: 42.125rem;
80 | --left-chart-rectangle-grid-first: 33.25rem;
81 | --left-chart-rectangle-grid-second: 37.125rem;
82 | --left-chart-rectangle-grid-third: 41rem;
83 | --left-chart-container: 1.5rem;
84 | --left-error-div: 13.25rem;
85 | --left-code: 1.813rem;
86 | --left-title: 1.813rem;
87 | --left-explanation: 1.813rem;
88 |
89 | /* margin */
90 | --margin-hardware-icon: 0.65rem;
91 |
92 | /* margin-right */
93 | --margin-right-form-squares-grid-div: 0.488rem;
94 | --margin-right-theme-buttons-first: 1.938rem;
95 | --margin-right-usage-value: 2.937rem;
96 | --margin-right-values-grid-div: 0.125rem;
97 | --margin-right-labels-grid-div: 0.125rem;
98 |
99 | /* margin-bottom */
100 | --margin-bottom-label-main-settings: 0.438rem;
101 | --margin-bottom-card: 1.875rem;
102 | --margin-bottom-labels-grid-div: 0.313rem;
103 |
104 | /* height */
105 | --height-body: 100%;
106 | --height-setup: 26.706rem;
107 | --height-setup-div: 32.706rem;
108 | --height-clouds: 8.281rem;
109 | --height-clouds-img: 5.438rem;
110 | --height-background: 8.281rem;
111 | --height-form: 24.425rem;
112 | --height-form-squares-grid-div: 0.625rem;
113 | --height-main-settings: 1.875rem;
114 | --height-main-settings-underline: 0.313rem;
115 | --height-main-settings-select: 1.875rem;
116 | --height-theme-buttons-input: 2.188rem;
117 | --height-background-settings: 2.188rem;
118 | --height-button-squares-grid-div: 0.625rem;
119 | --height-port: 3.125rem;
120 | --height-submit: 1.875rem;
121 | --height-index-xl: 35.031rem;
122 | --height-index-lg: 53.438rem;
123 | --height-index-md: 53.438rem;
124 | --height-hw-logo: 3.75rem;
125 | --height-usage: 5.313rem;
126 | --height-main-hw-info: 100%;
127 | --height-usage-value-span: 5.8rem;
128 | --height-usage-underline: 0.313rem;
129 | --height-footer: 3.125rem;
130 | --height-inner-dot: 0.75rem;
131 | --height-detailed-hw-info-div: 1.063rem;
132 | --height-dividers-div: 3.125rem;
133 | --height-uptime: 8.27rem;
134 | --height-values-grid-div: 3.188rem;
135 | --height-labels-grid-div: 0.813rem;
136 | --height-chart-rectangle-grid-div: 0.625rem;
137 | --height-chart-container: 11.688rem;
138 | --height-error: 25.75rem;
139 | --height-error-img: 19.313rem;
140 | --height-error-div: 12.125rem;
141 | --height-hardware-icon: 2.5rem;
142 |
143 | /* max-height */
144 | --max-height-card: 16.562rem;
145 |
146 | /* min-height */
147 | --min-height-card: 16.562rem;
148 |
149 | /* width */
150 | --width-body: 100%;
151 | --width-dhtmlx-message-area: 21.875rem;
152 | --width-setup-div: 21.875rem;
153 | --width-logo: 21.875rem;
154 | --width-logo-description: 21.875rem;
155 | --width-clouds: 21.875rem;
156 | --width-clouds-img: 4.375rem;
157 | --width-background: 21.875rem;
158 | --width-form: 21.875rem;
159 | --width-form-squares-grid-div: 0.625rem;
160 | --width-main-settings: 18.875rem;
161 | --width-main-settings-input: 18.875rem;
162 | --width-main-settings-underline: 18.875rem;
163 | --width-main-settings-select: 18.875rem;
164 | --width-theme-buttons-input: 9.063rem;
165 | --width-background-settings-input: 9.063rem;
166 | --width-button-squares-grid-div: 0.625rem;
167 | --width-port: 18.875rem;
168 | --width-submit: 8.75rem;
169 | --width-hw-logo: 3.75rem;
170 | --width-usage: 18.875rem;
171 | --width-usage-value-span: 2.224rem;
172 | --width-info-label: 9.5rem;
173 | --width-usage-underline: 9.5rem;
174 | --width-footer: 100%;
175 | --width-inner-dot: 0.75rem;
176 | --width-detailed-hw-info-div: 5.625rem;
177 | --width-dividers-div: 0.063rem;
178 | --width-announcement: 21.875rem;
179 | --width-uptime: 100%;
180 | --width-values-grid-div: 3.75rem;
181 | --width-labels-grid-div: 3.75rem;
182 | --day-width-values-grid-div: 5rem;
183 | --day-width-labels-grid-div: 5rem;
184 | --width-chart-rectangle-grid-div: 3.125rem;
185 | --width-chart-container: 42.625rem;
186 | --width-error-img: 19.313rem;
187 | --width-error-div: 23.875rem;
188 | --width-advice: 23.875rem;
189 | --width-hardware-icon: 2.5rem;
190 |
191 | /* max-width */
192 | --max-width-setup: 71.25rem;
193 | --max-width-index-xl: 71.25rem;
194 | --max-width-index-lg: 47.5rem;
195 | --max-width-index-md: 23.75rem;
196 | --max-width-col-sm-12-col-md-6-col-lg-6-col-xl-4: 23.75rem;
197 | --max-width-col-lg-12-col-xl-8: 47.5rem;
198 |
199 | /* min-width */
200 | --min-width-setup: 71.25rem;
201 | --min-width-index-xl: 71.25rem;
202 | --min-width-index-lg: 47.5rem;
203 | --min-width-index-md: 23.75rem;
204 | --min-width-col-sm-12-col-md-6-col-lg-6-col-xl-4: 23.75rem;
205 | --min-width-col-lg-12-col-xl-8: 47.5rem;
206 | --min-width-error: 71.25rem;
207 |
208 | /* border */
209 | --border-chart-container: 0.063rem;
210 |
211 | /* border-width */
212 | --border-width-chart-triangle-grid-div: 0.438rem 0.438rem 0rem 0.438rem;
213 |
214 | /* border-radius */
215 | --border-radius-setup-div: 1.25rem;
216 | --border-radius-port: 0rem 0rem 0.625rem 0.625rem;
217 | --border-radius-card: 1.25rem;
218 | --border-radius-hw-logo: 50%;
219 | --border-radius-inner-dot: 50%;
220 | --border-radius-error-img: 50%;
221 | --border-radius-error-div: 1.25rem;
222 |
223 | /* letter-spacing */
224 | --letter-spacing-2px: 0.125rem;
225 | --letter-spacing-5px: 0.313rem;
226 | --letter-spacing-10px: 0.625rem;
227 |
228 | /* transition */
229 | --transition-all: color 0.2s, background 0.2s, transform 0.07s, opacity 0.4s;
230 |
231 | /* transform */
232 | --transform-form-squares-grid-second: scale(1.3);
233 | --transform-theme-buttons-input-active: scale(0.9);
234 | --transform-submit-active: scale(0.9);
235 | --transform-chart-rectangle-grid-div-active: scale(0.9);
236 | }
237 |
--------------------------------------------------------------------------------
/src/main/resources/static/css/fonts.css:
--------------------------------------------------------------------------------
1 | /*
2 | Fonts file
3 | Used for define fonts of project
4 |
5 | Every category must follow convention:
6 | * Category must begins with "font" word
7 | * Further should be followed by font property name
8 |
9 | Every entry must follow convention:
10 | * Must begins with category name
11 | * Further should be followed by size/weight/family/etc.
12 |
13 | By example: --font-weight-regular
14 | */
15 |
16 | :root
17 | {
18 | /* font-family */
19 | --font-family-roboto: roboto;
20 |
21 | /* font-size */
22 | --font-size-9pt: 0.563em;
23 | --font-size-10pt: 0.625em;
24 | --font-size-11pt: 0.688em;
25 | --font-size-12pt: 0.750em;
26 | --font-size-13pt: 0.813em;
27 | --font-size-14pt: 0.875em;
28 | --font-size-18pt: 1.125em;
29 | --font-size-21pt: 1.313em;
30 | --font-size-31pt: 1.938em;
31 | --font-size-42pt: 2.625em;
32 | --font-size-62pt: 3.875em;
33 |
34 | /* font-weight */
35 | --font-weight-regular: 400;
36 | --font-weight-bold: 700;
37 | }
38 |
39 | @font-face
40 | {
41 | font-family: roboto;
42 | font-weight: 400;
43 | src: url(/fonts/roboto/regular.woff2) format('woff2');
44 | }
45 |
46 | @font-face
47 | {
48 | font-family: roboto;
49 | font-weight: 700;
50 | src: url(/fonts/roboto/bold.woff2) format('woff2');
51 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/gradients.css:
--------------------------------------------------------------------------------
1 | /*
2 | Gradients file
3 | Used for define gradients of project
4 |
5 | Every category must follow convention:
6 | * Category must contain only gradient type name
7 |
8 | Every entry must follow convention:
9 | * Must begins with category name
10 | * Further should be followed by tag/class/id/etc.
11 |
12 | By example: --linear-gradient-uptime
13 | */
14 |
15 | :root
16 | {
17 | /* linear-gradient */
18 | --linear-gradient-form-light: linear-gradient(45deg, var(--blue-form) 0%, var(--red-form) 50%, var(--green-form) 100%);
19 | --linear-gradient-form-dark: linear-gradient(45deg, var(--grey) 0%, var(--grey-dimmed) 50%, var(--grey) 100%);
20 | --linear-gradient-uptime-light: linear-gradient(45deg, var(--blue-form) 0%, var(--red-form) 50%, var(--green-form) 100%);
21 | --linear-gradient-uptime-dark: linear-gradient(45deg, var(--grey) 0%, var(--grey-dimmed) 50%, var(--grey) 100%);
22 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/layout.css:
--------------------------------------------------------------------------------
1 | /*
2 | Layout css file
3 | New classes, indexes and overrides must be defined here
4 |
5 | Every category must follow convention:
6 | * Category must contain page name (Exception are base classes)
7 | * Page name must be followed by word "elements"
8 |
9 | By example: index elements
10 | */
11 |
12 | /* base elements */
13 | * {
14 | font-family: var(--font-family-roboto);
15 | transition: var(--transition-all);
16 | }
17 |
18 | body {
19 | position: fixed;
20 | top: 0;
21 | left: 0;
22 | height: var(--height-body);
23 | width: var(--width-body);
24 | background: var(--background-body);
25 | }
26 |
27 | .logo {
28 | position: absolute;
29 | top: var(--top-logo);
30 | z-index: 1;
31 | width: var(--width-logo);
32 | text-align: center;
33 | letter-spacing: var(--letter-spacing-10px);
34 | font-size: var(--font-size-42pt);
35 | font-weight: var(--font-weight-regular);
36 | color: var(--color-logo);
37 | }
38 |
39 | .logo-description {
40 | position: absolute;
41 | top: var(--top-logo-description);
42 | z-index: 1;
43 | width: var(--width-logo-description);
44 | text-align: center;
45 | letter-spacing: var(--letter-spacing-2px);
46 | font-size: var(--font-size-9pt);
47 | font-weight: var(--font-weight-regular);
48 | color: var(--color-logo-description);
49 | }
50 |
51 | .clouds {
52 | height: var(--height-clouds);
53 | width: var(--width-clouds);
54 | overflow: hidden;
55 | }
56 |
57 | .clouds > img {
58 | position: relative;
59 | z-index: 1;
60 | height: var(--height-clouds-img);
61 | width: var(--width-clouds-img);
62 | }
63 |
64 | .clouds > .first {
65 | top: var(--top-clouds-first);
66 | }
67 |
68 | .clouds > .second {
69 | top: var(--top-clouds-second);
70 | left: var(--left-clouds-second);
71 | }
72 |
73 | .background {
74 | position: absolute;
75 | top: 0;
76 | height: var(--height-background);
77 | width: var(--width-background);
78 | }
79 |
80 | /* setup elements */
81 | .dhtmlx_message_area {
82 | width: var(--width-dhtmlx-message-area);
83 | }
84 |
85 | .setup {
86 | margin-top: calc((100vh / 2) - (var(--height-setup) / 2));
87 | max-width: var(--max-width-setup);
88 | min-width: var(--min-width-setup);
89 | }
90 |
91 | .setup-div {
92 | display: block;
93 | position: relative;
94 | margin: auto;
95 | height: var(--height-setup-div);
96 | width: var(--width-setup-div);
97 | opacity: 0;
98 | background: white;
99 | border-radius: var(--border-radius-setup-div);
100 | overflow: hidden;
101 | box-shadow: var(--box-shadow-setup-div) var(--black-opacity-10);
102 | animation: fade-in-setup-div;
103 | animation-duration: var(--animation-duration-fade-in-setup-div);
104 | animation-fill-mode: forwards;
105 | }
106 |
107 | .form {
108 | position: absolute;
109 | bottom: 0;
110 | left: 0;
111 | height: var(--height-form);
112 | width: var(--width-form);
113 | background: var(--background-form);
114 | }
115 |
116 | .form-squares-grid {
117 | position: relative;
118 | bottom: var(--bottom-form-squares-grid);
119 | left: var(--left-form-squares-grid);
120 | }
121 |
122 | .form-squares-grid > div {
123 | display: inline-block;
124 | margin-right: var(--margin-right-form-squares-grid-div);
125 | height: var(--height-form-squares-grid-div);
126 | width: var(--width-form-squares-grid-div);
127 | box-shadow: var(--box-shadow-form-squares-grid-div) var(--black-opacity-10);
128 | }
129 |
130 | .form-squares-grid > .first {
131 | background: var(--background-form-squares-grid-first);
132 | }
133 |
134 | .form-squares-grid > .second {
135 | background: var(--background-form-squares-grid-second);
136 | transform: var(--transform-form-squares-grid-second);
137 | }
138 |
139 | .form-squares-grid > .third {
140 | background: var(--background-form-squares-grid-third);
141 | }
142 |
143 | .label-main-settings {
144 | position: relative;
145 | margin-bottom: var(--margin-bottom-label-main-settings);
146 | text-align: center;
147 | letter-spacing: var(--letter-spacing-2px);
148 | font-size: var(--font-size-9pt);
149 | font-weight: var(--font-weight-regular);
150 | color: var(--color-label-main-settings);
151 | }
152 |
153 | .main-settings {
154 | position: relative;
155 | left: var(--left-main-settings);
156 | height: var(--height-main-settings);
157 | width: var(--width-main-settings);
158 | background: var(--background-main-settings);
159 | }
160 |
161 | .main-settings > input {
162 | position: relative;
163 | top: var(--top-main-settings-input);
164 | width: var(--width-main-settings-input);
165 | text-align: center;
166 | font-size: var(--font-size-14pt);
167 | font-weight: var(--font-weight-regular);
168 | color: var(--color-main-settings-input);
169 | background: var(--background-main-settings-input);
170 | border: 0;
171 | outline: none;
172 | }
173 |
174 | .main-settings > input::placeholder {
175 | color: var(--color-main-settings-input-placeholder);
176 | }
177 |
178 | .main-settings > input::-webkit-input-placeholder {
179 | color: var(--color-main-settings-input-placeholder);
180 | }
181 |
182 | .main-settings > input::-moz-placeholder {
183 | opacity: 1;
184 | }
185 |
186 | .main-settings > input::-ms-clear {
187 | display: none;
188 | }
189 |
190 | .main-settings > select {
191 | position: relative;
192 | top: var(--top-main-settings-select);
193 | height: var(--height-main-settings-select);
194 | width: var(--width-main-settings-select);
195 | font-size: var(--font-size-14pt);
196 | font-weight: var(--font-weight-regular);
197 | color: var(--color-main-settings-input);
198 | background: var(--background-main-settings-select);
199 | border: 0;
200 | outline: none;
201 | }
202 |
203 | .main-settings-underline {
204 | position: relative;
205 | top: var(--top-main-settings-underline);
206 | height: var(--height-main-settings-underline);
207 | width: var(--width-main-settings-underline);
208 | background: var(--background-main-settings-underline);
209 | box-shadow: var(--box-shadow-main-settings-underline) var(--black-opacity-10);
210 | }
211 |
212 | .label-additional-settings {
213 | position: relative;
214 | top: var(--top-label-additional-settings);
215 | text-align: center;
216 | letter-spacing: var(--letter-spacing-2px);
217 | font-size: var(--font-size-9pt);
218 | font-weight: var(--font-weight-regular);
219 | color: var(--color-label-additional-settings);
220 | }
221 |
222 | .additional-settings {
223 | position: relative;
224 | top: var(--top-additional-settings);
225 | }
226 |
227 | .button-squares-grid {
228 | position: relative;
229 | top: var(--top-button-squares-grid);
230 | }
231 |
232 | .button-squares-grid > div {
233 | display: inline-block;
234 | position: absolute;
235 | height: var(--height-button-squares-grid-div);
236 | width: var(--width-button-squares-grid-div);
237 | opacity: 0;
238 | box-shadow: var(--box-shadow-button-squares-grid-div) var(--black-opacity-10);
239 | }
240 |
241 | .button-squares-grid > .first {
242 | left: var(--left-button-squares-grid-first);
243 | background: var(--background-button-squares-grid-first);
244 | animation: fade-in-square;
245 | animation-duration: var(--animation-duration-fade-in-square);
246 | animation-fill-mode: forwards;
247 | }
248 |
249 | .button-squares-grid > .second {
250 | left: var(--left-button-squares-grid-second);
251 | visibility: hidden;
252 | background: var(--background-button-squares-grid-second);
253 | }
254 |
255 | .theme-buttons > input {
256 | position: relative;
257 | top: var(--top-theme-buttons-input);
258 | height: var(--height-theme-buttons-input);
259 | width: var(--width-theme-buttons-input);
260 | letter-spacing: var(--letter-spacing-2px);
261 | font-size: var(--font-size-14pt);
262 | font-weight: var(--font-weight-regular);
263 | color: var(--color-theme-buttons-input);
264 | border: 0;
265 | outline: none;
266 | box-shadow: var(--box-shadow-theme-buttons-input) var(--black-opacity-10);
267 | }
268 |
269 | .theme-buttons > input:active {
270 | transform: var(--transform-theme-buttons-input-active);
271 | }
272 |
273 | .theme-buttons > .first {
274 | left: var(--left-theme-buttons-first);
275 | margin-right: var(--margin-right-theme-buttons-first);
276 | background: var(--background-theme-buttons-first);
277 | }
278 |
279 | .theme-buttons > .second {
280 | background: var(--background-theme-buttons-second);
281 | }
282 |
283 | .additional-settings > label {
284 | top: var(--top-background-settings);
285 | left: var(--left-background-settings);
286 | height: var(--height-background-settings);
287 | white-space: nowrap;
288 | }
289 |
290 | .additional-settings > label > input {
291 | vertical-align: middle;
292 | position: relative;
293 | left: var(--left-background-settings);
294 | border-style: none;
295 | }
296 |
297 | .additional-settings > label > span {
298 | vertical-align: middle;
299 | position: relative;
300 | }
301 |
302 | .additional-settings > .color-selector {
303 | display: block;
304 | position: relative;
305 | margin-top: var(--height-background-settings);
306 | left: var(--left-background-settings-color-selector);
307 | width: var(--width-background-settings-input);
308 | background: var(--background-background-settings-color-selector);
309 | box-shadow: var(--box-shadow-background-settings-input) var(--black-opacity-10);
310 | }
311 |
312 | .port {
313 | position: relative;
314 | top: var(--top-port);
315 | left: var(--left-port);
316 | height: var(--height-port);
317 | width: var(--width-port);
318 | text-align: center;
319 | letter-spacing: var(--letter-spacing-5px);
320 | font-size: var(--font-size-14pt);
321 | font-weight: var(--font-weight-regular);
322 | color: var(--color-port);
323 | background: var(--background-port);
324 | border-radius: var(--border-radius-port);
325 | border: 0;
326 | outline: none;
327 | }
328 |
329 | .port::placeholder {
330 | letter-spacing: 0;
331 | color: var(--color-port-placeholder);
332 | }
333 |
334 | .port::-webkit-input-placeholder {
335 | letter-spacing: 0;
336 | color: var(--color-port-placeholder);
337 | }
338 |
339 | .port::-moz-placeholder {
340 | letter-spacing: 0;
341 | opacity: 1;
342 | }
343 |
344 | .port::-ms-clear {
345 | display: none;
346 | }
347 |
348 | .submit {
349 | position: absolute;
350 | bottom: var(--bottom-submit);
351 | left: var(--left-submit);
352 | height: var(--height-submit);
353 | width: var(--width-submit);
354 | letter-spacing: var(--letter-spacing-2px);
355 | font-size: var(--font-size-14pt);
356 | font-weight: var(--font-weight-regular);
357 | color: var(--color-submit);
358 | background: var(--background-submit);
359 | border: 0;
360 | border-radius: 0.625rem;
361 | outline: none;
362 | box-shadow: var(--box-shadow-submit) var(--black-opacity-10);
363 | }
364 |
365 | .submit:active {
366 | transform: var(--transform-submit-active);
367 | }
368 |
369 | /* index elements */
370 | .index {
371 | margin-top: calc((100vh / 2) - (var(--height-index-xl) / 2));
372 | max-width: var(--max-width-index-xl);
373 | min-width: var(--min-width-index-xl);
374 | }
375 |
376 | @media only screen and (max-width: 75rem) {
377 | .index {
378 | margin-top: calc((100vh / 2) - (var(--height-index-lg) / 2));
379 | max-width: var(--max-width-index-lg);
380 | min-width: var(--min-width-index-lg);
381 | }
382 | }
383 |
384 | @media only screen and (max-width: 48rem) {
385 | .index {
386 | margin-top: calc((100vh / 2) - (var(--height-index-md) / 2));
387 | max-width: var(--max-width-index-md);
388 | min-width: var(--min-width-index-md);
389 | }
390 |
391 | .sm-hidden {
392 | visibility: hidden;
393 | }
394 | }
395 |
396 | .col-sm-12.col-md-6.col-lg-6.col-xl-4 {
397 | max-width: var(--max-width-col-sm-12-col-md-6-col-lg-6-col-xl-4);
398 | min-width: var(--min-width-col-sm-12-col-md-6-col-lg-6-col-xl-4);
399 | }
400 |
401 | .col-lg-12.col-xl-8 {
402 | max-width: var(--max-width-col-lg-12-col-xl-8);
403 | min-width: var(--min-width-col-lg-12-col-xl-8);
404 | }
405 |
406 | .card {
407 | margin-bottom: var(--margin-bottom-card);
408 | max-height: var(--max-height-card);
409 | min-height: var(--min-height-card);
410 | opacity: 0;
411 | border: none;
412 | border-radius: var(--border-radius-card);
413 | overflow: hidden;
414 | background: var(--background-card);
415 | box-shadow: var(--box-shadow-card) var(--black-opacity-10);
416 | }
417 |
418 | .header {
419 | position: relative;
420 | display: flex;
421 | top: var(--top-header);
422 | left: var(--left-header);
423 | }
424 |
425 | .hw-logo {
426 | height: var(--height-hw-logo);
427 | width: var(--width-hw-logo);
428 | border-radius: var(--border-radius-hw-logo);
429 | }
430 |
431 | .hw-logo.first {
432 | background: var(--background-hw-logo-first);
433 | }
434 |
435 | .hw-logo.second {
436 | background: var(--background-hw-logo-second);
437 | }
438 |
439 | .hw-logo.third {
440 | background: var(--background-hw-logo-third);
441 | }
442 |
443 | .label-hw-info {
444 | position: absolute;
445 | top: var(--top-label-hw-info);
446 | left: var(--left-label-hw-info);
447 | }
448 |
449 | .hw-type {
450 | font-size: var(--font-size-18pt);
451 | font-weight: var(--font-weight-bold);
452 | color: var(--color-hw-type);
453 | }
454 |
455 | .hw-name {
456 | font-size: var(--font-size-12pt);
457 | font-weight: var(--font-weight-regular);
458 | color: var(--color-hw-name);
459 | }
460 |
461 | .usage {
462 | position: absolute;
463 | height: var(--height-usage);
464 | width: var(--width-usage);
465 | bottom: var(--bottom-usage);
466 | left: var(--left-usage);
467 | }
468 |
469 | .main-hw-info {
470 | position: absolute;
471 | right: 0;
472 | height: var(--height-main-hw-info);
473 | }
474 |
475 | .hw-usage > div {
476 | position: absolute;
477 | right: 0;
478 | bottom: var(--bottom-hw-usage-div);
479 | font-size: var(--font-size-62pt);
480 | font-weight: var(--font-weight-bold);
481 | }
482 |
483 | .usage-value {
484 | display: flex;
485 | margin-right: var(--margin-right-usage-value);
486 | }
487 |
488 | .usage-value > span {
489 | position: relative;
490 | height: var(--height-usage-value-span);
491 | width: var(--width-usage-value-span);
492 | color: var(--color-usage-value-span);
493 | animation: wiggle-usage-value;
494 | animation-duration: var(--animation-duration-wiggle-usage-value);
495 | }
496 |
497 | .usage-value > .first {
498 | animation-delay: var(--animation-delay-usage-value-first);
499 | }
500 |
501 | .usage-value > .second {
502 | animation-delay: var(--animation-delay-usage-value-second);
503 | }
504 |
505 | .usage-value > .third {
506 | animation-delay: var(--animation-delay-usage-value-third);
507 | }
508 |
509 | .usage-postfix {
510 | color: var(--color-usage-postfix);
511 | }
512 |
513 | .info-label {
514 | position: relative;
515 | top: var(--top-info-label);
516 | width: var(--width-info-label);
517 | text-align: center;
518 | font-size: var(--font-size-9pt);
519 | font-weight: var(--font-weight-regular);
520 | color: var(--color-info-label);
521 | background: transparent;
522 | }
523 |
524 | .usage-underline {
525 | position: absolute;
526 | right: 0;
527 | bottom: 0;
528 | height: var(--height-usage-underline);
529 | width: var(--width-usage-underline);
530 | }
531 |
532 | .usage-underline.first {
533 | background: var(--background-usage-underline-first);
534 | }
535 |
536 | .usage-underline.second {
537 | background: var(--background-usage-underline-second);
538 | }
539 |
540 | .usage-underline.third {
541 | background: var(--background-usage-underline-third);
542 | }
543 |
544 | .footer {
545 | position: absolute;
546 | bottom: 0;
547 | left: 0;
548 | height: var(--height-footer);
549 | width: var(--width-footer);
550 | }
551 |
552 | .footer.first {
553 | background: var(--background-footer-first);
554 | }
555 |
556 | .footer.second {
557 | background: var(--background-footer-second);
558 | }
559 |
560 | .footer.third {
561 | background: var(--background-footer-third);
562 | }
563 |
564 | .inner-dot {
565 | position: absolute;
566 | top: var(--top-inner-dot);
567 | left: var(--left-inner-dot);
568 | height: var(--height-inner-dot);
569 | width: var(--width-inner-dot);
570 | border-radius: var(--border-radius-inner-dot);
571 | }
572 |
573 | .detailed-hw-info {
574 | position: absolute;
575 | }
576 |
577 | .detailed-hw-info > div {
578 | display: inline-block;
579 | position: absolute;
580 | top: var(--top-detailed-hw-info-div);
581 | height: var(--height-detailed-hw-info-div);
582 | width: var(--width-detailed-hw-info-div);
583 | text-align: center;
584 | font-size: var(--font-size-14pt);
585 | font-weight: var(--font-weight-regular);
586 | color: var(--color-detailed-hw-info-div);
587 | }
588 |
589 | .detailed-hw-info > .first {
590 | left: var(--left-detailed-hw-info-first);
591 | }
592 |
593 | .detailed-hw-info > .second {
594 | left: var(--left-detailed-hw-info-second);
595 | }
596 |
597 | .detailed-hw-info > .third {
598 | left: var(--left-detailed-hw-info-third);
599 | }
600 |
601 | .dividers {
602 | position: absolute;
603 | }
604 |
605 | .dividers > div {
606 | display: inline-block;
607 | position: absolute;
608 | height: var(--height-dividers-div);
609 | width: var(--width-dividers-div);
610 | background: var(--background-dividers-div);
611 | }
612 |
613 | .dividers > .first {
614 | left: var(--left-dividers-first);
615 | }
616 |
617 | .dividers > .second {
618 | left: var(--left-dividers-second);
619 | }
620 |
621 | .uptime {
622 | position: absolute;
623 | bottom: 0;
624 | left: 0;
625 | height: var(--height-uptime);
626 | width: var(--width-uptime);
627 | background: var(--background-uptime);
628 | }
629 |
630 | .uptime-rectangle-grid {
631 | position: absolute;
632 | top: var(--top-uptime-rectangle-grid);
633 | left: var(--left-uptime-rectangle-grid);
634 | }
635 |
636 | .values-grid > div {
637 | display: inline-block;
638 | margin-right: var(--margin-right-values-grid-div);
639 | height: var(--height-values-grid-div);
640 | width: var(--width-values-grid-div);
641 | text-align: center;
642 | font-size: var(--font-size-42pt);
643 | font-weight: var(--font-weight-bold);
644 | color: var(--color-values-grid-div);
645 | background: var(--background-values-grid-div);
646 | border-radius: 2px
647 | }
648 |
649 | .values-grid > div:first-child {
650 | width: var(--day-width-values-grid-div);
651 | }
652 |
653 | .values-grid > div > p {
654 | position: relative;
655 | bottom: var(--bottom-values-grid-div-p);
656 | }
657 |
658 | .labels-grid > div {
659 | display: inline-block;
660 | margin-right: var(--margin-right-labels-grid-div);
661 | margin-bottom: var(--margin-bottom-labels-grid-div);
662 | height: var(--height-labels-grid-div);
663 | width: var(--width-labels-grid-div);
664 | text-align: center;
665 | font-size: var(--font-size-9pt);
666 | font-weight: var(--font-weight-regular);
667 | color: var(--color-labels-grid-div);
668 | background: var(--background-labels-grid-div);
669 | border-radius: 2px
670 | }
671 |
672 | .labels-grid > div:first-child {
673 | width: var(--day-width-labels-grid-div);
674 | }
675 |
676 | .chart-label {
677 | position: absolute;
678 | top: var(--top-chart-label);
679 | left: var(--left-chart-label);
680 | font-size: var(--font-size-18pt);
681 | font-weight: var(--font-weight-bold);
682 | color: var(--color-chart-label);
683 | }
684 |
685 | .chart-triangle-grid {
686 | position: absolute;
687 | top: var(--top-chart-triangle-grid);
688 | }
689 |
690 | .chart-triangle-grid > div {
691 | position: absolute;
692 | border-style: solid;
693 | border-width: var(--border-width-chart-triangle-grid-div);
694 | opacity: 0;
695 | animation: fade-in-triangle;
696 | animation-duration: var(--animation-duration-fade-in-triangle);
697 | animation-delay: var(--animation-delay-chart-triangle-grid-div);
698 | animation-fill-mode: forwards;
699 | }
700 |
701 | .chart-triangle-grid > .first {
702 | left: var(--left-chart-triangle-grid-first);
703 | border-color: var(--border-color-chart-triangle-grid-first) transparent;
704 | }
705 |
706 | .chart-triangle-grid > .second {
707 | left: var(--left-chart-triangle-grid-second);
708 | border-color: var(--border-color-chart-triangle-grid-second) transparent;
709 | }
710 |
711 | .chart-triangle-grid > .third {
712 | left: var(--left-chart-triangle-grid-third);
713 | border-color: var(--border-color-chart-triangle-grid-third) transparent;
714 | }
715 |
716 | .chart-rectangle-grid {
717 | position: absolute;
718 | top: var(--top-chart-rectangle-grid);
719 | }
720 |
721 | .chart-rectangle-grid > div {
722 | display: inline-block;
723 | position: absolute;
724 | height: var(--height-chart-rectangle-grid-div);
725 | width: var(--width-chart-rectangle-grid-div);
726 | cursor: pointer;
727 | }
728 |
729 | .chart-rectangle-grid > div:active {
730 | transform: var(--transform-chart-rectangle-grid-div-active);
731 | }
732 |
733 | .chart-rectangle-grid > .first {
734 | left: var(--left-chart-rectangle-grid-first);
735 | background: var(--background-chart-rectangle-grid-first);
736 | }
737 |
738 | .chart-rectangle-grid > .second {
739 | left: var(--left-chart-rectangle-grid-second);
740 | background: var(--background-chart-rectangle-grid-second);
741 | }
742 |
743 | .chart-rectangle-grid > .third {
744 | left: var(--left-chart-rectangle-grid-third);
745 | background: var(--background-chart-rectangle-grid-third);
746 | }
747 |
748 | .chart-container {
749 | position: absolute;
750 | top: var(--top-chart-container);
751 | left: var(--left-chart-container);
752 | height: var(--height-chart-container);
753 | width: var(--width-chart-container);
754 | overflow: hidden;
755 | border: var(--border-chart-container) solid var(--grey-light);
756 | }
757 |
758 | #project-version {
759 | position: relative;
760 | bottom: var(--bottom-project-version);
761 | opacity: 0;
762 | font-size: var(--font-size-12pt);
763 | font-weight: var(--font-weight-regular);
764 | color: var(--color-project-version);
765 | }
766 |
767 | /* error classes */
768 | .error {
769 | margin-top: calc((100vh / 2) - (var(--height-error) / 2));
770 | max-width: var(--min-width-error);
771 | min-width: var(--min-width-error);
772 | }
773 |
774 | .error-img {
775 | display: block;
776 | position: relative;
777 | z-index: 1;
778 | margin: auto;
779 | height: var(--height-error-img);
780 | width: var(--width-error-img);
781 | object-fit: cover;
782 | border-radius: var(--border-radius-error-img);
783 | box-shadow: var(--box-shadow-error-img) var(--black-opacity-10);
784 | }
785 |
786 | .error-div {
787 | position: relative;
788 | left: var(--left-error-div);
789 | z-index: 1;
790 | height: var(--height-error-div);
791 | width: var(--width-error-div);
792 | opacity: 0;
793 | border-radius: var(--border-radius-error-div);
794 | background: var(--background-error-div);
795 | box-shadow: var(--box-shadow-error-div) var(--black-opacity-10);
796 | animation: fade-in-error-div;
797 | animation-duration: var(--animation-duration-fade-in-error-div);
798 | animation-fill-mode: forwards;
799 | }
800 |
801 | .error-div > div {
802 | position: absolute;
803 | }
804 |
805 | .code {
806 | top: var(--top-code);
807 | left: var(--left-code);
808 | font-size: var(--font-size-21pt);
809 | font-weight: var(--font-weight-bold);
810 | color: var(--color-code);
811 | }
812 |
813 | .title {
814 | top: var(--top-title);
815 | left: var(--left-title);
816 | font-size: var(--font-size-31pt);
817 | font-weight: var(--font-weight-bold);
818 | color: var(--color-title);
819 | }
820 |
821 | .explanation {
822 | top: var(--top-explanation);
823 | left: var(--left-explanation);
824 | }
825 |
826 | .explanation > div {
827 | font-size: var(--font-size-13pt);
828 | font-weight: var(--font-weight-regular);
829 | color: var(--color-explanation-div);
830 | }
831 |
832 | .advice {
833 | width: var(--width-advice);
834 | bottom: var(--bottom-advice);
835 | text-align: center;
836 | font-size: var(--font-size-11pt);
837 | font-weight: var(--font-weight-regular);
838 | color: var(--color-advice);
839 | }
840 |
841 | .hardware-icon {
842 | width: var(--width-hardware-icon);
843 | height: var(--height-hardware-icon);
844 | margin: var(--margin-hardware-icon);
845 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/shadows.css:
--------------------------------------------------------------------------------
1 | /*
2 | Shadows file
3 | Used for define shadows of project
4 |
5 | Every category must follow convention:
6 | * Category must contain only shadow type name
7 |
8 | Every entry must follow convention:
9 | * Must begins with category name
10 | * Further should be followed by tag/class/id/etc.
11 |
12 | By example: --box-shadow-card
13 | */
14 |
15 | :root
16 | {
17 | /* box-shadow */
18 | --box-shadow-setup-div: 0.000rem 0.313rem 0.625rem 0.000rem;
19 | --box-shadow-form-squares-grid-div: 0.000rem 0.188rem 0.313rem 0.000rem;
20 | --box-shadow-main-settings-underline: 0.000rem 0.188rem 0.313rem 0.000rem;
21 | --box-shadow-button-squares-grid-div: 0.000rem 0.188rem 0.313rem 0.000rem;
22 | --box-shadow-theme-buttons-input: 0.000rem 0.188rem 0.313rem 0.000rem;
23 | --box-shadow-background-settings-input: 0.000rem 0.188rem 0.313rem 0.000rem;
24 | --box-shadow-submit: 0.000rem 0.188rem 0.313rem 0.000rem;
25 | --box-shadow-card: 0.000rem 0.313rem 0.625rem 0.000rem;
26 | --box-shadow-uptime-squares-grid-div: 0.000rem 0.188rem 0.313rem 0.000rem;
27 | --box-shadow-error-img: 0.000rem 0.188rem 0.313rem 0.000rem;
28 | --box-shadow-error-div: 0.000rem 0.313rem 0.625rem 0.000rem;
29 | }
--------------------------------------------------------------------------------
/src/main/resources/static/css/themes.css:
--------------------------------------------------------------------------------
1 | /*
2 | Themes file
3 | Used for define themes of project
4 |
5 | Every category must follow convention:
6 | * Category must contain only theme name
7 |
8 | Every subcategory must follow convention:
9 | * Subcategory must contain only css property name
10 |
11 | Every entry must follow convention:
12 | * Must begins with subcategory name
13 | * Further should be followed by tag/class/id/etc.
14 |
15 | By example: --color-body
16 | */
17 |
18 | /* light */
19 | html[theme = "light"]
20 | {
21 | /* color */
22 | --color-logo: var(--white);
23 | --color-logo-description: var(--white);
24 | --color-label-main-settings: var(--grey);
25 | --color-main-settings-input: var(--grey);
26 | --color-main-settings-input-placeholder: var(--grey);
27 | --color-label-additional-settings: var(--grey);
28 | --color-theme-buttons-input: var(--grey);
29 | --color-port: var(--grey);
30 | --color-port-placeholder: var(--grey-light);
31 | --color-submit: var(--white);
32 | --color-hw-type: var(--black);
33 | --color-hw-name: var(--grey);
34 | --color-usage-value-span: var(--grey-light);
35 | --color-usage-postfix: var(--black);
36 | --color-info-label: var(--grey-light);
37 | --color-detailed-hw-info-div: var(--white);
38 | --color-announcement: var(--white);
39 | --color-uptime-dashboard-logo: var(--grey-light);
40 | --color-uptime-dashboard-logo-description: var(--grey-light);
41 | --color-values-grid-div: var(--grey);
42 | --color-labels-grid-div: var(--grey-light);
43 | --color-chart-label: var(--black);
44 | --color-project-version: var(--grey);
45 | --color-code: var(--black);
46 | --color-title: var(--black);
47 | --color-explanation-div: var(--grey);
48 | --color-advice: var(--grey-light);
49 |
50 | /* background */
51 | --background-body: var(--purple-light);
52 | --background-form: var(--linear-gradient-form-light);
53 | --background-form-squares-grid-first: var(--blue-light);
54 | --background-form-squares-grid-second: var(--red-light);
55 | --background-form-squares-grid-third: var(--green-light);
56 | --background-main-settings: var(--white);
57 | --background-main-settings-input: var(--white);
58 | --background-main-settings-select: var(--white);
59 | --background-main-settings-underline: var(--blue-light);
60 | --background-button-squares-grid-first: var(--purple-light);
61 | --background-button-squares-grid-second: var(--grey-light);
62 | --background-theme-buttons-first: var(--purple-light);
63 | --background-theme-buttons-second: var(--grey-light);
64 | --background-background-settings-color-selector: var(--grey-light);
65 | --background-port: var(--white);
66 | --background-submit: var(--green-light);
67 | --background-card: var(--white);
68 | --background-hw-logo-first: var(--blue-light);
69 | --background-hw-logo-second: var(--red-light);
70 | --background-hw-logo-third: var(--green-light);
71 | --background-usage-underline-first: var(--blue-light);
72 | --background-usage-underline-second: var(--red-light);
73 | --background-usage-underline-third: var(--green-light);
74 | --background-footer-first: var(--blue-light);
75 | --background-footer-second: var(--red-light);
76 | --background-footer-third: var(--green-light);
77 | --background-dividers-div: var(--white);
78 | --background-uptime: var(--linear-gradient-uptime-light);
79 | --background-values-grid-div: var(--white-opacity-70);
80 | --background-labels-grid-div: var(--white-opacity-90);
81 | --background-chart-rectangle-grid-first: var(--blue-light);
82 | --background-chart-rectangle-grid-second: var(--red-light);
83 | --background-chart-rectangle-grid-third: var(--green-light);
84 | --background-error-div: var(--white);
85 |
86 | /* border-color */
87 | --border-color-chart-triangle-grid-first: var(--blue);
88 | --border-color-chart-triangle-grid-second: var(--red);
89 | --border-color-chart-triangle-grid-third: var(--green);
90 | }
91 |
92 | /* dark */
93 | html[theme = "dark"]
94 | {
95 | /* color */
96 | --color-logo: var(--white);
97 | --color-logo-description: var(--white);
98 | --color-label-main-settings: var(--white);
99 | --color-main-settings-input: var(--white);
100 | --color-main-settings-input-placeholder: var(--grey-light);
101 | --color-label-additional-settings: var(--white);
102 | --color-theme-buttons-input: var(--grey);
103 | --color-port: var(--white);
104 | --color-port-placeholder: var(--grey-light);
105 | --color-submit: var(--white);
106 | --color-hw-type: var(--white);
107 | --color-hw-name: var(--white);
108 | --color-usage-value-span: var(--white);
109 | --color-usage-postfix: var(--white);
110 | --color-info-label: var(--white);
111 | --color-detailed-hw-info-div: var(--white);
112 | --color-announcement: var(--white);
113 | --color-uptime-dashboard-logo: var(--grey-light);
114 | --color-uptime-dashboard-logo-description: var(--white);
115 | --color-values-grid-div: var(--white);
116 | --color-labels-grid-div: var(--white);
117 | --color-chart-label: var(--white);
118 | --color-project-version: var(--white);
119 | --color-code: var(--white);
120 | --color-title: var(--white);
121 | --color-explanation-div: var(--grey);
122 | --color-advice: var(--grey-light);
123 |
124 | /* background */
125 | --background-body: var(--grey-light);
126 | --background-form: var(--linear-gradient-form-dark);
127 | --background-form-squares-grid-first: var(--grey-light);
128 | --background-form-squares-grid-second: var(--grey-light);
129 | --background-form-squares-grid-third: var(--grey-light);
130 | --background-main-settings: var(--grey);
131 | --background-main-settings-input: var(--grey);
132 | --background-main-settings-select: var(--grey);
133 | --background-main-settings-underline: var(--grey-light);
134 | --background-button-squares-grid-first: var(--purple-light);
135 | --background-button-squares-grid-second: var(--grey-light);
136 | --background-theme-buttons-first: var(--purple-light);
137 | --background-theme-buttons-second: var(--grey-light);
138 | --background-background-settings-color-selector: var(--grey-light);
139 | --background-port: var(--grey);
140 | --background-submit: var(--grey-light);
141 | --background-card: var(--grey-dark);
142 | --background-hw-logo-first: var(--blue-light);
143 | --background-hw-logo-second: var(--red-light);
144 | --background-hw-logo-third: var(--green-light);
145 | --background-usage-underline-first: var(--blue-light);
146 | --background-usage-underline-second: var(--red-light);
147 | --background-usage-underline-third: var(--green-light);
148 | --background-footer-first: var(--blue);
149 | --background-footer-second: var(--red);
150 | --background-footer-third: var(--green);
151 | --background-dividers-div: var(--grey-dark);
152 | --background-uptime: var(--grey-dark);
153 | --background-values-grid-div: var(--grey-opacity-70);
154 | --background-labels-grid-div: var(--grey-opacity-90);
155 | --background-chart-rectangle-grid-first: var(--blue-light);
156 | --background-chart-rectangle-grid-second: var(--red-light);
157 | --background-chart-rectangle-grid-third: var(--green-light);
158 | --background-error-div: var(--grey-dark);
159 |
160 | /* border-color */
161 | --border-color-chart-triangle-grid-first: var(--blue);
162 | --border-color-chart-triangle-grid-second: var(--red);
163 | --border-color-chart-triangle-grid-third: var(--green);
164 | }
--------------------------------------------------------------------------------
/src/main/resources/static/fonts/roboto/bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/fonts/roboto/bold.woff2
--------------------------------------------------------------------------------
/src/main/resources/static/fonts/roboto/regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/fonts/roboto/regular.woff2
--------------------------------------------------------------------------------
/src/main/resources/static/img/error/404.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/error/404.gif
--------------------------------------------------------------------------------
/src/main/resources/static/img/error/500.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/error/500.gif
--------------------------------------------------------------------------------
/src/main/resources/static/img/ico/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/ico/favicon.ico
--------------------------------------------------------------------------------
/src/main/resources/static/img/icons/disk.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/icons/disk.png
--------------------------------------------------------------------------------
/src/main/resources/static/img/icons/memory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/icons/memory.png
--------------------------------------------------------------------------------
/src/main/resources/static/img/icons/processor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/icons/processor.png
--------------------------------------------------------------------------------
/src/main/resources/static/img/logo/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/logo/background.png
--------------------------------------------------------------------------------
/src/main/resources/static/img/logo/clouds/left.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/logo/clouds/left.png
--------------------------------------------------------------------------------
/src/main/resources/static/img/logo/clouds/right.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Akttoer/Ward_CN/90b8902e1e244497399341890d7065a6d2b11e03/src/main/resources/static/img/logo/clouds/right.png
--------------------------------------------------------------------------------
/src/main/resources/static/js/assets/dhtmlx.min.js:
--------------------------------------------------------------------------------
1 | window.dhtmlx||(window.dhtmlx={}),function(){var e=null;function t(t,n){var i=t.callback;o(!1),t.box.parentNode.removeChild(t.box),e=t.box=null,i&&i(n)}function n(n){if(e){var o=(n=n||event).which||event.keyCode;return dhtmlx.message.keyboard&&(13!=o&&32!=o||t(e,!0),27==o&&t(e,!1)),n.preventDefault&&n.preventDefault(),!(n.cancelBubble=!0)}}function o(e){o.cover||(o.cover=document.createElement("DIV"),o.cover.onkeydown=n,o.cover.className="dhx_modal_cover",document.body.appendChild(o.cover));document.body.scrollHeight;o.cover.style.display=e?"inline-block":"none"}function i(e,t){return""}function d(d,r,l){var a=d.tagName?d:function(n,o,d){var r=document.createElement("DIV");r.className=" dhtmlx_modal_box dhtmlx-"+n.type,r.setAttribute("dhxbox",1);var l="";if(n.width&&(r.style.width=n.width),n.height&&(r.style.height=n.height),n.title&&(l+='"),l+='