mirror of
https://github.com/moshowgame/SpringBootCodeGenerator.git
synced 2026-05-08 14:26:18 +08:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
303d1eeae7 | ||
|
|
8794d1e51d | ||
|
|
5397cd1221 | ||
|
|
6d1f29b17c | ||
|
|
48054f3a6b | ||
|
|
8515dd3110 | ||
|
|
64fbaade24 | ||
|
|
412aa510d0 | ||
|
|
536ab42ec1 | ||
|
|
3af7114c7f |
64
README.md
64
README.md
@@ -1,6 +1,6 @@
|
||||
# SpringBootCodeGenerator
|
||||
----
|
||||
又名`JAVA在线代码生成平台`、`sql转java`、`大狼狗代码生成器`、`mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`<br>
|
||||
又名`Java代码生成器`、`JAVA在线代码生成平台`、`sql转java`、`大狼狗代码生成器`、`mybatis在线生成器`、`SQL转Java JPA、MYBATIS实现类代码生成平台`<br>
|
||||

|
||||

|
||||

|
||||
@@ -16,17 +16,37 @@
|
||||
>For reducing the repetitive CRUD work<br>
|
||||
> #以解放双手为目的,减少大量的`重复CRUD工作`
|
||||
>
|
||||
>mainly support mysql, support oracle and pgsql as well<br>
|
||||
>Support mysql, oracle and pgsql<br>
|
||||
> #支持`MySQL`、Oracle、PgSQL三大主流数据库
|
||||
>
|
||||
>generate to many popular templates by ddl-sql/insert-sql/simple json<br>
|
||||
> 可通过`建表SQL语句`或`INSERT语句`或者`简单JSON`生成`JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper`相关模板代码.
|
||||
>Generate to many predefined popular templates by DDL-SQL/Insert-SQL/Simple JSON<br>
|
||||
> 可通过`建表SQL语句`或`INSERT语句`或者`简单JSON`生成预设的`JPA/JdbcTemplate/Mybatis/MybatisPlus/BeetlSQL/CommonMapper`相关模板代码.
|
||||
>
|
||||
>thanks for your using and feedback,I'm inspired by the 600PV every day and github more than 900 stars <br>
|
||||
> 感谢大家的使用和反馈,每天六百的PV和获得超过九百多的星星是我前进和继续做下去的动力。
|
||||
>Thanks for your using and feedback,I'm inspired by the 1500+PV (AVG) every day and github more than 1.9K stars <br>
|
||||
> 感谢大家的使用和反馈,每天1500的PV和获得超过九百多的星星是我前进和继续做下去的动力。
|
||||
>
|
||||
>hope everyone can keep good balance on work and life , stay health and safety , be smooth on work as well<br>
|
||||
> 愿大家可以维持生活和工作平衡,保持健康和安全,祝大家工作顺利!
|
||||
>Hope everyone can keep good balance on work and life , stay health and safety . I wish you success in your new position and get promoted step by step. <br>
|
||||
> 愿大家可以维持生活和工作平衡,保持健康和安全,祝大家工作顺利,步步高升!
|
||||
>Please submit your issue and template , or pull your good idea into the PR <br>
|
||||
> 提交你的问题和生成模板,或者提交你的好主意到PR。
|
||||
|
||||
|
||||
# URL
|
||||
|
||||
- 感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是besjon专供的`金牌工具`(线上版本不一定是最新的,会有延迟,请谅解,谢谢).<br>
|
||||
- 感谢`jully.top`部署的副本 [https://jully.top/generator/](https://jully.top/generator/)。<br>
|
||||
- 感谢`三叔`将他部署在[DEVTOOLS](https://java.devtools.cn/) (Demised)上,继续作为Golden Tool开放给大家使用。<br>
|
||||
- 感谢`七牛`提供的云js/css免费加速服务,它尽可能全面收录优秀的开源库,并免费为之提供 CDN 加速服务,使之有更好的访问速度和稳定的环境。
|
||||
- Thanks for `JetBrains` providing us the `Licenses for Open Source Development` ,[Get free access to all JetBrains tools for developing your open source project!](https://www.jetbrains.com/community/opensource/#support) .<br>
|
||||
|
||||
| 访问地址 | http://localhost:1234/generator |
|
||||
|:-----------------------|:--------------------------------------------------------------|
|
||||
| BEJSON 在线地址 | https://java.bejson.com/generator/ |
|
||||
| Jully 在线地址 | https://jully.top/generator/ |
|
||||
| DEVTOOLS 在线地址(Demised) | https://java.devtools.cn |
|
||||
| CSDN BLOG | https://zhengkai.blog.csdn.net |
|
||||
| GITEE仓库 | https://gitee.com/moshowgame/SpringBootCodeGenerator/releases |
|
||||
| GITHUB仓库 | https://github.com/moshowgame/SpringBootCodeGenerator |
|
||||
|
||||
# Tips or Features
|
||||
- 支持`DDL SQL`/`INSERT SQL`/`SIMPLE JSON`三种生成模式
|
||||
@@ -41,27 +61,22 @@
|
||||
- OEM信息可以在`applicaltion.yml`中的`OEM`中更改
|
||||
- *支持公共js/css的Local/CDN模式切换,方便`本地`或者`工具站`进行部署,可以在`application.yml`的`OEM.Mode=`进行设置,之后请在`header-CDN.html`/`header-local.html`中检查对应js/css配置是否正确。
|
||||
|
||||
# Url
|
||||
|
||||
感谢`卡卡`将他部署在[BEJSON](https://java.bejson.com/generator)上,目前是besjon专供的金牌工具(线上版本不一定是最新的,会有延迟,请谅解,谢谢).<br>
|
||||
感谢`jully.top`部署的副本 [https://jully.top/generator/](https://jully.top/generator/)。<br>
|
||||
感谢`三叔`将他部署在[DEVTOOLS](https://java.devtools.cn/) (Demised)上,继续作为Golden Tool开放给大家使用。<br>
|
||||
感谢`七牛`提供的云js/css免费加速服务,它尽可能全面收录优秀的开源库,并免费为之提供 CDN 加速服务,使之有更好的访问速度和稳定的环境。
|
||||
Thanks for `JetBrains` providing us the `Licenses for Open Source Development` ,[Get free access to all JetBrains tools for developing your open source project!](https://www.jetbrains.com/community/opensource/#support) .<br>
|
||||
|
||||
| 访问地址 | http://localhost:1234/generator |
|
||||
|:-----------------------|:--------------------------------------------------------------|
|
||||
| BEJSON 在线地址 | https://java.bejson.com/generator |
|
||||
| Jully 在线地址 | https://jully.top/generator/ |
|
||||
| DEVTOOLS 在线地址(Demised) | https://java.devtools.cn |
|
||||
| CSDN BLOG | https://zhengkai.blog.csdn.net |
|
||||
| GITEE仓库 | https://gitee.com/moshowgame/SpringBootCodeGenerator/releases |
|
||||
| GITHUB仓库 | https://github.com/moshowgame/SpringBootCodeGenerator |
|
||||
# Branch Detail 分支介绍
|
||||
- Master:主力分支,基于SpringBoot3+,需要JDK17+
|
||||
- JDK11:兼容分支,基于SpringBoot2+,支持JDK8/JDK11/JDK17等版本,请自行(切换jdk11分支)[https://github.com/moshowgame/SpringBootCodeGenerator/tree/jdk11]
|
||||
- NewUI:新UI界面改版尝鲜
|
||||
|
||||
# 更新预告
|
||||
1.计划引入DJANGO等其他语言的ORM模板,欢迎大家submit相关代码供参考
|
||||
2.计划升级一下UI界面
|
||||
|
||||
# Update Logs
|
||||
| 更新日期 | 更新内容 |
|
||||
|:-----------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 2024.04.21 | 推出JDK11分支,支持JDK8/JDK11/JDK17等版本,兼容性较好但维护速度较慢,为了更好兼容旧机器和旧环境
|
||||
| 2024.04.20 | 修复CDN版本cdn.staticfile.org域名备份失败问题,已同步更新到cdn.staticfile.net(本地版本则不受影响)
|
||||
| 2024.01.26 | 修复大写下滑线列名转驼峰问题(感谢@Nisus-Liu
|
||||
的PR) |
|
||||
| 2023.10.22 | 工具站CDN更新。 |
|
||||
| 2023.08.31 | (感谢@Nisus-Liu的PR)<br>fix 驼峰列名转命名风格错误问题<br>增强转下划线命名风格, 对原始风格不敏感. 支持各种命名风格的列名 to 下划线<br>增加 NonCaseString 大小写不敏感字符串包装类, 简化编码<br>几点代码小优化。 |
|
||||
| 2023.07.11 | 安全更新,正式支持SpringBoot3,javax升级到jakarta。 |
|
||||
@@ -161,6 +176,7 @@ Thanks for `JetBrains` providing us the `Licenses for Open Source Development`
|
||||
|
||||
<img src="./codegenerator1.png">
|
||||
<img src="./codegenerator2.png">
|
||||
<img src="./site_analysis-2024.png">
|
||||
<img src="./site_analysis.png">
|
||||
<img src="./donate.png">
|
||||
|
||||
|
||||
@@ -36,10 +36,11 @@
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>-->
|
||||
|
||||
<!--<dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>-->
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
|
||||
@@ -14,6 +14,9 @@ public class StringUtils {
|
||||
* @return
|
||||
*/
|
||||
public static String upperCaseFirst(String str) {
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
return str.substring(0, 1).toUpperCase() + str.substring(1);
|
||||
}
|
||||
|
||||
@@ -89,12 +92,41 @@ public class StringUtils {
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* any str ==> lowerCamel
|
||||
*/
|
||||
public static String toLowerCamel(String str) {
|
||||
if (str == null || str.trim().isEmpty()) {
|
||||
return str;
|
||||
}
|
||||
|
||||
public static boolean isNotNull(String str){
|
||||
return org.apache.commons.lang3.StringUtils.isNotEmpty(str);
|
||||
StringBuilder result = new StringBuilder();
|
||||
char pre = '\0';
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char ch = str.charAt(i);
|
||||
if (ch == '-' || ch == '—' || ch == '_') {
|
||||
ch = '_';
|
||||
pre = ch;
|
||||
continue;
|
||||
}
|
||||
char ch2 = ch;
|
||||
if (pre == '_') {
|
||||
ch2 = Character.toUpperCase(ch);
|
||||
pre = ch2;
|
||||
} else if (pre >= 'A' && pre <= 'Z') {
|
||||
pre = ch;
|
||||
ch2 = Character.toLowerCase(ch);
|
||||
} else {
|
||||
pre = ch;
|
||||
}
|
||||
result.append(ch2);
|
||||
}
|
||||
|
||||
return lowerCaseFirst(result.toString());
|
||||
}
|
||||
public static void main(String[] args) {
|
||||
|
||||
public static boolean isNotNull(String str) {
|
||||
return org.apache.commons.lang3.StringUtils.isNotEmpty(str);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ public class TableParseUtil {
|
||||
// 2019-2-22 zhengkai 要在条件中使用复杂的表达式
|
||||
// 2019-4-29 zhengkai 优化对普通和特殊storage关键字的判断(感谢@AhHeadFloating的反馈 )
|
||||
// 2020-10-20 zhengkai 优化对fulltext/index关键字的处理(感谢@WEGFan的反馈)
|
||||
// 2023-8-27 zhangfei 改用工具方法判断, 且修改变量名(非特殊标识), 方法抽取
|
||||
// 2023-8-27 L&J 改用工具方法判断, 且修改变量名(非特殊标识), 方法抽取
|
||||
boolean notSpecialFlag = isNotSpecialColumnLine(columnLine, i);
|
||||
|
||||
if (notSpecialFlag) {
|
||||
@@ -185,13 +185,11 @@ public class TableParseUtil {
|
||||
|
||||
// field Name
|
||||
// 2019-09-08 yj 添加是否下划线转换为驼峰的判断
|
||||
// 2023-8-27 zhangfei 支持原始列名任意命名风格, 不依赖用户是否输入下划线
|
||||
// 2023-8-27 L&J 支持原始列名任意命名风格, 不依赖用户是否输入下划线
|
||||
String fieldName = null;
|
||||
if (ParamInfo.NAME_CASE_TYPE.CAMEL_CASE.equals(nameCaseType)) {
|
||||
fieldName = StringUtils.lowerCaseFirst(StringUtils.underlineToCamelCase(columnName));
|
||||
if (fieldName.contains("_")) {
|
||||
fieldName = fieldName.replaceAll("_", "");
|
||||
}
|
||||
// 2024-1-27 L&J 适配任意(maybe)原始风格转小写驼峰
|
||||
fieldName = StringUtils.toLowerCamel(columnName);
|
||||
} else if (ParamInfo.NAME_CASE_TYPE.UNDER_SCORE_CASE.equals(nameCaseType)) {
|
||||
fieldName = StringUtils.toUnderline(columnName, false);
|
||||
} else if (ParamInfo.NAME_CASE_TYPE.UPPER_UNDER_SCORE_CASE.equals(nameCaseType)) {
|
||||
|
||||
@@ -47,7 +47,7 @@ spring:
|
||||
#mvc:
|
||||
# static-path-pattern: /statics/**
|
||||
OEM:
|
||||
version: 2023.10
|
||||
version: 2024.4
|
||||
header: SQL转Java JPA、MYBATIS实现类代码生成平台
|
||||
keywords: sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现
|
||||
title: JAVA在线代码生成
|
||||
|
||||
@@ -47,7 +47,7 @@ spring:
|
||||
#mvc:
|
||||
# static-path-pattern: /statics/**
|
||||
OEM:
|
||||
version: 2023.10
|
||||
version: 2024.4
|
||||
header: SQL转Java JPA、MYBATIS实现类代码生成平台
|
||||
keywords: sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现
|
||||
title: JAVA代码生成平台
|
||||
|
||||
@@ -47,7 +47,7 @@ spring:
|
||||
#mvc:
|
||||
# static-path-pattern: /statics/**
|
||||
OEM:
|
||||
version: 2023.10
|
||||
version: 2024.4
|
||||
header: SQL转Java JPA、MYBATIS实现类代码生成平台
|
||||
keywords: sql转实体类,sql转DAO,SQL转service,SQL转JPA实现,SQL转MYBATIS实现
|
||||
title: JAVA在线代码生成
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
spring:
|
||||
profiles:
|
||||
active: dev
|
||||
active: bejson
|
||||
@@ -3,31 +3,31 @@
|
||||
<!--#################-->
|
||||
|
||||
<!--jquery | vue | element-ui | axios-->
|
||||
<script src="//cdn.staticfile.org/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/vue/2.6.12/vue.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/element-ui/2.15.14/index.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.org/element-ui/2.15.0/theme-chalk/index.min.css">
|
||||
<script src="//cdn.staticfile.org/axios/0.1.0/axios.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/jquery/3.5.1/jquery.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/vue/2.6.12/vue.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/element-ui/2.15.14/index.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/element-ui/2.15.0/theme-chalk/index.min.css">
|
||||
<script src="//cdn.staticfile.net/axios/0.1.0/axios.min.js"></script>
|
||||
|
||||
<script src="${request.contextPath}/statics/js/common.js"></script>
|
||||
<link rel="stylesheet" href="${request.contextPath}/statics/css/main.css">
|
||||
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//cdn.staticfile.org/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/respond.js/1.4.2/respond.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/html5shiv/3.7.3/html5shiv.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/respond.js/1.4.2/respond.min.js"></script>
|
||||
<![endif]-->
|
||||
|
||||
|
||||
<!-- import codemirror -->
|
||||
<script src="//cdn.staticfile.org/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/codemirror/6.65.7/mode/sql/sql.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/codemirror/6.65.7/mode/xml/xml.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/codemirror/6.65.7/mode/clike/clike.min.js"></script>
|
||||
<script src="//cdn.staticfile.org/codemirror/6.65.7/mode/javascript/javascript.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.org/codemirror/6.65.7/codemirror.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.org/codemirror/6.65.7/theme/idea.min.css">
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/codemirror.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/sql/sql.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/xml/xml.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/clike/clike.min.js"></script>
|
||||
<script src="//cdn.staticfile.net/codemirror/6.65.7/mode/javascript/javascript.min.js"></script>
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/codemirror/6.65.7/codemirror.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/codemirror/6.65.7/theme/idea.min.css">
|
||||
|
||||
<!--bootsrap -->
|
||||
<link rel="stylesheet" href="${request.contextPath}/statics/css/all-skins.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.org/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.org/admin-lte/2.3.11/css/AdminLTE.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/twitter-bootstrap/3.3.7/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="//cdn.staticfile.net/admin-lte/2.3.11/css/AdminLTE.min.css">
|
||||
@@ -19,6 +19,8 @@ public class FooTest {
|
||||
System.out.println(StringUtils.toUnderline("UserName",true));
|
||||
System.out.println(StringUtils.toUnderline("user_NameGgg_x-UUU",true));
|
||||
System.out.println(StringUtils.toUnderline("username",true));
|
||||
|
||||
System.out.println(StringUtils.underlineToCamelCase("CREATE_TIME"));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.softdev.system.generator.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import static junit.framework.TestCase.assertTrue;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
public class StringUtilsTest {
|
||||
|
||||
@Test
|
||||
public void toLowerCamel() {
|
||||
System.out.println(StringUtils.toLowerCamel("hello_world"));
|
||||
System.out.println(StringUtils.toLowerCamel("HELLO_WO-RLD-IK"));
|
||||
System.out.println(StringUtils.toLowerCamel("HELLO_WORLD-IKabc"));
|
||||
System.out.println(StringUtils.toLowerCamel("HELLO-WORLD-IKabc"));
|
||||
System.out.println(StringUtils.toLowerCamel("HELLO-123WORLD-IKabc"));
|
||||
System.out.println(StringUtils.toLowerCamel("helloWorldOKla"));
|
||||
assertEquals("helloWorldChina", StringUtils.toLowerCamel("hello_-_world-cHina"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upperCaseFirstShouldReturnStringWithFirstLetterCapitalized() {
|
||||
assertEquals("Hello", StringUtils.upperCaseFirst("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upperCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() {
|
||||
assertEquals("", StringUtils.upperCaseFirst(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lowerCaseFirstShouldReturnStringWithFirstLetterLowercased() {
|
||||
assertEquals("hello", StringUtils.lowerCaseFirst("Hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void lowerCaseFirstShouldReturnEmptyStringWhenInputIsEmpty() {
|
||||
assertEquals("", StringUtils.lowerCaseFirst(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void underlineToCamelCaseShouldReturnCamelCaseString() {
|
||||
assertEquals("helloWorld", StringUtils.underlineToCamelCase("hello_world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void underlineToCamelCaseShouldReturnEmptyStringWhenInputIsEmpty() {
|
||||
assertEquals("", StringUtils.underlineToCamelCase(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toUnderlineShouldReturnUnderlinedString() {
|
||||
assertEquals("hello_world", StringUtils.toUnderline("helloWorld", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toUnderlineShouldReturnEmptyStringWhenInputIsEmpty() {
|
||||
assertEquals("", StringUtils.toUnderline("", false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toCamelShouldReturnCamelCaseString() {
|
||||
assertEquals("helloWorld", StringUtils.toLowerCamel("hello_world"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toCamelShouldReturnEmptyStringWhenInputIsEmpty() {
|
||||
assertEquals("", StringUtils.toLowerCamel(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isNotNullShouldReturnTrueWhenStringIsNotEmpty() {
|
||||
assertTrue(StringUtils.isNotNull("hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isNotNullShouldReturnFalseWhenStringIsEmpty() {
|
||||
assertFalse(StringUtils.isNotNull(""));
|
||||
}
|
||||
}
|
||||
2
pom.xml
2
pom.xml
@@ -131,7 +131,7 @@
|
||||
<repository>
|
||||
<id>alimaven</id>
|
||||
<name>aliyun maven</name>
|
||||
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
<url>https://maven.aliyun.com/nexus/content/groups/public/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
|
||||
BIN
site_analysis-2024.png
Normal file
BIN
site_analysis-2024.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 239 KiB |
Reference in New Issue
Block a user