mirror of
https://github.com/yhl452493373/frpc-panel.git
synced 2026-04-04 14:27:01 +08:00
Compare commits
2 Commits
18792a395c
...
1bb3028308
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bb3028308 | |||
| cd81e22d53 |
23
README.md
23
README.md
@@ -6,6 +6,8 @@ frpc-panel 是 https://github.com/fatedier/frp 的一个客户端工具,用于
|
||||
|
||||
frps-panel 会以一个单独的进程运行,通过后台调用frpc的接口实现对frpc的操作。
|
||||
|
||||
## 从版本2.0.0开始,本插件只支持版本号大于等于v0.52.0的frp
|
||||
|
||||
## 功能
|
||||
|
||||
+ 展示客户端基础配置信息
|
||||
@@ -17,14 +19,21 @@ frps-panel 会以一个单独的进程运行,通过后台调用frpc的接口
|
||||
|
||||
## 使用方法
|
||||
|
||||
1、frpc的配置文件`frpc.ini`中,增加如下内容:
|
||||
1、frpc的配置文件`frpc.toml`中,增加如下内容:
|
||||
|
||||
```ini
|
||||
[common]
|
||||
admin_addr = 127.0.0.1
|
||||
admin_port = 7400
|
||||
admin_user = admin
|
||||
admin_pwd = admin
|
||||
```toml
|
||||
webServer.addr = "127.0.0.1"
|
||||
webServer.port = 7400
|
||||
webServer.user = "admin"
|
||||
webServer.password = "admin"
|
||||
```
|
||||
或
|
||||
```toml
|
||||
[webServer]
|
||||
addr = "127.0.0.1"
|
||||
port = 7400
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
```
|
||||
|
||||
2、frpc-panel的配置文件`frpc-panel.toml`的配置如下:
|
||||
|
||||
23
README_en.md
23
README_en.md
@@ -6,6 +6,8 @@ frpc-panel is a client tool of https://github.com/fatedier/frp , it's used to sh
|
||||
|
||||
frps-panel will run as one single process and manage frpc proxy info with frpc's api.
|
||||
|
||||
## Since version 2.0.0,this plugin only support frp version >= v0.52.0
|
||||
|
||||
## Features
|
||||
|
||||
+ Show frpc basic info
|
||||
@@ -17,14 +19,21 @@ frps-panel will run as one single process and manage frpc proxy info with frpc's
|
||||
|
||||
## Usage
|
||||
|
||||
1.add config in frpc's config file '`frpc.ini`:
|
||||
1.add config in frpc's config file '`frpc.toml`:
|
||||
|
||||
```ini
|
||||
[common]
|
||||
admin_addr = 127.0.0.1
|
||||
admin_port = 7400
|
||||
admin_user = admin
|
||||
admin_pwd = admin
|
||||
```toml
|
||||
webServer.addr = "127.0.0.1"
|
||||
webServer.port = 7400
|
||||
webServer.user = "admin"
|
||||
webServer.password = "admin"
|
||||
```
|
||||
or
|
||||
```toml
|
||||
[webServer]
|
||||
addr = "127.0.0.1"
|
||||
port = 7400
|
||||
user = "admin"
|
||||
password = "admin"
|
||||
```
|
||||
|
||||
2.`frpc-panel.toml`:
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
"Extra": "Extra Params",
|
||||
"Proxy Name": "Proxy Name",
|
||||
"Custom Domains": "Custom Domains",
|
||||
"Custom Domains Example": "[\"first.domain.org\",\"second.domain.net\"]",
|
||||
"Subdomain": "Subdomain",
|
||||
"Remote Port": "Remote Port",
|
||||
"Use Encryption": "Use Encryption",
|
||||
@@ -53,8 +54,12 @@
|
||||
"running": "running",
|
||||
"start error": "start error",
|
||||
"new": "new",
|
||||
"Proxy Name Example": "Intranet Penetration",
|
||||
"Local IP": "Local IP",
|
||||
"Local IP Example": "127.0.0.1",
|
||||
"Local Port": "Local Port",
|
||||
"Local Port Example": "8080",
|
||||
"Remote Port Example": "18080",
|
||||
"Operation": "Operation",
|
||||
"Confirm": "Confirm",
|
||||
"Cancel": "Cancel",
|
||||
@@ -68,5 +73,15 @@
|
||||
"Frp Client Error": "Frp client error",
|
||||
"Proxy Exist,": "Proxy name exist",
|
||||
"Proxy Not Exist": "Proxy name not exist",
|
||||
"Client Tips": "Client tips"
|
||||
"Client Tips": "Client tips",
|
||||
"and": " and ",
|
||||
"Require Not All Empty": " can't be empty at the same time",
|
||||
"Require Not Empty": " can't be empty",
|
||||
"Require Number": " should be a number",
|
||||
"Require Boolean": " should be a boolean",
|
||||
"Require Array": " should be an js array",
|
||||
"Total": "Total ",
|
||||
"Items": " items",
|
||||
"Go to": "Go to",
|
||||
"Per Page": " / page"
|
||||
}
|
||||
@@ -37,6 +37,7 @@
|
||||
"Extra": "附加参数",
|
||||
"Proxy Name": "代理名称",
|
||||
"Custom Domains": "自定义域名",
|
||||
"Custom Domains Example": "[\"first.domain.org\",\"second.domain.net\"]",
|
||||
"Subdomain": "子域名",
|
||||
"Remote Port": "服务端端口",
|
||||
"Use Encryption": "加密传输",
|
||||
@@ -53,8 +54,12 @@
|
||||
"running": "运行中",
|
||||
"start error": "错误",
|
||||
"new": "新连接",
|
||||
"Proxy Name Example": "内网穿透",
|
||||
"Local IP": "本地IP",
|
||||
"Local IP Example": "127.0.0.1",
|
||||
"Local Port": "本地端口",
|
||||
"Local Port Example": "8080",
|
||||
"Remote Port Example": "18080",
|
||||
"Operation": "操作",
|
||||
"Confirm": "确定",
|
||||
"Cancel": "取消",
|
||||
@@ -68,5 +73,15 @@
|
||||
"Frp Client Error": "Frp客户端错误",
|
||||
"Proxy Exist": "代理名称重复",
|
||||
"Proxy Not Exist": "代理名称不存在",
|
||||
"Client Tips": "客户端提示"
|
||||
"Client Tips": "客户端提示",
|
||||
"and": "和",
|
||||
"Require Not All Empty": "不能同时为空",
|
||||
"Require Not Empty": "不能为空",
|
||||
"Require Number": "应当为数字",
|
||||
"Require Boolean": "应当为布尔值",
|
||||
"Require Array": "应当为JS数组",
|
||||
"Total": "共",
|
||||
"Items": "条记录",
|
||||
"Go to": "到第",
|
||||
"Per Page": "条/页"
|
||||
}
|
||||
@@ -1,13 +1,9 @@
|
||||
var loadClientInfo = (function ($) {
|
||||
var i18n = {};
|
||||
|
||||
/**
|
||||
* get client info
|
||||
* @param lang {Map<string,string>} language json
|
||||
* @param title {string} page title
|
||||
*/
|
||||
function loadClientInfo(lang, title) {
|
||||
i18n = lang;
|
||||
function loadClientInfo( title) {
|
||||
$("#title").text(title);
|
||||
$('#content').empty();
|
||||
var loading = layui.layer.load();
|
||||
@@ -16,20 +12,6 @@ var loadClientInfo = (function ($) {
|
||||
type: 'none'
|
||||
}).done(function (result) {
|
||||
if (result.success) {
|
||||
var proxies = [];
|
||||
result.data.proxies.forEach(function (proxy) {
|
||||
var items = flatJSON(proxy.ProxyConfigurer);
|
||||
proxies.push(expandJSON(items))
|
||||
})
|
||||
var visitors = [];
|
||||
result.data.visitors.forEach(function (visitor) {
|
||||
var items = flatJSON(visitor.VisitorConfigurer);
|
||||
visitors.push(expandJSON(items))
|
||||
})
|
||||
|
||||
window.clientConfig = $.extend(true, {}, result.data);
|
||||
window.clientConfig.proxies = proxies;
|
||||
window.clientConfig.visitors = visitors;
|
||||
renderClientInfo(result.data);
|
||||
} else {
|
||||
layui.layer.msg(result.message);
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
var loadProxyInfo = (function ($) {
|
||||
var i18n = {}, currentProxyType, currentTitle;
|
||||
var currentProxyType, currentTitle;
|
||||
|
||||
/**
|
||||
* get proxy info
|
||||
* @param lang {{}} language json
|
||||
* @param title page title
|
||||
* @param proxyType proxy type
|
||||
*/
|
||||
function loadProxyInfo(lang, title, proxyType) {
|
||||
if (lang != null)
|
||||
i18n = lang;
|
||||
function loadProxyInfo(title, proxyType) {
|
||||
if (title != null)
|
||||
currentTitle = title;
|
||||
if (proxyType != null)
|
||||
@@ -24,6 +21,7 @@ var loadProxyInfo = (function ($) {
|
||||
if (result.success) {
|
||||
$('#content').html($('#proxyListTableTemplate').html());
|
||||
renderProxyListTable(result.data);
|
||||
loadFrpcConfig();
|
||||
} else {
|
||||
layui.layer.msg(result.message);
|
||||
}
|
||||
@@ -32,6 +30,32 @@ var loadProxyInfo = (function ($) {
|
||||
});
|
||||
}
|
||||
|
||||
function loadFrpcConfig() {
|
||||
$.getJSON('/proxy/api/config', {
|
||||
type: 'none'
|
||||
}).done(function (result) {
|
||||
if (result.success) {
|
||||
var proxies = [];
|
||||
result.data.proxies.forEach(function (proxy) {
|
||||
var items = flatJSON(proxy['ProxyConfigurer']);
|
||||
proxies.push(expandJSON(items))
|
||||
})
|
||||
var visitors = [];
|
||||
result.data.visitors.forEach(function (visitor) {
|
||||
var items = flatJSON(visitor['VisitorConfigurer']);
|
||||
visitors.push(expandJSON(items))
|
||||
});
|
||||
|
||||
window.clientConfig = $.extend(true, {}, result.data);
|
||||
window.clientConfig.proxies = proxies;
|
||||
window.clientConfig.visitors = visitors;
|
||||
} else {
|
||||
window.clientConfig = {};
|
||||
layui.layer.msg(result.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* render proxy list table
|
||||
* @param data {[Map<string,string>]} proxy data
|
||||
@@ -92,7 +116,11 @@ var loadProxyInfo = (function ($) {
|
||||
text: {none: i18n['EmptyData']},
|
||||
cols: [cols],
|
||||
page: {
|
||||
layout: navigator.language.indexOf("zh") === -1 ? ['first', 'prev', 'next', 'last'] : ['prev', 'page', 'next', 'skip', 'count', 'limit']
|
||||
limitTemplet: function (item) {
|
||||
return item + i18n['PerPage'];
|
||||
},
|
||||
skipText: [i18n['Goto'], '', i18n['Confirm']],
|
||||
countText: [i18n['Total'], i18n['Items']]
|
||||
},
|
||||
toolbar: '#proxyListToolbarTemplate',
|
||||
defaultToolbar: false,
|
||||
@@ -168,8 +196,8 @@ var loadProxyInfo = (function ($) {
|
||||
var name = basicName.name;
|
||||
if (name.indexOf('.') !== -1) {
|
||||
var keys = name.split('.');
|
||||
expandJSONKeys(tempData, keys, basicName.defaultValue);
|
||||
expandJSONKeys(basicData, keys, null);
|
||||
expandJSONKeys(tempData, keys, null);
|
||||
expandJSONKeys(basicData, keys, basicName.defaultValue);
|
||||
}
|
||||
|
||||
eval('basicData.' + name + ' = ' + 'tempData.' + name);
|
||||
@@ -177,7 +205,6 @@ var loadProxyInfo = (function ($) {
|
||||
});
|
||||
|
||||
var flatted = flatJSON(tempData);
|
||||
|
||||
for (var key in flatted) {
|
||||
var value = flatted[key];
|
||||
if (value == null || value === '')
|
||||
@@ -189,7 +216,7 @@ var loadProxyInfo = (function ($) {
|
||||
}
|
||||
}
|
||||
|
||||
var html = document.getElementById('addProxyTemplate').innerHTML;
|
||||
var html = document.getElementById('proxyFormTemplate').innerHTML;
|
||||
var content = layui.laytpl(html).render({
|
||||
type: currentProxyType,
|
||||
extraData: extraData
|
||||
@@ -202,15 +229,14 @@ var loadProxyInfo = (function ($) {
|
||||
content: content,
|
||||
btn: [i18n['Confirm'], i18n['Cancel']],
|
||||
btn1: function (index) {
|
||||
if (layui.form.validate('#addProxyTemplate')) {
|
||||
var formData = layui.form.val('addProxyForm');
|
||||
var $items = $('#addProxyForm .extra-param-tab-item .extra-param-item');
|
||||
if (layui.form.validate('#proxyForm')) {
|
||||
var formData = layui.form.val('proxyForm');
|
||||
var $items = $('#proxyForm .extra-param-tab-item .extra-param-item');
|
||||
$items.each(function () {
|
||||
var name = $(this).find('input').first().val();
|
||||
var value = $(this).find('input').last().val();
|
||||
formData[name] = value;
|
||||
});
|
||||
|
||||
addOrUpdate(formData, index, update);
|
||||
}
|
||||
},
|
||||
@@ -221,14 +247,14 @@ var loadProxyInfo = (function ($) {
|
||||
//get and set old name for update form
|
||||
var originalNameKey = layero.find('#originalNameKey').attr('name');
|
||||
basicData[originalNameKey] = basicData.name;
|
||||
layui.form.val('addProxyForm', flatJSON(basicData));
|
||||
layui.form.val('proxyForm', flatJSON(basicData));
|
||||
proxyPopupSuccess();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function proxyPopupSuccess() {
|
||||
layui.form.render(null, 'addProxyForm');
|
||||
layui.form.render(null, 'proxyForm');
|
||||
layui.form.on('input-affix(addition)', function (obj) {
|
||||
var $paramValue = $(obj.elem);
|
||||
var $paramName = $paramValue.closest('.layui-form-item').find('input[type=text]');
|
||||
@@ -258,7 +284,7 @@ var loadProxyInfo = (function ($) {
|
||||
* @param update update flag. true - update, false - add
|
||||
*/
|
||||
function addOrUpdate(data, index, update) {
|
||||
var loading = layui.layer.load();
|
||||
try {
|
||||
var originalNameKey = $('#originalNameKey').attr('name');
|
||||
var proxies = clientConfig.proxies;
|
||||
if (update) {
|
||||
@@ -271,31 +297,12 @@ var loadProxyInfo = (function ($) {
|
||||
} else {
|
||||
proxies.push(expandJSON(data));
|
||||
}
|
||||
} catch (e) {
|
||||
layui.layer.msg(e.message);
|
||||
return;
|
||||
}
|
||||
|
||||
var tomlStr = TOML.stringify(clientConfig);
|
||||
|
||||
$.ajax({
|
||||
url: '/update',
|
||||
type: 'post',
|
||||
contentType: 'text/plain',
|
||||
data: tomlStr,
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
layui.layer.close(index);
|
||||
reloadTable();
|
||||
layui.layer.msg(i18n['OperateSuccess']);
|
||||
} else {
|
||||
errorMsg(result);
|
||||
if (result.code === 5) {
|
||||
layui.layer.close(index);
|
||||
reloadTable();
|
||||
}
|
||||
}
|
||||
},
|
||||
complete: function () {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
updateFrpcConfig(index);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -307,25 +314,36 @@ var loadProxyInfo = (function ($) {
|
||||
layui.layer.msg(i18n['ShouldCheckProxy']);
|
||||
return;
|
||||
}
|
||||
data.forEach(function (temp) {
|
||||
for (var key in temp) {
|
||||
if (typeof temp[key] === 'boolean') {
|
||||
temp[key] = temp[key] + '';
|
||||
}
|
||||
}
|
||||
});
|
||||
layui.layer.confirm(i18n['ConfirmRemoveProxy'], {
|
||||
title: i18n['OperationConfirm'],
|
||||
btn: [i18n['Confirm'], i18n['Cancel']]
|
||||
}, function (index) {
|
||||
layui.layer.close(index);
|
||||
var proxies = clientConfig.proxies;
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
proxies.forEach(function (proxy, j) {
|
||||
if (data[i].name === proxy.name) {
|
||||
proxies.splice(j, 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateFrpcConfig(index);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* update frpc's config
|
||||
* @param index popup index
|
||||
*/
|
||||
function updateFrpcConfig(index) {
|
||||
var loading = layui.layer.load();
|
||||
$.post({
|
||||
url: '/remove',
|
||||
var content = TOML.stringify(clientConfig);
|
||||
$.ajax({
|
||||
url: '/update',
|
||||
type: 'post',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify(data),
|
||||
contentType: 'text/plain',
|
||||
data: content,
|
||||
success: function (result) {
|
||||
if (result.success) {
|
||||
layui.layer.close(index);
|
||||
@@ -343,14 +361,13 @@ var loadProxyInfo = (function ($) {
|
||||
layui.layer.close(loading);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* reload proxy table
|
||||
*/
|
||||
function reloadTable() {
|
||||
loadProxyInfo(null, null, null);
|
||||
loadProxyInfo(null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
var loadOverview = (function ($) {
|
||||
var i18n = {};
|
||||
|
||||
/**
|
||||
* get proxy info
|
||||
* @param lang {{}} language json
|
||||
* @param title page title
|
||||
*/
|
||||
function loadOverview(lang, title) {
|
||||
i18n = lang;
|
||||
function loadOverview(title) {
|
||||
$("#title").text(title);
|
||||
$('#content').empty();
|
||||
var loading = layui.layer.load();
|
||||
@@ -63,7 +59,11 @@ var loadOverview = (function ($) {
|
||||
text: {none: i18n['EmptyData']},
|
||||
cols: [cols],
|
||||
page: {
|
||||
layout: navigator.language.indexOf("zh") === -1 ? ['first', 'prev', 'next', 'last'] : ['prev', 'page', 'next', 'skip', 'count', 'limit']
|
||||
limitTemplet: function (item) {
|
||||
return item + i18n['PerPage'];
|
||||
},
|
||||
skipText: [i18n['Goto'], '', i18n['Confirm']],
|
||||
countText: [i18n['Total'], i18n['Items']]
|
||||
},
|
||||
data: dataList,
|
||||
initSort: {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
window.clientConfig = {};
|
||||
window.i18n = {};
|
||||
(function ($) {
|
||||
$(function () {
|
||||
function init() {
|
||||
var langLoading = layui.layer.load()
|
||||
$.getJSON('/lang.json').done(function (lang) {
|
||||
window.i18n = lang;
|
||||
$.ajaxSetup({
|
||||
error: function (xhr,) {
|
||||
if (xhr.status === 401) {
|
||||
@@ -18,13 +20,13 @@ window.clientConfig = {};
|
||||
var id = elem.attr('id');
|
||||
var title = elem.text();
|
||||
if (id === 'clientInfo') {
|
||||
loadClientInfo(lang, title.trim());
|
||||
loadClientInfo(title.trim());
|
||||
} else if (id === 'overview') {
|
||||
loadOverview(lang, title.trim());
|
||||
loadOverview(title.trim());
|
||||
} else if (elem.closest('.layui-nav-item').attr('id') === 'proxies') {
|
||||
if (id != null && id.trim() !== '') {
|
||||
var suffix = elem.closest('.layui-nav-item').children('a').text().trim();
|
||||
loadProxyInfo(lang, title + " " + suffix, id);
|
||||
loadProxyInfo(title + " " + suffix, id);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -35,6 +37,45 @@ window.clientConfig = {};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* add verify rule to layui.form
|
||||
*/
|
||||
function initFormVerifyRule() {
|
||||
layui.form.verify({
|
||||
proxyName: function (value, elem) {
|
||||
if (value.trim() === '') {
|
||||
var nameI18n = $('#proxyName').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return nameI18n + i18n['RequireNotEmpty'];
|
||||
}
|
||||
},
|
||||
localPort: function (value, elem) {
|
||||
if (value !== '' && !/^\d+$/.test(value)) {
|
||||
var nameI18n = $('#localPort').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return nameI18n + i18n['RequireNumber'];
|
||||
}
|
||||
},
|
||||
domain: function (value, elem) {
|
||||
var proxyType = $('#proxyType').val().toLowerCase();
|
||||
var $customDomains = $('#customDomains');
|
||||
var customDomains = $customDomains.val();
|
||||
var $subdomain = $('#subdomain');
|
||||
var subdomain = $subdomain.val();
|
||||
if (proxyType === 'http' || proxyType === 'https') {
|
||||
if (customDomains.trim() === '' && subdomain.trim() === '') {
|
||||
var customDomainsNameI18n = $customDomains.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
var subdomainNameI18n = $subdomain.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
return customDomainsNameI18n + i18n['and'] + subdomainNameI18n + i18n['RequireNotAllEmpty'];
|
||||
} else if (customDomains.trim() !== '') {
|
||||
var nameI18n = $customDomains.closest('.layui-form-item').children('.layui-form-label').text();
|
||||
if (!/^\s*\[.*]\s*$/.test(customDomains)) {
|
||||
return nameI18n + i18n['RequireArray'];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function logout() {
|
||||
$.get("/logout", function (result) {
|
||||
window.location.reload();
|
||||
@@ -46,5 +87,6 @@ window.clientConfig = {};
|
||||
});
|
||||
|
||||
init();
|
||||
initFormVerifyRule();
|
||||
});
|
||||
})(layui.$);
|
||||
@@ -1,4 +1,4 @@
|
||||
(function () {
|
||||
(function ($) {
|
||||
//param names in Basic tab
|
||||
var basicParams = [
|
||||
{
|
||||
@@ -24,10 +24,10 @@
|
||||
defaultValue: '-'
|
||||
}, {
|
||||
name: 'transport.useEncryption',
|
||||
defaultValue: 'false',
|
||||
defaultValue: false,
|
||||
}, {
|
||||
name: 'transport.useCompression',
|
||||
defaultValue: 'false',
|
||||
defaultValue: false,
|
||||
}
|
||||
];
|
||||
var mapParams = [{
|
||||
@@ -40,6 +40,7 @@
|
||||
'healthCheck.maxFailed',
|
||||
'healthCheck.intervalSeconds',
|
||||
'localPort',
|
||||
'remotePort'
|
||||
],
|
||||
boolean: [
|
||||
'transport.useEncryption',
|
||||
@@ -103,17 +104,41 @@
|
||||
|
||||
function expandJSON(obj) {
|
||||
var newObj = {};
|
||||
var inPopup = $('#proxyForm').length !== 0;
|
||||
for (var name in obj) {
|
||||
var value = obj[name];
|
||||
if (value === '') {
|
||||
continue;
|
||||
}
|
||||
var nameI18n = name;
|
||||
if (inPopup) {
|
||||
nameI18n = $('#proxyForm [name="' + name + '"]').closest('.layui-form-item').children('.layui-form-label').text();
|
||||
if (nameI18n === '') {
|
||||
nameI18n = name;
|
||||
}
|
||||
}
|
||||
|
||||
if (paramTypes.number.indexOf(name) !== -1) {
|
||||
value = parseInt(value) || 0;
|
||||
value = parseInt(value);
|
||||
if (isNaN(value)) {
|
||||
throw new Error(nameI18n + i18n['RequireNumber']);
|
||||
}
|
||||
} else if (paramTypes.boolean.indexOf(name) !== -1) {
|
||||
value = Boolean(value) || false;
|
||||
if (typeof value === "string" && (value === 'true' || value === 'false')) {
|
||||
value = value === 'true';
|
||||
} else if (typeof value !== 'boolean') {
|
||||
throw new Error(nameI18n + i18n['RequireBoolean']);
|
||||
}
|
||||
} else if (paramTypes.array.indexOf(name) !== -1) {
|
||||
try {
|
||||
if (/^\s*\[.*]\s*$/.test(value)) {
|
||||
value = eval('(' + value + ')') || [];
|
||||
} else {
|
||||
throw new Error('value format incorrect');
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error(nameI18n + i18n['RequireArray']);
|
||||
}
|
||||
} else {
|
||||
for (var i = 0; i < paramTypes.map.length; i++) {
|
||||
var key = paramTypes.map[i];
|
||||
@@ -126,6 +151,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expandJSONKeys(newObj, name.split("."), value, false);
|
||||
}
|
||||
return newObj;
|
||||
@@ -181,4 +207,4 @@
|
||||
window.expandJSONKeys = expandJSONKeys;
|
||||
window.expandJSON = expandJSON;
|
||||
window.flatJSON = flatJSON;
|
||||
})();
|
||||
})(layui.$);
|
||||
344
assets/static/lib/codemirror/lib/codemirror.css
vendored
344
assets/static/lib/codemirror/lib/codemirror.css
vendored
@@ -1,344 +0,0 @@
|
||||
/* BASICS */
|
||||
|
||||
.CodeMirror {
|
||||
/* Set height, width, borders, and global font properties here */
|
||||
font-family: monospace;
|
||||
height: 300px;
|
||||
color: black;
|
||||
direction: ltr;
|
||||
}
|
||||
|
||||
/* PADDING */
|
||||
|
||||
.CodeMirror-lines {
|
||||
padding: 4px 0; /* Vertical padding around content */
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
padding: 0 4px; /* Horizontal padding of content */
|
||||
}
|
||||
|
||||
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
background-color: white; /* The little square between H and V scrollbars */
|
||||
}
|
||||
|
||||
/* GUTTER */
|
||||
|
||||
.CodeMirror-gutters {
|
||||
border-right: 1px solid #ddd;
|
||||
background-color: #f7f7f7;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.CodeMirror-linenumbers {}
|
||||
.CodeMirror-linenumber {
|
||||
padding: 0 3px 0 5px;
|
||||
min-width: 20px;
|
||||
text-align: right;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.CodeMirror-guttermarker { color: black; }
|
||||
.CodeMirror-guttermarker-subtle { color: #999; }
|
||||
|
||||
/* CURSOR */
|
||||
|
||||
.CodeMirror-cursor {
|
||||
border-left: 1px solid black;
|
||||
border-right: none;
|
||||
width: 0;
|
||||
}
|
||||
/* Shown when moving in bi-directional text */
|
||||
.CodeMirror div.CodeMirror-secondarycursor {
|
||||
border-left: 1px solid silver;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-cursor {
|
||||
width: auto;
|
||||
border: 0 !important;
|
||||
background: #7e7;
|
||||
}
|
||||
.cm-fat-cursor div.CodeMirror-cursors {
|
||||
z-index: 1;
|
||||
}
|
||||
.cm-fat-cursor .CodeMirror-line::selection,
|
||||
.cm-fat-cursor .CodeMirror-line > span::selection,
|
||||
.cm-fat-cursor .CodeMirror-line > span > span::selection { background: transparent; }
|
||||
.cm-fat-cursor .CodeMirror-line::-moz-selection,
|
||||
.cm-fat-cursor .CodeMirror-line > span::-moz-selection,
|
||||
.cm-fat-cursor .CodeMirror-line > span > span::-moz-selection { background: transparent; }
|
||||
.cm-fat-cursor { caret-color: transparent; }
|
||||
@-moz-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@-webkit-keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
@keyframes blink {
|
||||
0% {}
|
||||
50% { background-color: transparent; }
|
||||
100% {}
|
||||
}
|
||||
|
||||
/* Can style cursor different in overwrite (non-insert) mode */
|
||||
.CodeMirror-overwrite .CodeMirror-cursor {}
|
||||
|
||||
.cm-tab { display: inline-block; text-decoration: inherit; }
|
||||
|
||||
.CodeMirror-rulers {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: -50px; bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.CodeMirror-ruler {
|
||||
border-left: 1px solid #ccc;
|
||||
top: 0; bottom: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
/* DEFAULT THEME */
|
||||
|
||||
.cm-s-default .cm-header {color: blue;}
|
||||
.cm-s-default .cm-quote {color: #090;}
|
||||
.cm-negative {color: #d44;}
|
||||
.cm-positive {color: #292;}
|
||||
.cm-header, .cm-strong {font-weight: bold;}
|
||||
.cm-em {font-style: italic;}
|
||||
.cm-link {text-decoration: underline;}
|
||||
.cm-strikethrough {text-decoration: line-through;}
|
||||
|
||||
.cm-s-default .cm-keyword {color: #708;}
|
||||
.cm-s-default .cm-atom {color: #219;}
|
||||
.cm-s-default .cm-number {color: #164;}
|
||||
.cm-s-default .cm-def {color: #00f;}
|
||||
.cm-s-default .cm-variable,
|
||||
.cm-s-default .cm-punctuation,
|
||||
.cm-s-default .cm-property,
|
||||
.cm-s-default .cm-operator {}
|
||||
.cm-s-default .cm-variable-2 {color: #05a;}
|
||||
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
|
||||
.cm-s-default .cm-comment {color: #a50;}
|
||||
.cm-s-default .cm-string {color: #a11;}
|
||||
.cm-s-default .cm-string-2 {color: #f50;}
|
||||
.cm-s-default .cm-meta {color: #555;}
|
||||
.cm-s-default .cm-qualifier {color: #555;}
|
||||
.cm-s-default .cm-builtin {color: #30a;}
|
||||
.cm-s-default .cm-bracket {color: #997;}
|
||||
.cm-s-default .cm-tag {color: #170;}
|
||||
.cm-s-default .cm-attribute {color: #00c;}
|
||||
.cm-s-default .cm-hr {color: #999;}
|
||||
.cm-s-default .cm-link {color: #00c;}
|
||||
|
||||
.cm-s-default .cm-error {color: #f00;}
|
||||
.cm-invalidchar {color: #f00;}
|
||||
|
||||
.CodeMirror-composing { border-bottom: 2px solid; }
|
||||
|
||||
/* Default styles for common addons */
|
||||
|
||||
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
|
||||
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
|
||||
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
|
||||
.CodeMirror-activeline-background {background: #e8f2ff;}
|
||||
|
||||
/* STOP */
|
||||
|
||||
/* The rest of this file contains styles related to the mechanics of
|
||||
the editor. You probably shouldn't touch them. */
|
||||
|
||||
.CodeMirror {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.CodeMirror-scroll {
|
||||
overflow: scroll !important; /* Things will break if this is overridden */
|
||||
/* 50px is the magic margin used to hide the element's real scrollbars */
|
||||
/* See overflow: hidden in .CodeMirror */
|
||||
margin-bottom: -50px; margin-right: -50px;
|
||||
padding-bottom: 50px;
|
||||
height: 100%;
|
||||
outline: none; /* Prevent dragging from highlighting the element */
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
}
|
||||
.CodeMirror-sizer {
|
||||
position: relative;
|
||||
border-right: 50px solid transparent;
|
||||
}
|
||||
|
||||
/* The fake, visible scrollbars. Used to force redraw during scrolling
|
||||
before actual scrolling happens, thus preventing shaking and
|
||||
flickering artifacts. */
|
||||
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
|
||||
position: absolute;
|
||||
z-index: 6;
|
||||
display: none;
|
||||
outline: none;
|
||||
}
|
||||
.CodeMirror-vscrollbar {
|
||||
right: 0; top: 0;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.CodeMirror-hscrollbar {
|
||||
bottom: 0; left: 0;
|
||||
overflow-y: hidden;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
.CodeMirror-scrollbar-filler {
|
||||
right: 0; bottom: 0;
|
||||
}
|
||||
.CodeMirror-gutter-filler {
|
||||
left: 0; bottom: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-gutters {
|
||||
position: absolute; left: 0; top: 0;
|
||||
min-height: 100%;
|
||||
z-index: 3;
|
||||
}
|
||||
.CodeMirror-gutter {
|
||||
white-space: normal;
|
||||
height: 100%;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-bottom: -50px;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper {
|
||||
position: absolute;
|
||||
z-index: 4;
|
||||
background: none !important;
|
||||
border: none !important;
|
||||
}
|
||||
.CodeMirror-gutter-background {
|
||||
position: absolute;
|
||||
top: 0; bottom: 0;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-elt {
|
||||
position: absolute;
|
||||
cursor: default;
|
||||
z-index: 4;
|
||||
}
|
||||
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
|
||||
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
|
||||
|
||||
.CodeMirror-lines {
|
||||
cursor: text;
|
||||
min-height: 1px; /* prevents collapsing before first draw */
|
||||
}
|
||||
.CodeMirror pre.CodeMirror-line,
|
||||
.CodeMirror pre.CodeMirror-line-like {
|
||||
/* Reset some styles that the rest of the page might have set */
|
||||
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
|
||||
border-width: 0;
|
||||
background: transparent;
|
||||
font-family: inherit;
|
||||
font-size: inherit;
|
||||
margin: 0;
|
||||
white-space: pre;
|
||||
word-wrap: normal;
|
||||
line-height: inherit;
|
||||
color: inherit;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
-webkit-font-variant-ligatures: contextual;
|
||||
font-variant-ligatures: contextual;
|
||||
}
|
||||
.CodeMirror-wrap pre.CodeMirror-line,
|
||||
.CodeMirror-wrap pre.CodeMirror-line-like {
|
||||
word-wrap: break-word;
|
||||
white-space: pre-wrap;
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
.CodeMirror-linebackground {
|
||||
position: absolute;
|
||||
left: 0; right: 0; top: 0; bottom: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.CodeMirror-linewidget {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 0.1px; /* Force widget margins to stay inside of the container */
|
||||
}
|
||||
|
||||
.CodeMirror-widget {}
|
||||
|
||||
.CodeMirror-rtl pre { direction: rtl; }
|
||||
|
||||
.CodeMirror-code {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Force content-box sizing for the elements where we expect it */
|
||||
.CodeMirror-scroll,
|
||||
.CodeMirror-sizer,
|
||||
.CodeMirror-gutter,
|
||||
.CodeMirror-gutters,
|
||||
.CodeMirror-linenumber {
|
||||
-moz-box-sizing: content-box;
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.CodeMirror-measure {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.CodeMirror-cursor {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
}
|
||||
.CodeMirror-measure pre { position: static; }
|
||||
|
||||
div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
}
|
||||
div.CodeMirror-dragcursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-focused div.CodeMirror-cursors {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.CodeMirror-selected { background: #d9d9d9; }
|
||||
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
|
||||
.CodeMirror-crosshair { cursor: crosshair; }
|
||||
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
|
||||
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
|
||||
|
||||
.cm-searching {
|
||||
background-color: #ffa;
|
||||
background-color: rgba(255, 255, 0, .4);
|
||||
}
|
||||
|
||||
/* Used to force a border model for a node */
|
||||
.cm-force-border { padding-right: .1px; }
|
||||
|
||||
@media print {
|
||||
/* Hide the cursor when printing */
|
||||
.CodeMirror div.CodeMirror-cursors {
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/* See issue #2901 */
|
||||
.cm-tab-wrap-hack:after { content: ''; }
|
||||
|
||||
/* Help users use markselection to safely style text background */
|
||||
span.CodeMirror-selectedtext { background: none; }
|
||||
9874
assets/static/lib/codemirror/lib/codemirror.js
vendored
9874
assets/static/lib/codemirror/lib/codemirror.js
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,53 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: Properties files mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="properties.js"></script>
|
||||
<style>.CodeMirror {border-top: 1px solid #ddd; border-bottom: 1px solid #ddd;}</style>
|
||||
<div id=nav>
|
||||
<a href="https://codemirror.net/5"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror5">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">Properties files</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>Properties files mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
# This is a properties file
|
||||
a.key = A value
|
||||
another.key = http://example.com
|
||||
! Exclamation mark as comment
|
||||
but.not=Within ! A value # indeed
|
||||
# Spaces at the beginning of a line
|
||||
spaces.before.key=value
|
||||
backslash=Used for multi\
|
||||
line entries,\
|
||||
that's convenient.
|
||||
# Unicode sequences
|
||||
unicode.key=This is \u0020 Unicode
|
||||
no.multiline=here
|
||||
# Colons
|
||||
colons : can be used too
|
||||
# Spaces
|
||||
spaces\ in\ keys=Not very common...
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-properties</code>,
|
||||
<code>text/x-ini</code>.</p>
|
||||
|
||||
</article>
|
||||
@@ -1,78 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("properties", function() {
|
||||
return {
|
||||
token: function(stream, state) {
|
||||
var sol = stream.sol() || state.afterSection;
|
||||
var eol = stream.eol();
|
||||
|
||||
state.afterSection = false;
|
||||
|
||||
if (sol) {
|
||||
if (state.nextMultiline) {
|
||||
state.inMultiline = true;
|
||||
state.nextMultiline = false;
|
||||
} else {
|
||||
state.position = "def";
|
||||
}
|
||||
}
|
||||
|
||||
if (eol && ! state.nextMultiline) {
|
||||
state.inMultiline = false;
|
||||
state.position = "def";
|
||||
}
|
||||
|
||||
if (sol) {
|
||||
while(stream.eatSpace()) {}
|
||||
}
|
||||
|
||||
var ch = stream.next();
|
||||
|
||||
if (sol && (ch === "#" || ch === "!" || ch === ";")) {
|
||||
state.position = "comment";
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else if (sol && ch === "[") {
|
||||
state.afterSection = true;
|
||||
stream.skipTo("]"); stream.eat("]");
|
||||
return "header";
|
||||
} else if (ch === "=" || ch === ":") {
|
||||
state.position = "quote";
|
||||
return null;
|
||||
} else if (ch === "\\" && state.position === "quote") {
|
||||
if (stream.eol()) { // end of line?
|
||||
// Multiline value
|
||||
state.nextMultiline = true;
|
||||
}
|
||||
}
|
||||
|
||||
return state.position;
|
||||
},
|
||||
|
||||
startState: function() {
|
||||
return {
|
||||
position : "def", // Current position, "def", "quote" or "comment"
|
||||
nextMultiline : false, // Is the next line multiline value
|
||||
inMultiline : false, // Is the current line a multiline value
|
||||
afterSection : false // Did we just open a section
|
||||
};
|
||||
}
|
||||
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-properties", "properties");
|
||||
CodeMirror.defineMIME("text/x-ini", "properties");
|
||||
|
||||
});
|
||||
@@ -1,73 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: TOML Mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="toml.js"></script>
|
||||
<style>.CodeMirror {border-top: 1px solid black; border-bottom: 1px solid black;}</style>
|
||||
<div id=nav>
|
||||
<a href="https://codemirror.net/5"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror5">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">TOML Mode</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>TOML Mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
# This is a TOML document. Boom.
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
organization = "GitHub"
|
||||
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
||||
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
||||
|
||||
[database]
|
||||
server = "192.168.1.1"
|
||||
ports = [ 8001, 8001, 8002 ]
|
||||
connection_max = 5000
|
||||
enabled = true
|
||||
|
||||
[servers]
|
||||
|
||||
# You can indent as you please. Tabs or spaces. TOML don't care.
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
dc = "eqdc10"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
dc = "eqdc10"
|
||||
|
||||
[clients]
|
||||
data = [ ["gamma", "delta"], [1, 2] ]
|
||||
|
||||
# Line breaks are OK when inside arrays
|
||||
hosts = [
|
||||
"alpha",
|
||||
"omega"
|
||||
]
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
mode: {name: "toml"},
|
||||
lineNumbers: true
|
||||
});
|
||||
</script>
|
||||
<h3>The TOML Mode</h3>
|
||||
<p> Created by Forbes Lindesay.</p>
|
||||
<p><strong>MIME type defined:</strong> <code>text/x-toml</code>.</p>
|
||||
</article>
|
||||
88
assets/static/lib/codemirror/mode/toml/toml.js
vendored
88
assets/static/lib/codemirror/mode/toml/toml.js
vendored
@@ -1,88 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("toml", function () {
|
||||
return {
|
||||
startState: function () {
|
||||
return {
|
||||
inString: false,
|
||||
stringType: "",
|
||||
lhs: true,
|
||||
inArray: 0
|
||||
};
|
||||
},
|
||||
token: function (stream, state) {
|
||||
//check for state changes
|
||||
if (!state.inString && ((stream.peek() == '"') || (stream.peek() == "'"))) {
|
||||
state.stringType = stream.peek();
|
||||
stream.next(); // Skip quote
|
||||
state.inString = true; // Update state
|
||||
}
|
||||
if (stream.sol() && state.inArray === 0) {
|
||||
state.lhs = true;
|
||||
}
|
||||
//return state
|
||||
if (state.inString) {
|
||||
while (state.inString && !stream.eol()) {
|
||||
if (stream.peek() === state.stringType) {
|
||||
stream.next(); // Skip quote
|
||||
state.inString = false; // Clear flag
|
||||
} else if (stream.peek() === '\\') {
|
||||
stream.next();
|
||||
stream.next();
|
||||
} else {
|
||||
stream.match(/^.[^\\\"\']*/);
|
||||
}
|
||||
}
|
||||
return state.lhs ? "property string" : "string"; // Token style
|
||||
} else if (state.inArray && stream.peek() === ']') {
|
||||
stream.next();
|
||||
state.inArray--;
|
||||
return 'bracket';
|
||||
} else if (state.lhs && stream.peek() === '[' && stream.skipTo(']')) {
|
||||
stream.next();//skip closing ]
|
||||
// array of objects has an extra open & close []
|
||||
if (stream.peek() === ']') stream.next();
|
||||
return "atom";
|
||||
} else if (stream.peek() === "#") {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
} else if (stream.eatSpace()) {
|
||||
return null;
|
||||
} else if (state.lhs && stream.eatWhile(function (c) { return c != '=' && c != ' '; })) {
|
||||
return "property";
|
||||
} else if (state.lhs && stream.peek() === "=") {
|
||||
stream.next();
|
||||
state.lhs = false;
|
||||
return null;
|
||||
} else if (!state.lhs && stream.match(/^\d\d\d\d[\d\-\:\.T]*Z/)) {
|
||||
return 'atom'; //date
|
||||
} else if (!state.lhs && (stream.match('true') || stream.match('false'))) {
|
||||
return 'atom';
|
||||
} else if (!state.lhs && stream.peek() === '[') {
|
||||
state.inArray++;
|
||||
stream.next();
|
||||
return 'bracket';
|
||||
} else if (!state.lhs && stream.match(/^\-?\d+(?:\.\d+)?/)) {
|
||||
return 'number';
|
||||
} else if (!stream.eatSpace()) {
|
||||
stream.next();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME('text/x-toml', 'toml');
|
||||
|
||||
});
|
||||
@@ -1,80 +0,0 @@
|
||||
<!doctype html>
|
||||
|
||||
<title>CodeMirror: YAML mode</title>
|
||||
<meta charset="utf-8"/>
|
||||
<link rel=stylesheet href="../../doc/docs.css">
|
||||
|
||||
<link rel="stylesheet" href="../../lib/codemirror.css">
|
||||
<script src="../../lib/codemirror.js"></script>
|
||||
<script src="yaml.js"></script>
|
||||
<style>.CodeMirror { border-top: 1px solid #ddd; border-bottom: 1px solid #ddd; }</style>
|
||||
<div id=nav>
|
||||
<a href="https://codemirror.net/5"><h1>CodeMirror</h1><img id=logo src="../../doc/logo.png" alt=""></a>
|
||||
|
||||
<ul>
|
||||
<li><a href="../../index.html">Home</a>
|
||||
<li><a href="../../doc/manual.html">Manual</a>
|
||||
<li><a href="https://github.com/codemirror/codemirror5">Code</a>
|
||||
</ul>
|
||||
<ul>
|
||||
<li><a href="../index.html">Language modes</a>
|
||||
<li><a class=active href="#">YAML</a>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<article>
|
||||
<h2>YAML mode</h2>
|
||||
<form><textarea id="code" name="code">
|
||||
--- # Favorite movies
|
||||
- Casablanca
|
||||
- North by Northwest
|
||||
- The Man Who Wasn't There
|
||||
--- # Shopping list
|
||||
[milk, pumpkin pie, eggs, juice]
|
||||
--- # Indented Blocks, common in YAML data files, use indentation and new lines to separate the key: value pairs
|
||||
name: John Smith
|
||||
age: 33
|
||||
--- # Inline Blocks, common in YAML data streams, use commas to separate the key: value pairs between braces
|
||||
{name: John Smith, age: 33}
|
||||
---
|
||||
receipt: Oz-Ware Purchase Invoice
|
||||
date: 2007-08-06
|
||||
customer:
|
||||
given: Dorothy
|
||||
family: Gale
|
||||
|
||||
items:
|
||||
- part_no: A4786
|
||||
descrip: Water Bucket (Filled)
|
||||
price: 1.47
|
||||
quantity: 4
|
||||
|
||||
- part_no: E1628
|
||||
descrip: High Heeled "Ruby" Slippers
|
||||
size: 8
|
||||
price: 100.27
|
||||
quantity: 1
|
||||
|
||||
bill-to: &id001
|
||||
street: |
|
||||
123 Tornado Alley
|
||||
Suite 16
|
||||
city: East Centerville
|
||||
state: KS
|
||||
|
||||
ship-to: *id001
|
||||
|
||||
specialDelivery: >
|
||||
Follow the Yellow Brick
|
||||
Road to the Emerald City.
|
||||
Pay no attention to the
|
||||
man behind the curtain.
|
||||
...
|
||||
</textarea></form>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {});
|
||||
</script>
|
||||
|
||||
<p><strong>MIME types defined:</strong> <code>text/x-yaml</code>.</p>
|
||||
|
||||
</article>
|
||||
120
assets/static/lib/codemirror/mode/yaml/yaml.js
vendored
120
assets/static/lib/codemirror/mode/yaml/yaml.js
vendored
@@ -1,120 +0,0 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: https://codemirror.net/5/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"));
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror"], mod);
|
||||
else // Plain browser env
|
||||
mod(CodeMirror);
|
||||
})(function(CodeMirror) {
|
||||
"use strict";
|
||||
|
||||
CodeMirror.defineMode("yaml", function() {
|
||||
|
||||
var cons = ['true', 'false', 'on', 'off', 'yes', 'no'];
|
||||
var keywordRegex = new RegExp("\\b(("+cons.join(")|(")+"))$", 'i');
|
||||
|
||||
return {
|
||||
token: function(stream, state) {
|
||||
var ch = stream.peek();
|
||||
var esc = state.escaped;
|
||||
state.escaped = false;
|
||||
/* comments */
|
||||
if (ch == "#" && (stream.pos == 0 || /\s/.test(stream.string.charAt(stream.pos - 1)))) {
|
||||
stream.skipToEnd();
|
||||
return "comment";
|
||||
}
|
||||
|
||||
if (stream.match(/^('([^']|\\.)*'?|"([^"]|\\.)*"?)/))
|
||||
return "string";
|
||||
|
||||
if (state.literal && stream.indentation() > state.keyCol) {
|
||||
stream.skipToEnd(); return "string";
|
||||
} else if (state.literal) { state.literal = false; }
|
||||
if (stream.sol()) {
|
||||
state.keyCol = 0;
|
||||
state.pair = false;
|
||||
state.pairStart = false;
|
||||
/* document start */
|
||||
if(stream.match('---')) { return "def"; }
|
||||
/* document end */
|
||||
if (stream.match('...')) { return "def"; }
|
||||
/* array list item */
|
||||
if (stream.match(/\s*-\s+/)) { return 'meta'; }
|
||||
}
|
||||
/* inline pairs/lists */
|
||||
if (stream.match(/^(\{|\}|\[|\])/)) {
|
||||
if (ch == '{')
|
||||
state.inlinePairs++;
|
||||
else if (ch == '}')
|
||||
state.inlinePairs--;
|
||||
else if (ch == '[')
|
||||
state.inlineList++;
|
||||
else
|
||||
state.inlineList--;
|
||||
return 'meta';
|
||||
}
|
||||
|
||||
/* list separator */
|
||||
if (state.inlineList > 0 && !esc && ch == ',') {
|
||||
stream.next();
|
||||
return 'meta';
|
||||
}
|
||||
/* pairs separator */
|
||||
if (state.inlinePairs > 0 && !esc && ch == ',') {
|
||||
state.keyCol = 0;
|
||||
state.pair = false;
|
||||
state.pairStart = false;
|
||||
stream.next();
|
||||
return 'meta';
|
||||
}
|
||||
|
||||
/* start of value of a pair */
|
||||
if (state.pairStart) {
|
||||
/* block literals */
|
||||
if (stream.match(/^\s*(\||\>)\s*/)) { state.literal = true; return 'meta'; };
|
||||
/* references */
|
||||
if (stream.match(/^\s*(\&|\*)[a-z0-9\._-]+\b/i)) { return 'variable-2'; }
|
||||
/* numbers */
|
||||
if (state.inlinePairs == 0 && stream.match(/^\s*-?[0-9\.\,]+\s?$/)) { return 'number'; }
|
||||
if (state.inlinePairs > 0 && stream.match(/^\s*-?[0-9\.\,]+\s?(?=(,|}))/)) { return 'number'; }
|
||||
/* keywords */
|
||||
if (stream.match(keywordRegex)) { return 'keyword'; }
|
||||
}
|
||||
|
||||
/* pairs (associative arrays) -> key */
|
||||
if (!state.pair && stream.match(/^\s*(?:[,\[\]{}&*!|>'"%@`][^\s'":]|[^\s,\[\]{}#&*!|>'"%@`])[^#:]*(?=:($|\s))/)) {
|
||||
state.pair = true;
|
||||
state.keyCol = stream.indentation();
|
||||
return "atom";
|
||||
}
|
||||
if (state.pair && stream.match(/^:\s*/)) { state.pairStart = true; return 'meta'; }
|
||||
|
||||
/* nothing found, continue */
|
||||
state.pairStart = false;
|
||||
state.escaped = (ch == '\\');
|
||||
stream.next();
|
||||
return null;
|
||||
},
|
||||
startState: function() {
|
||||
return {
|
||||
pair: false,
|
||||
pairStart: false,
|
||||
keyCol: 0,
|
||||
inlinePairs: 0,
|
||||
inlineList: 0,
|
||||
literal: false,
|
||||
escaped: false
|
||||
};
|
||||
},
|
||||
lineComment: "#",
|
||||
fold: "indent"
|
||||
};
|
||||
});
|
||||
|
||||
CodeMirror.defineMIME("text/x-yaml", "yaml");
|
||||
CodeMirror.defineMIME("text/yaml", "yaml");
|
||||
|
||||
});
|
||||
71
assets/static/lib/codemirror/theme/base16.css
vendored
71
assets/static/lib/codemirror/theme/base16.css
vendored
@@ -1,71 +0,0 @@
|
||||
/*
|
||||
|
||||
Name: Base16 Default Light
|
||||
Author: Chris Kempson (http://chriskempson.com)
|
||||
|
||||
CodeMirror template by Jan T. Sott (https://github.com/idleberg/base16-codemirror)
|
||||
Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16)
|
||||
|
||||
*/
|
||||
|
||||
.cm-s-base16.CodeMirror { background: #f5f5f5; color: #202020; }
|
||||
.cm-s-base16 div.CodeMirror-selected { background: #e0e0e0; }
|
||||
.cm-s-base16 .CodeMirror-line::selection, .cm-s-base16 .CodeMirror-line > span::selection, .cm-s-base16 .CodeMirror-line > span > span::selection { background: #e0e0e0; }
|
||||
.cm-s-base16 .CodeMirror-line::-moz-selection, .cm-s-base16 .CodeMirror-line > span::-moz-selection, .cm-s-base16 .CodeMirror-line > span > span::-moz-selection { background: #e0e0e0; }
|
||||
.cm-s-base16 .CodeMirror-gutters { background: #f5f5f5; border-right: 0px; }
|
||||
.cm-s-base16 .CodeMirror-guttermarker { color: #ac4142; }
|
||||
.cm-s-base16 .CodeMirror-guttermarker-subtle { color: #b0b0b0; }
|
||||
.cm-s-base16 .CodeMirror-linenumber { color: #b0b0b0; }
|
||||
.cm-s-base16 .CodeMirror-cursor { border-left: 1px solid #505050; }
|
||||
|
||||
.cm-s-base16 span.cm-comment { color: #8f5536; }
|
||||
.cm-s-base16 span.cm-atom { color: #aa759f; }
|
||||
.cm-s-base16 span.cm-number { color: #aa759f; }
|
||||
|
||||
.cm-s-base16 span.cm-property, .cm-s-base16 span.cm-attribute { color: #90a959; }
|
||||
.cm-s-base16 span.cm-keyword { color: #ac4142; }
|
||||
.cm-s-base16 span.cm-string { color: #f4bf75; }
|
||||
|
||||
.cm-s-base16 span.cm-variable { color: #90a959; }
|
||||
.cm-s-base16 span.cm-variable-2 { color: #6a9fb5; }
|
||||
.cm-s-base16 span.cm-def { color: #d28445; }
|
||||
.cm-s-base16 span.cm-bracket { color: #202020; }
|
||||
.cm-s-base16 span.cm-tag { color: #ac4142; }
|
||||
.cm-s-base16 span.cm-link { color: #aa759f; }
|
||||
.cm-s-base16 span.cm-error { background: #ac4142; color: #505050; }
|
||||
|
||||
.cm-s-base16 .CodeMirror-activeline-background { background: #DDDCDC; }
|
||||
.cm-s-base16 .CodeMirror-matchingbracket { color: #f5f5f5 !important; background-color: #6A9FB5 !important}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.cm-s-base16.CodeMirror { background: #151515; color: #e0e0e0; }
|
||||
.cm-s-base16 div.CodeMirror-selected { background: #303030; }
|
||||
.cm-s-base16 .CodeMirror-line::selection, .cm-s-base16 .CodeMirror-line > span::selection, .cm-s-base16 .CodeMirror-line > span > span::selection { background: rgba(48, 48, 48, .99); }
|
||||
.cm-s-base16 .CodeMirror-line::-moz-selection, .cm-s-base16 .CodeMirror-line > span::-moz-selection, .cm-s-base16 .CodeMirror-line > span > span::-moz-selection { background: rgba(48, 48, 48, .99); }
|
||||
.cm-s-base16 .CodeMirror-gutters { background: #151515; border-right: 0px; }
|
||||
.cm-s-base16 .CodeMirror-guttermarker { color: #ac4142; }
|
||||
.cm-s-base16 .CodeMirror-guttermarker-subtle { color: #505050; }
|
||||
.cm-s-base16 .CodeMirror-linenumber { color: #505050; }
|
||||
.cm-s-base16 .CodeMirror-cursor { border-left: 1px solid #b0b0b0; }
|
||||
.cm-s-base16.cm-fat-cursor .CodeMirror-cursor { background-color: #8e8d8875 !important; }
|
||||
.cm-s-base16 .cm-animate-fat-cursor { background-color: #8e8d8875 !important; }
|
||||
|
||||
.cm-s-base16 span.cm-comment { color: #8f5536; }
|
||||
.cm-s-base16 span.cm-atom { color: #aa759f; }
|
||||
.cm-s-base16 span.cm-number { color: #aa759f; }
|
||||
|
||||
.cm-s-base16 span.cm-property, .cm-s-base16 span.cm-attribute { color: #90a959; }
|
||||
.cm-s-base16 span.cm-keyword { color: #ac4142; }
|
||||
.cm-s-base16 span.cm-string { color: #f4bf75; }
|
||||
|
||||
.cm-s-base16 span.cm-variable { color: #90a959; }
|
||||
.cm-s-base16 span.cm-variable-2 { color: #6a9fb5; }
|
||||
.cm-s-base16 span.cm-def { color: #d28445; }
|
||||
.cm-s-base16 span.cm-bracket { color: #e0e0e0; }
|
||||
.cm-s-base16 span.cm-tag { color: #ac4142; }
|
||||
.cm-s-base16 span.cm-link { color: #aa759f; }
|
||||
.cm-s-base16 span.cm-error { background: #ac4142; color: #b0b0b0; }
|
||||
|
||||
.cm-s-base16 .CodeMirror-activeline-background { background: #202020; }
|
||||
.cm-s-base16 .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,28 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<link rel="stylesheet" href="../static/lib/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="../static/lib/codemirror/theme/base16.css">
|
||||
<script src="../static/lib/codemirror/lib/codemirror.js"></script>
|
||||
<script src="../static/lib/codemirror/mode/properties/properties.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://codemirror.net/5/doc/manual.html">https://codemirror.net/5/doc/manual.html</a>
|
||||
<textarea id="code" name="code"></textarea>
|
||||
<script>
|
||||
var editor = CodeMirror.fromTextArea(document.getElementById("code"), {
|
||||
lineNumbers: true,
|
||||
mode: 'text/x-ini',
|
||||
theme: 'base16'
|
||||
});
|
||||
editor.setValue(`
|
||||
[HTTP:aaa.bbb.com]
|
||||
a = 1
|
||||
b = 2
|
||||
`)
|
||||
console.log(editor.getValue());
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -6,9 +6,9 @@
|
||||
<link rel="stylesheet" href="./static/css/layui-theme-dark.css?v=${ .version }">
|
||||
<link rel="stylesheet" href="./static/css/index.css?v=${ .version }">
|
||||
<link rel="stylesheet" href="./static/css/color.css?v=${ .version }">
|
||||
<script src="./static/js/json-process.js?v=${ .version }"></script>
|
||||
<script src="./static/js/toml.js?v=${ .version }"></script>
|
||||
<script src="./static/lib/layui/layui.js?v=${ .version }"></script>
|
||||
<script src="./static/js/toml.js?v=${ .version }"></script>
|
||||
<script src="./static/js/json-process.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-client-info.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-proxy-overview.js?v=${ .version }"></script>
|
||||
<script src="./static/js/index-proxy-list.js?v=${ .version }"></script>
|
||||
@@ -146,51 +146,51 @@
|
||||
</script>
|
||||
|
||||
<!--用户列表-添加用户表单模板-->
|
||||
<script type="text/html" id="addProxyTemplate">
|
||||
<form class="layui-form" id="addProxyForm" lay-filter="addProxyForm">
|
||||
<script type="text/html" id="proxyFormTemplate">
|
||||
<form class="layui-form" id="proxyForm" lay-filter="proxyForm">
|
||||
<div class="layui-tab layui-tab-brief">
|
||||
<ul class="layui-tab-title">
|
||||
<li class="layui-this">${ .Basic }</li>
|
||||
<li>${ .Extra }</li>
|
||||
</ul>
|
||||
<div class="layui-tab-content">
|
||||
<input type="hidden" name="type">
|
||||
<input type="hidden" name="type" id="proxyType">
|
||||
<input type="hidden" name="${ .OriginalNameKey }" id="originalNameKey">
|
||||
<div class="layui-tab-item layui-show">
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .ProxyName }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="name" placeholder="${ .ProxyName }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="name" id="proxyName" placeholder="${ .ProxyNameExample }"
|
||||
autocomplete="off" class="layui-input" lay-verify="proxyName"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .LocalIP }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="localIP" placeholder="${ .LocalIP }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="localIP" id="localIP" placeholder="${ .LocalIPExample }"
|
||||
autocomplete="off" class="layui-input"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item">
|
||||
<label class="layui-form-label">${ .LocalPort }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="localPort" placeholder="${ .LocalPort }" autocomplete="off"
|
||||
class="layui-input"/>
|
||||
<input type="text" name="localPort" id="localPort" placeholder="${ .LocalPortExample }"
|
||||
autocomplete="off" class="layui-input" lay-verify="localPort"/>
|
||||
</div>
|
||||
</div>
|
||||
{{# if (d.type.toLowerCase() === 'http' || d.type.toLowerCase() === 'https') { }}
|
||||
<div class="layui-form-item http https">
|
||||
<label class="layui-form-label">${ .CustomDomains }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="customDomains" placeholder="${ .CustomDomains }" autocomplete="off"
|
||||
class="layui-textarea"></textarea>
|
||||
<textarea name="customDomains" id="customDomains" placeholder="${ .CustomDomainsExample }"
|
||||
autocomplete="off" class="layui-textarea" lay-verify="domain"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="layui-form-item layui-form-text http https">
|
||||
<label class="layui-form-label">${ .Subdomain }</label>
|
||||
<div class="layui-input-block">
|
||||
<textarea name="subdomain" placeholder="${ .Subdomain }" autocomplete="off"
|
||||
class="layui-textarea"></textarea>
|
||||
<textarea name="subdomain" id="subdomain" placeholder="${ .Subdomain }" autocomplete="off"
|
||||
class="layui-textarea" lay-verify="domain"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
{{# } }}
|
||||
@@ -198,7 +198,8 @@
|
||||
<div class="layui-form-item tcp udp">
|
||||
<label class="layui-form-label">${ .RemotePort }</label>
|
||||
<div class="layui-input-block">
|
||||
<input type="text" name="remotePort" placeholder="${ .RemotePort }" autocomplete="off"
|
||||
<input type="text" name="remotePort" placeholder="${ .RemotePortExample }"
|
||||
autocomplete="off"
|
||||
class="layui-input"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const version = "1.0.1"
|
||||
const version = "2.0.0"
|
||||
|
||||
var (
|
||||
showVersion bool
|
||||
|
||||
@@ -85,10 +85,15 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
||||
"Basic": ginI18n.MustGetMessage(context, "Basic"),
|
||||
"Extra": ginI18n.MustGetMessage(context, "Extra"),
|
||||
"ProxyName": ginI18n.MustGetMessage(context, "Proxy Name"),
|
||||
"ProxyNameExample": ginI18n.MustGetMessage(context, "Proxy Name Example"),
|
||||
"LocalIP": ginI18n.MustGetMessage(context, "Local IP"),
|
||||
"LocalIPExample": ginI18n.MustGetMessage(context, "Local IP Example"),
|
||||
"LocalPort": ginI18n.MustGetMessage(context, "Local Port"),
|
||||
"LocalPortExample": ginI18n.MustGetMessage(context, "Local Port Example"),
|
||||
"RemotePort": ginI18n.MustGetMessage(context, "Remote Port"),
|
||||
"RemotePortExample": ginI18n.MustGetMessage(context, "Remote Port Example"),
|
||||
"CustomDomains": ginI18n.MustGetMessage(context, "Custom Domains"),
|
||||
"CustomDomainsExample": ginI18n.MustGetMessage(context, "Custom Domains Example"),
|
||||
"Subdomain": ginI18n.MustGetMessage(context, "Subdomain"),
|
||||
"UseEncryption": ginI18n.MustGetMessage(context, "Use Encryption"),
|
||||
"true": ginI18n.MustGetMessage(context, "true"),
|
||||
@@ -102,6 +107,7 @@ func (c *HandleController) MakeIndexFunc() func(context *gin.Context) {
|
||||
func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
||||
return func(context *gin.Context) {
|
||||
context.JSON(http.StatusOK, gin.H{
|
||||
"Proxies": ginI18n.MustGetMessage(context, "Proxies"),
|
||||
"EmptyData": ginI18n.MustGetMessage(context, "Empty data"),
|
||||
"true": ginI18n.MustGetMessage(context, "true"),
|
||||
"false": ginI18n.MustGetMessage(context, "false"),
|
||||
@@ -136,6 +142,16 @@ func (c *HandleController) MakeLangFunc() func(context *gin.Context) {
|
||||
"ProxyExist": ginI18n.MustGetMessage(context, "Proxy Exist"),
|
||||
"ProxyNotExist": ginI18n.MustGetMessage(context, "Proxy Not Exist"),
|
||||
"ClientTips": ginI18n.MustGetMessage(context, "Client Tips"),
|
||||
"and": ginI18n.MustGetMessage(context, "and"),
|
||||
"RequireNotAllEmpty": ginI18n.MustGetMessage(context, "Require Not All Empty"),
|
||||
"RequireNotEmpty": ginI18n.MustGetMessage(context, "Require Not Empty"),
|
||||
"RequireNumber": ginI18n.MustGetMessage(context, "Require Number"),
|
||||
"RequireBoolean": ginI18n.MustGetMessage(context, "Require Boolean"),
|
||||
"RequireArray": ginI18n.MustGetMessage(context, "Require Array"),
|
||||
"Total": ginI18n.MustGetMessage(context, "Total"),
|
||||
"Items": ginI18n.MustGetMessage(context, "Items"),
|
||||
"Goto": ginI18n.MustGetMessage(context, "Go to"),
|
||||
"PerPage": ginI18n.MustGetMessage(context, "Per Page"),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -149,60 +165,27 @@ func (c *HandleController) MakeUpdateProxyFunc() func(context *gin.Context) {
|
||||
Message: "proxy update success",
|
||||
}
|
||||
|
||||
data, _ := context.GetRawData()
|
||||
data, err := context.GetRawData()
|
||||
if err != nil {
|
||||
response.Success = false
|
||||
response.Code = http.StatusNoContent
|
||||
response.Message = fmt.Sprintf("update failed, error : %v", err)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
c.UpdateFrpcConfig(data)
|
||||
res := c.UpdateFrpcConfig(data)
|
||||
if !res.Success {
|
||||
response.Success = false
|
||||
response.Code = res.Code
|
||||
response.Message = fmt.Sprintf("update failed, error : %v", res.Message)
|
||||
log.Printf(response.Message)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
return
|
||||
}
|
||||
|
||||
context.JSON(200, &response)
|
||||
|
||||
//proxy.GetBaseConfig()
|
||||
//
|
||||
//oldName := proxy[OriginalNameKey]
|
||||
//name := proxy[NameKey]
|
||||
//
|
||||
//if trimString(oldName) == "" || trimString(name) == "" {
|
||||
// response.Success = false
|
||||
// response.Code = ParamError
|
||||
// response.Message = fmt.Sprintf("proxy add failed, proxy name invalid")
|
||||
// log.Printf(response.Message)
|
||||
// context.JSON(http.StatusOK, &response)
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//if _, exist := clientProxies[oldName]; !exist {
|
||||
// response.Success = false
|
||||
// response.Code = ProxyNotExist
|
||||
// response.Message = fmt.Sprintf("proxy update failed, proxy not exist")
|
||||
// log.Printf(response.Message)
|
||||
// context.JSON(http.StatusOK, &response)
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//if oldName != name {
|
||||
// if _, exist := clientProxies[name]; exist {
|
||||
// response.Success = false
|
||||
// response.Code = ProxyExist
|
||||
// response.Message = fmt.Sprintf("proxy update failed, proxy exist")
|
||||
// log.Printf(response.Message)
|
||||
// context.JSON(http.StatusOK, &response)
|
||||
// return
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//delete(clientProxies, oldName)
|
||||
//clientProxies[name] = proxy
|
||||
//
|
||||
//res := c.UpdateFrpcConfig()
|
||||
//if !res.Success {
|
||||
// response.Success = false
|
||||
// response.Code = res.Code
|
||||
// response.Message = fmt.Sprintf("user update failed, error : %v", res.Message)
|
||||
// log.Printf(response.Message)
|
||||
// context.JSON(http.StatusOK, &response)
|
||||
// return
|
||||
//}
|
||||
//
|
||||
//context.JSON(http.StatusOK, &response)
|
||||
context.JSON(http.StatusOK, &response)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user