Showing preview only (665K chars total). Download the full file or copy to clipboard to get everything.
Repository: wangweianger/APubPlat
Branch: master
Commit: 7b6a3a37dc17
Files: 102
Total size: 617.9 KB
Directory structure:
gitextract_cteq_eaa/
├── .autod.conf.js
├── .eslintignore
├── .eslintrc
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── app/
│ ├── controller/
│ │ ├── api/
│ │ │ ├── application.js
│ │ │ ├── assets.js
│ │ │ ├── build.js
│ │ │ ├── commtask.js
│ │ │ ├── console.js
│ │ │ ├── email.js
│ │ │ ├── environment.js
│ │ │ ├── files.js
│ │ │ ├── logs.js
│ │ │ ├── qiniu.js
│ │ │ ├── team.js
│ │ │ ├── user.js
│ │ │ └── util.js
│ │ ├── home.js
│ │ └── web.js
│ ├── extend/
│ │ └── application.js
│ ├── io/
│ │ ├── controller/
│ │ │ └── nsp.js
│ │ └── middleware/
│ │ └── auth.js
│ ├── middleware/
│ │ └── token_required.js
│ ├── model/
│ │ ├── application.js
│ │ ├── assets.js
│ │ ├── commtask.js
│ │ ├── email.js
│ │ ├── environment.js
│ │ ├── logs.js
│ │ ├── team.js
│ │ └── user.js
│ ├── public/
│ │ ├── css/
│ │ │ ├── base.css
│ │ │ └── home.css
│ │ ├── iconfont/
│ │ │ └── iconfont.css
│ │ ├── js/
│ │ │ ├── config.js
│ │ │ ├── util.js
│ │ │ ├── vue-components.js
│ │ │ └── vue-filters.js
│ │ └── lib/
│ │ ├── bootstrap/
│ │ │ ├── css/
│ │ │ │ ├── bootstrap-theme.css
│ │ │ │ └── bootstrap.css
│ │ │ └── js/
│ │ │ ├── bootstrap.js
│ │ │ └── npm.js
│ │ ├── page/
│ │ │ ├── page.css
│ │ │ └── page.js
│ │ └── popup/
│ │ ├── popup.css
│ │ └── popup.js
│ ├── router/
│ │ ├── api.js
│ │ └── home.js
│ ├── router.js
│ ├── service/
│ │ ├── application.js
│ │ ├── assets.js
│ │ ├── build.js
│ │ ├── commtask.js
│ │ ├── console.js
│ │ ├── email.js
│ │ ├── environment.js
│ │ ├── files.js
│ │ ├── logs.js
│ │ ├── qiniu.js
│ │ ├── team.js
│ │ ├── user.js
│ │ └── util.js
│ ├── tempFile/
│ │ └── install-node.sh
│ ├── util/
│ │ ├── sftp.js
│ │ ├── socket.js
│ │ ├── ssh2.js
│ │ └── utils.js
│ └── view/
│ ├── appconfig.html
│ ├── application.html
│ ├── assets.html
│ ├── assetsconfig.html
│ ├── build.html
│ ├── buildprocess.html
│ ├── commtask.html
│ ├── console.html
│ ├── email.html
│ ├── environment.html
│ ├── footer.html
│ ├── header.html
│ ├── home.html
│ ├── layout.html
│ ├── login.html
│ ├── logs.html
│ ├── reduction.html
│ ├── side.html
│ ├── team.html
│ └── user.html
├── app.js
├── appveyor.yml
├── config/
│ ├── config.default.js
│ ├── config.prod.js
│ └── plugin.js
├── lib/
│ └── plugin/
│ └── egg-email/
│ ├── LICENSE
│ ├── README.md
│ ├── app.js
│ ├── config/
│ │ └── config.default.js
│ ├── lib/
│ │ └── email.js
│ └── package.json
└── package.json
================================================
FILE CONTENTS
================================================
================================================
FILE: .autod.conf.js
================================================
'use strict';
module.exports = {
write: true,
prefix: '^',
plugin: 'autod-egg',
test: [
'test',
'benchmark',
],
dep: [
'egg',
'egg-scripts',
],
devdep: [
'egg-ci',
'egg-bin',
'egg-mock',
'autod',
'autod-egg',
'eslint',
'eslint-config-egg',
'webstorm-disable-index',
],
exclude: [
'./test/fixtures',
'./dist',
],
};
================================================
FILE: .eslintignore
================================================
coverage
================================================
FILE: .eslintrc
================================================
{
"extends": "eslint-config-egg",
"rules": {
"indent": [
"error",
4
]
},
"plugins": [
"html"
],
"settings": {
"html/html-extensions": [
".html"
]
}
}
================================================
FILE: .gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# next.js build output
.next
logs/
npm-debug.log
yarn-error.log
node_modules/
package-lock.json
yarn.lock
coverage/
.idea/
run/
D/
buildlogs/
.DS_Store
*.sw*
*.un~
config/config.prod_1.js
buildlogs/
================================================
FILE: .travis.yml
================================================
sudo: false
language: node_js
node_js:
- '8'
install:
- npm i npminstall && npminstall
script:
- npm run ci
after_script:
- npminstall codecov && codecov
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2018-2019 zane
- zane ([@wangweianger](https://github.com/wangweianger))
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# APubPlat - [开发文档](http://apub-wiki.seosiwei.com/)
[](https://nodejs.org/en/)
[](https://cn.vuejs.org/)
[](https://eggjs.org/)
[](https://www.mongodb.com/)
[](https://redis.io/)
[](https://www.npmjs.com/package/ssh2)
[](https://xtermjs.org/)
[](https://microsoft.github.io/monaco-editor/)
[](https://socket.io/)
APubPlat是一款开源免费的自动化部署、运维平台,开源堡垒机。
实现了Web Terminal,跟xshell一样的体验。可开启多窗口和批量命令的运行。
友好的持续集成,支持web前端、node、java、php等后端servers的发布,并支持单机和多机的同时发布能力。
### 开发文档:http://apub-wiki.seosiwei.com
# Preview


### 发布、备份、生成配置日志

### build servers

### Web Terminal

================================================
FILE: app/controller/api/application.js
================================================
'use strict';
const Controller = require('egg').Controller;
class ApplicationController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const team_code = query.team_code;
const environ_code = query.environ_code;
const net_type = query.net_type;
const status = query.status;
const name = query.app_name;
const result = await this.ctx.service.application.list(pageNo, pageSize, team_code, environ_code, net_type, status, name);
ctx.body = this.app.result({
data: result,
});
}
async all() {
const { ctx } = this;
const result = await this.ctx.service.application.all();
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const name = query.name;
const code = query.code;
const team_code = query.team_code;
const environ_code = query.environ_code;
const _id = query._id;
const user_name = query.user_name;
if (type === 2 && !_id) throw new Error('id参数不能为空!');
if (!team_code) throw new Error('请选择应用所属团队!');
if (!environ_code) throw new Error('请选择应用所属环境!');
if (!name) throw new Error('应用名称不能为空!');
if (!code) throw new Error('应用编码不能为空!');
const result = await this.ctx.service.application.handle({ type, name, code, status, _id, team_code, environ_code, user_name });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const status = query.status || 1;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.setStatus({ _id, status });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.delete(_id);
ctx.body = this.app.result({
data: result,
});
}
// 分配资产
async distribution() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const net_type = query.net_type || 1;
const assets_list = query.assets_list || [];
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.distribution(_id, assets_list, net_type);
ctx.body = this.app.result({
data: result,
});
}
// 获得单个应用详情
async itemdetail() {
const { ctx } = this;
const query = ctx.request.query;
const id = query.id;
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.itemdetail(id);
ctx.body = this.app.result({
data: result,
});
}
// 更新应用构建配置
async updateConfigs() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
const tasklist = query.tasklist || [];
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.updateConfigs(id, tasklist);
ctx.body = this.app.result({
data: result,
});
}
// 绑定|取消 应该绑定的邮箱
async handleEmail() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
const emaillist = query.emaillist || [];
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.application.handleEmail(id, emaillist);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = ApplicationController;
================================================
FILE: app/controller/api/assets.js
================================================
'use strict';
const Controller = require('egg').Controller;
class AssetsController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const team_code = query.team_code;
const assets_name = query.assets_name;
const status = query.status || '';
const result = await this.ctx.service.assets.list(pageNo, pageSize, team_code, assets_name, status);
ctx.body = this.app.result({
data: result,
});
}
async all() {
const { ctx } = this;
const result = await this.ctx.service.assets.all();
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const name = query.name;
const code = query.code;
const _id = query._id;
const team_code = query.team_code;
const outer_ip = query.outer_ip;
const lan_ip = query.lan_ip;
const user = query.user;
const port = query.port;
const password = query.password;
const user_name = query.user_name;
if (type === 2 && !_id) throw new Error('id参数不能为空!');
if (!team_code) throw new Error('请选择资产所属团队!');
if (!name) throw new Error('资产名称不能为空!');
if (!code) throw new Error('资产编码不能为空!');
if (!outer_ip) throw new Error('外网IP不能为空!');
if (!lan_ip) throw new Error('外网IP不能为空!');
if (!user) throw new Error('登录用户名不能为空!');
if (!port) throw new Error('登录端口号不能为空!');
if (!password) throw new Error('登录密码不能为空!');
const result = await this.ctx.service.assets.handle({ type, name, code, status, _id, team_code, outer_ip, lan_ip, user, port, password, user_name });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const status = query.status || 1;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.assets.setStatus({ _id, status });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.assets.delete(_id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = AssetsController;
================================================
FILE: app/controller/api/build.js
================================================
'use strict';
const Controller = require('egg').Controller;
class BuildController extends Controller {
// 生成构建配置
async generateBuildConfig() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id || '';
const taskItem = query.taskItem || {};
const assetsList = query.assetsList || [];
const user_name = query.user_name || '';
if (!taskItem.shell_path) throw new Error('shell脚本地址不能为空!');
if (!taskItem.shell_body) throw new Error('shell脚本内容不能为空!');
const result = await this.ctx.service.build.generateBuildConfig(id, taskItem, assetsList, user_name);
ctx.body = this.app.result({
data: result,
});
}
// 服务备份
async backupApplications() {
const { ctx } = this;
const query = ctx.request.body;
const taskItem = query.taskItem || {};
const assetsList = query.assetsList || [];
const id = query.id || '';
const user_name = query.user_name || '';
if (!taskItem.project_path) throw new Error('应用所在位置不能为空!');
if (!taskItem.backups_path) throw new Error('应用备份的路径不能为空!');
const result = await this.ctx.service.build.backupApplications(id, taskItem, assetsList, user_name);
ctx.body = this.app.result({
data: result,
});
}
// 构建应用
async buildApplicationed() {
const { ctx } = this;
const query = ctx.request.body;
const result = await this.ctx.service.logs.addLogs(query);
ctx.body = this.app.result({
data: result,
});
}
// 应用还原
async reductionApplications() {
const { ctx } = this;
const query = ctx.request.body;
const taskItem = query.taskItem || {};
const assetsList = query.assetsList || [];
const id = query.id || '';
const user_name = query.user_name || '';
if (!taskItem.reduction_shell_path) throw new Error('备份shell脚本路径不能为空!');
if (!taskItem.reduction_shell_body) throw new Error('备份shell脚本内容不能为空!');
const result = await this.ctx.service.build.reductionApplications(id, taskItem, assetsList, user_name);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = BuildController;
================================================
FILE: app/controller/api/commtask.js
================================================
'use strict';
const Controller = require('egg').Controller;
class CommtaskController extends Controller {
async list() {
const { ctx } = this;
const result = await this.ctx.service.commtask.list();
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
const name = query.name;
const handletype = query.handletype || 1;
const _id = query._id;
const shell_body = query.shell_body;
if (parseInt(handletype) === 2 && !_id) throw new Error('id参数不能为空!');
if (!name) throw new Error('脚本任务名称不能为空!');
if (!shell_body) throw new Error('脚本任务脚本内容不能为空!');
const result = await this.ctx.service.commtask.handle(query);
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.commtask.delete(id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = CommtaskController;
================================================
FILE: app/controller/api/console.js
================================================
'use strict';
const Controller = require('egg').Controller;
class ConsoleController extends Controller {
// 获得服务器ssh key
async getAssetSshKey() {
const { ctx } = this;
const query = ctx.request.body;
const { host, port, username, password } = query;
if (!host) throw new Error('资产host不能为空!');
if (!port) throw new Error('资产port不能为空!');
if (!username) throw new Error('资产username不能为空!');
if (!password) throw new Error('资产password不能为空!');
const result = await this.ctx.service.util.getAssetSshKey(query);
ctx.body = this.app.result({
data: result,
});
}
// 执行shell任务
async handleShellTasks() {
const { ctx } = this;
const query = ctx.request.body;
const { host, port, username, password, shell_type, shell_body, shell_path } = query;
if (!host) throw new Error('资产host不能为空!');
if (!port) throw new Error('资产port不能为空!');
if (!username) throw new Error('资产username不能为空!');
if (!password) throw new Error('资产password不能为空!');
if (!shell_type) throw new Error('执行脚本的类型不能为空!');
if (!shell_body) throw new Error('执行脚本的内容不能为空!');
if (parseInt(shell_type) === 2 && !shell_path) throw new Error('执行脚本的脚本路径不能为空!');
const result = await this.ctx.service.util.handleShellTasks(query);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = ConsoleController;
================================================
FILE: app/controller/api/email.js
================================================
'use strict';
const Controller = require('egg').Controller;
class EmailController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const status = query.status;
const result = await this.ctx.service.email.list(pageNo, pageSize, status);
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const name = query.name;
const email = query.email;
const id = query.id;
if (type === 2 && !id) throw new Error('id参数不能为空!');
if (!email) throw new Error('邮件地址不能为空!');
if (!name) throw new Error('邮件所属人不能为空!');
const result = await this.ctx.service.email.handle({ type, name, email, status, id });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
const status = query.status || 1;
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.email.setStatus({ id, status });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.email.delete(id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = EmailController;
================================================
FILE: app/controller/api/environment.js
================================================
'use strict';
const Controller = require('egg').Controller;
class TeamController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const result = await this.ctx.service.environment.list(pageNo, pageSize);
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
const name = query.name;
const code = query.code;
const id = query.id;
if (type === 2 && !id) throw new Error('id参数不能为空!');
if (!name) throw new Error('环境名称不能为空!');
if (!code) throw new Error('环境编码不能为空!');
const result = await this.ctx.service.environment.handle({ type, name, code, id });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id;
if (!id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.environment.delete(id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = TeamController;
================================================
FILE: app/controller/api/files.js
================================================
'use strict';
const Controller = require('egg').Controller;
class FilesController extends Controller {
// update file
async updatefile() {
const { ctx } = this;
const query = ctx.request.body;
const content = query.content;
const filename = query.filename;
if (!filename) throw new Error('需要修改的文件不能为空!');
if (!content) throw new Error('修改文件的内容不能为空!');
const result = await this.ctx.service.files.updatefile(filename, content) || {};
ctx.body = this.app.result({
data: result,
});
}
// add file
async addfile() {
const { ctx } = this;
const query = ctx.request.body;
const filename = query.filename.trim();
const content = query.content;
const remotePath = query.remotePath;
if (!filename) throw new Error('文件名称不能为空!');
if (!content) throw new Error('新增文件的内容不能为空!');
if (!remotePath) throw new Error('新增文件的远程目录不能为空!');
const result = await this.ctx.service.files.addfile(filename, content, remotePath) || {};
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = FilesController;
================================================
FILE: app/controller/api/logs.js
================================================
'use strict';
const Controller = require('egg').Controller;
class LogsController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const type = query.type || 1;
const name = query.name || '';
const application_id = query.application_id || '';
const result = await this.ctx.service.logs.list(pageNo, pageSize, type, name, application_id);
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const name = query.name;
const code = query.code;
const _id = query._id;
if (type === 2 && !_id) throw new Error('id参数不能为空!');
if (!name) throw new Error('团队名称不能为空!');
if (!code) throw new Error('团队编码不能为空!');
const result = await this.ctx.service.team.handle({ type, name, code, status, _id });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const status = query.status || 1;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.team.setStatus({ _id, status });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.team.delete(_id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = LogsController;
================================================
FILE: app/controller/api/qiniu.js
================================================
'use strict';
const Controller = require('egg').Controller;
class QiniuController extends Controller {
async getToken() {
const { ctx } = this;
const result = await ctx.service.qiniu.getToken();
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = QiniuController;
================================================
FILE: app/controller/api/team.js
================================================
'use strict';
const Controller = require('egg').Controller;
class TeamController extends Controller {
async list() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo || 1;
const pageSize = query.pageSize || this.app.config.pageSize;
const status = query.status;
const result = await this.ctx.service.team.list(pageNo, pageSize, status);
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const name = query.name;
const code = query.code;
const _id = query._id;
if (type === 2 && !_id) throw new Error('id参数不能为空!');
if (!name) throw new Error('团队名称不能为空!');
if (!code) throw new Error('团队编码不能为空!');
const result = await this.ctx.service.team.handle({ type, name, code, status, _id });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const status = query.status || 1;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.team.setStatus({ _id, status });
ctx.body = this.app.result({
data: result,
});
}
// 删除
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.team.delete(_id);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = TeamController;
================================================
FILE: app/controller/api/user.js
================================================
'use strict';
const Controller = require('egg').Controller;
class UserController extends Controller {
// 用户登录
async login() {
const { ctx } = this;
const query = ctx.request.body;
const userName = query.userName;
const passWord = query.passWord;
if (!userName) throw new Error('用户登录:userName不能为空');
if (!passWord) throw new Error('用户登录:passWord不能为空');
const result = await ctx.service.user.login(userName, passWord);
ctx.body = this.app.result({
data: result,
});
}
// 用户注册
async register() {
const { ctx } = this;
const query = ctx.request.body;
const userName = query.userName;
const passWord = query.passWord;
if (!userName) throw new Error('用户登录:userName不能为空');
if (!passWord) throw new Error('用户登录:passWord不能为空');
const result = await ctx.service.user.register(userName, passWord);
ctx.body = this.app.result({
data: result,
});
}
// 退出登录
async logout() {
const { ctx } = this;
const usertoken = ctx.cookies.get('usertoken', {
encrypt: true,
signed: true,
}) || '';
if (!usertoken) throw new Error('退出登录:token不能为空');
await ctx.service.user.logout(usertoken);
this.ctx.body = this.app.result({
data: {},
});
}
// 获得用户列表
async getUserList() {
const { ctx } = this;
const query = ctx.request.query;
const pageNo = query.pageNo;
const pageSize = query.pageSize || this.app.config.pageSize;
const username = query.username;
const result = await ctx.service.user.getUserList(pageNo, pageSize, username);
ctx.body = this.app.result({
data: result,
});
}
// add | update
async handle() {
const { ctx } = this;
const query = ctx.request.body;
let type = query.type || 1;
type = type * 1;
let status = query.status || 1;
status = status * 1;
const user_name = query.user_name;
const pass_word = query.pass_word;
const _id = query._id;
if ((type === 2 || type === 3) && !_id) throw new Error('id参数不能为空!');
if (type === 1 && !user_name) throw new Error('用户名称不能为空!');
if ((type === 1 || type === 3) && !pass_word) throw new Error('密码不能为空!');
const result = await this.ctx.service.user.handle({ type, user_name, pass_word, status, _id });
ctx.body = this.app.result({
data: result,
});
}
// 禁用 | 启用
async setStatus() {
const { ctx } = this;
const query = ctx.request.body;
const _id = query._id;
const status = query.status || 1;
const usertoken = query.usertoken || '';
if (!_id) throw new Error('id参数不能为空!');
const result = await this.ctx.service.user.setStatus({ _id, status, usertoken });
ctx.body = this.app.result({
data: result,
});
}
// 删除用户
async delete() {
const { ctx } = this;
const query = ctx.request.body;
const id = query.id || '';
const usertoken = query.usertoken || '';
if (!id) throw new Error('id不能为空');
const result = await ctx.service.user.delete(id, usertoken);
ctx.body = this.app.result({
data: result,
});
}
async setToken() {
this.ctx.body = this.app.result({
data: 'success',
});
}
}
module.exports = UserController;
================================================
FILE: app/controller/api/util.js
================================================
'use strict';
const Controller = require('egg').Controller;
class UtilController extends Controller {
// 获得服务器ssh key
async getAssetSshKey() {
const { ctx } = this;
const query = ctx.request.body;
const { host, port, username, password } = query;
if (!host) throw new Error('资产host不能为空!');
if (!port) throw new Error('资产port不能为空!');
if (!username) throw new Error('资产username不能为空!');
if (!password) throw new Error('资产password不能为空!');
const result = await this.ctx.service.util.getAssetSshKey(query);
ctx.body = this.app.result({
data: result,
});
}
// 执行shell任务
async handleShellTasks() {
const { ctx } = this;
const query = ctx.request.body;
const { host, port, username, password, shell_type, shell_body, shell_path } = query;
if (!host) throw new Error('资产host不能为空!');
if (!port) throw new Error('资产port不能为空!');
if (!username) throw new Error('资产username不能为空!');
if (!password) throw new Error('资产password不能为空!');
if (!shell_type) throw new Error('执行脚本的类型不能为空!');
if (!shell_body) throw new Error('执行脚本的内容不能为空!');
if (parseInt(shell_type) === 2 && !shell_path) throw new Error('执行脚本的脚本路径不能为空!');
const result = await this.ctx.service.util.handleShellTasks(query);
ctx.body = this.app.result({
data: result,
});
}
}
module.exports = UtilController;
================================================
FILE: app/controller/home.js
================================================
'use strict';
const Controller = require('egg').Controller;
class HomeController extends Controller {
async index() {
this.ctx.body = 'hi, egg';
}
}
module.exports = HomeController;
================================================
FILE: app/controller/web.js
================================================
'use strict';
// const fs = require('fs');
// const path = require('path');
const Controller = require('egg').Controller;
class WebController extends Controller {
async home() {
const { ctx } = this;
// this.ctx.service.ssh2.shell();
// this.ctx.service.ssh2.exec('bash /data/down/app.sh');
// const result = await this.ctx.service.sftp.list('/data/down');
// console.log(result);
// const result = await this.ctx.service.sftp.get('/data/down/miao.sh');
await ctx.render('home', {
data: {},
});
}
// 团队管理
async team() {
const { ctx } = this;
await ctx.render('team', {
data: {},
});
}
// 应用管理
async application() {
const { ctx } = this;
await ctx.render('application', {
data: {},
});
}
// 构建配置
async appconfig() {
const { ctx } = this;
await ctx.render('appconfig', {
data: {},
});
}
// 应用管理
async assets() {
const { ctx } = this;
await ctx.render('assets', {
data: {},
});
}
// 环境配置
async environment() {
const { ctx } = this;
await ctx.render('environment', {
data: {},
});
}
// 邮件管理
async emails() {
const { ctx } = this;
await ctx.render('email', {
data: {},
});
}
// 应用构建
async build() {
const { ctx } = this;
await ctx.render('build', {
data: {},
});
}
// 开始构建
async buildprocess() {
const { ctx } = this;
await ctx.render('buildprocess', {
data: {},
});
}
// 资产构建
async assetsconfig() {
const { ctx } = this;
await ctx.render('assetsconfig', {
data: {},
});
}
// 脚本任务
async commtask() {
const { ctx } = this;
await ctx.render('commtask', {
data: {},
});
}
// 控制台
async console() {
const { ctx } = this;
await ctx.render('console', {
data: {},
});
}
// 构建日志
async logs() {
const { ctx } = this;
await ctx.render('logs', {
data: {},
});
}
// 构建还原
async reduction() {
const { ctx } = this;
await ctx.render('reduction', {
data: {},
});
}
// 用户管理
async user() {
const { ctx } = this;
await ctx.render('user', {
data: {},
});
}
// 用户登录
async login() {
const { ctx } = this;
await ctx.render('login', {
data: {},
});
}
}
module.exports = WebController;
================================================
FILE: app/extend/application.js
================================================
'use strict';
const md5 = require('md5');
module.exports = {
/* 生成随机字符串 */
randomString(len) {
len = len || 7;
const $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
const maxPos = $chars.length;
let pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd + Date.now();
},
/* 本地加密算法 */
signwx(json) {
const wxkey = 'ZANEWANGWEI123456AGETEAMABmiliH';
/* 对json的key值排序 */
const arr = [];
const sortJson = {};
const newJson = json;
for (const key in json) {
if (json[key]) {
arr.push(key);
}
}
arr.sort((a, b) => {
return a.localeCompare(b);
});
for (let i = 0, len = arr.length; i < len; i++) {
sortJson[arr[i]] = json[arr[i]];
}
/* 拼接json为key=val形式 */
let str = '';
for (const key in sortJson) {
str += key + '=' + sortJson[key] + '&';
}
str += 'key=' + wxkey;
/* md5 */
const md5Str = md5(str);
const signstr = md5Str.toUpperCase();
/* 获得有sign参数的json */
newJson.paySign = signstr;
return newJson;
},
// 返回结果json
result(jn = {}) {
return Object.assign({
code: 1000,
desc: '成功',
data: '',
}, jn);
},
format(date, fmt) {
const o = {
'M+': date.getMonth() + 1, // 月份
'd+': date.getDate(), // 日
'h+': date.getHours(), // 小时
'H+': date.getHours() > 12 ? date.getHours() - 12 : date.getHours(),
'm+': date.getMinutes(), // 分
's+': date.getSeconds(), // 秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (date.getFullYear() + '').substr(4 - RegExp.$1.length));
for (const k in o) {
if (new RegExp('(' + k + ')').test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length === 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)));
}
return fmt;
},
};
================================================
FILE: app/io/controller/nsp.js
================================================
'use strict';
const Controller = require('egg').Controller;
const socket = require('../../util/socket');
class NspController extends Controller {
async socket() {
const { ctx } = this;
const query = ctx.args[0];
const buildType = query.buildType;
switch (buildType) {
case 'buildprocess': case 'buildtasks':
this.buildProcess(query);
break;
case 'sshonline':
this.sshOnline(query);
break;
default:
}
}
// common ssh2 servers
ssh2Client(json = {}) {
const { ctx } = this;
let { data, taskItem, shell, id, cols, rows } = json;
data = data || [];
taskItem = taskItem || {};
const tasklist = [];
const date = new Date();
const { project_path, backups_path, is_backups } = taskItem;
let backupPath = '';
let backupDir = '';
if (taskItem && is_backups && project_path && backups_path) {
backupDir = 'bak_' + this.app.format(new Date(), 'yyyy-MM-dd:hh:mm:ss');
const projectName = project_path ? project_path.split('/').splice(-1).join() : '';
backupPath = `${backups_path}/${backupDir}/${projectName}`;
}
for (let i = 0; i < data.length; i++) {
const datas = data[i] || {};
const assitsItem = datas.assitsItem || {};
const item = Promise.resolve(
this.backUpProject(taskItem, assitsItem, backupPath, backupDir).then(data => {
socket({
id,
date,
taskName: taskItem.task_name ? `${taskItem.task_name}任务-构建应用服务` : '',
assetsName: assitsItem.name,
lanip: assitsItem.lan_ip,
host: assitsItem.outer_ip,
port: assitsItem.port,
username: assitsItem.user,
password: assitsItem.password,
cols: cols || 138,
rows: rows || 46,
term: 'xterm-color',
taskType: taskItem.task_type || 'command',
socket: {
socket: ctx.socket,
geometry: datas.geometry,
close: datas.close,
data: datas.data,
end: datas.end,
resize: datas.resize,
},
initialTask: shell,
});
return data;
})
);
tasklist.push(item);
}
return Promise.all(tasklist);
}
// 构建task
async sshOnline(query = {}) {
if (!query.data) return;
const { data, cols, rows } = query;
this.ssh2Client({ data, cols, rows });
}
// 应用构建
async buildProcess(query = {}) {
if (!query.data) return;
const { taskItem, data, id, user_name } = query;
let shell = '';
if (taskItem && taskItem.shell_path) {
shell = taskItem.shell_path ?
`sh ${taskItem.shell_path} ${taskItem.shell_opction || ''} \n` :
taskItem.shell_body + '\n';
} else if (taskItem && taskItem.shell_body) {
shell = taskItem.shell_body + '\n';
}
const result = await this.ssh2Client({ data, taskItem, shell, id });
// 保存备份日志
taskItem.is_backups && this.ctx.service.logs.addLogs({
name: `${taskItem.task_name}任务-服务备份`,
type: 2,
user_name,
application_id: id,
content: result || [],
});
}
// 备份
backUpProject(taskItem = {}, assitsItem = {}, backupPath, backupDir) {
const { is_backups, project_path, backups_path } = taskItem;
let promise = null;
if (taskItem && is_backups && project_path && backups_path) {
promise = this.ctx.service.build.backUpProject(taskItem, assitsItem, backupPath, backupDir);
} else {
promise = new Promise(resolve => { resolve(1); });
}
return promise;
}
}
module.exports = NspController;
================================================
FILE: app/io/middleware/auth.js
================================================
'use strict';
module.exports = () => {
return async (ctx, next) => {
// ctx.socket.emit('response', 'connected!');
await next();
};
};
================================================
FILE: app/middleware/token_required.js
================================================
'use strict';
const { URL } = require('url');
// 校验用户是否登录
module.exports = () => {
return async (ctx, next) => {
const referer = ctx.request.header.referer || '';
const url = new URL(referer);
if (ctx.app.config.origin && ctx.app.config.origin.indexOf(url.origin) === -1) {
ctx.body = {
code: 1004,
desc: '域名来源有误,请检查config的origin配置',
};
return;
}
const usertoken = ctx.cookies.get('usertoken', {
encrypt: true,
signed: true,
}) || '';
if (!usertoken) {
ctx.body = {
code: 1004,
desc: '用户未登录,请重新登录',
};
return;
}
const data = await ctx.service.user.finUserForToken(usertoken);
if (!data || !data.user_name) {
ctx.cookies.set('usertoken', '');
const descr = data && !data.user_name ? data.desc : '登录用户无效,请重新登录!';
ctx.body = {
code: 1004,
desc: descr,
};
return;
}
await next();
};
};
================================================
FILE: app/model/application.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const ApplicationSchema = new Schema({
name: { type: String }, // 应用名称
code: { type: String }, // 应用编码
user_name: { type: String }, // 操作人
team_code: { type: String }, // 所属公司编码
environ_code: { type: String }, // 所属环境编码
net_type: { type: Number, default: 1 }, // 网络部署IP说明 1:外网IP 2:内网IP
assets_list: { type: Array }, // 拥有资产列表
task_list: { type: Array }, // 任务list
email_list: { type: Array }, // 绑定邮箱列表
status: { type: Number, default: 1 }, // 可用装填 1:可用 0:禁用
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Application', ApplicationSchema);
};
================================================
FILE: app/model/assets.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const AssetsSchema = new Schema({
name: { type: String }, // 资产名称
code: { type: String }, // 资产编码
user_name: { type: String }, // 操作人
outer_ip: { type: String }, // 外网IP
lan_ip: { type: String }, // 内网IP
user: { type: String }, // 登录用户
port: { type: Number }, // 登录端口号
password: { type: String }, // 登录密码
team_code: { type: String }, // 所属团队编码
status: { type: Number, default: 1 }, // 可用装填 1:可用 0:禁用
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Assets', AssetsSchema);
};
================================================
FILE: app/model/commtask.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const CommtaskSchema = new Schema({
name: { type: String }, // 任务名称
type: { type: Number, default: 1 }, // 任务类型 1:窗口运行命令 2:shell脚本命令
user_name: { type: String }, // 操作人
shell_body: { type: String }, // 运行内容
shell_opction: { type: String }, // shell 参数
shell_path: { type: String }, // shell存放路径
shell_write_type: { type: String }, // 脚本写入服务器方式 1:新建文件并上传方式 2:shell窗口命令行创建方式
btn_color: { type: String, default: 'primary' }, // 按钮颜色 可选类型 :primary|success|info|warning|danger|default
is_plain: { type: Number, default: 2 }, // 是:1 否:2
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Commtask', CommtaskSchema);
};
================================================
FILE: app/model/email.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const TeamSchema = new Schema({
email: { type: String }, // 邮件地址
name: { type: String }, // 邮件所属人员
status: { type: Number, default: 1 }, // 可用装填 1:可用 0:禁用
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Email', TeamSchema);
};
================================================
FILE: app/model/environment.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const EnvironmentSchema = new Schema({
name: { type: String }, // 团队名称
code: { type: String }, // 团队编码
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Environment', EnvironmentSchema);
};
================================================
FILE: app/model/logs.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const LogsSchema = new Schema({
name: { type: String }, // 日志名称
user_name: { type: String }, // 操作人
application_id: { type: String }, // 所属应用code
commtask_id: { type: String }, // 所属脚本任务code
type: { type: Number, default: 1 }, // 日志类型 1:发布服务 2:应用服务备份 3:应用生成构建配置 4:服务资产生成构建配置 5:备份还原记录
delete: { type: Boolean, default: false }, // 是否删除过
content: { type: Object }, // 日志item内容项目
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Logs', LogsSchema);
};
================================================
FILE: app/model/team.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const TeamSchema = new Schema({
name: { type: String }, // 团队名称
code: { type: String }, // 团队编码
status: { type: Number, default: 1 }, // 可用装填 1:可用 0:禁用
create_time: { type: Date, default: Date.now }, // 创建时间
});
return mongoose.model('Team', TeamSchema);
};
================================================
FILE: app/model/user.js
================================================
'use strict';
module.exports = app => {
const mongoose = app.mongoose;
const Schema = mongoose.Schema;
const UserSchema = new Schema({
user_name: { type: String }, // 用户名称
pass_word: { type: String }, // 用户密码
status: { type: Number, default: 1 }, // 可用装填 1:可用 0:禁用
token: { type: String }, // 用户秘钥
usertoken: { type: String }, // 用户登录态秘钥
create_time: { type: Date, default: Date.now }, // 用户访问时间
});
UserSchema.index({ user_name: -1, token: -1 });
return mongoose.model('User', UserSchema);
};
================================================
FILE: app/public/css/base.css
================================================
/*CSS Reset*/
*, *:before, *:after { -webkit-box-sizing: border-box; box-sizing: border-box; }
/*设置字体*/
@font-face{font-family: OpenSans;src: url('../font/OpenSans-Regular.ttf'),}
body{background: #f9fafb;font-family: 'OpenSans', sans-serif!important;}
/*字体结束*/
body, div, dl, dt, dd, ul, ol, li, h1, h2, h3, h4, h5, h6, pre, code, form, fieldset, legend, input, textarea, p, blockquote, th, td, header, hgroup, nav, section, article, aside, footer, figure, figcaption, menu, button {
margin: 0; padding: 0;};
body { line-height: 1.5; font-size: 14px; color: #70727C; -webkit-text-size-adjust: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0); outline: 0; }
h1, h2, h3, h4, h5, h6 { font-size: inherit; font-weight: normal; }
table { border-collapse: collapse; border-spacing: 0; }
fieldset, img { border: 0; }
li { list-style: none; }
input, textarea, select { font-family: inherit; font-size: inherit; font-weight: inherit; outline: none; -webkit-appearence: none; -ms-appearence: none; }
button, html input[type="button"], input[type="reset"], input[type="submit"] { border: none; background: none; -webkit-appearance: none; outline: none; }
a { -webkit-touch-callout: none; text-decoration: none; outline: 0; color:#8776f7;text-decoration:none;}
em, i { font-style: normal; }
iframe { display: none; }
[v-cloak] {display: none; }
.mt10{margin-top:10px;}
.mt15{margin-top:15px;}
.mt20{margin-top:20px;}
.mt30{margin-top:30px;}
.mt50{margin-top:50px;}
.mt90{margin-top:90px;}
.mt200{margin-top:200px!important;}
.mb10{margin-bottom:10px;}
.mb20{margin-bottom:20px;}
.mb30{margin-bottom:30px;}
.mb50{margin-bottom:50px;}
.mb100{margin-bottom:100px;}
.mb200{margin-bottom:200px;}
.ml10{margin-left:10px;}
.ml20{margin-left:20px;}
.ml30{margin-left:30px;}
.ml50{margin-left:50px;}
.ml100{margin-left:100px;}
.mr5{margin-right:5px;}
.mr10{margin-right:10px;}
.mr20{margin-right:20px;}
.pb100{padding-bottom:100px;}
.pdl20{padding-left:20px!important;}
.lightcolor{color:#999;}
.primary{color:#409eff;}
.success{color:#67c23a;}
.warning{color:#e6a23c;}
.tipscolor{color:#e15f63;font-size:14px;}
.light{color:#999;font-size:12px;}
.red{color:red!important;}
.tc{text-align:center;}
.bold{font-weight:bold;}
.fs-12{font-size:12px;}
.fs-14{font-size:14px;}
.fs-16{font-size:16px;}
.fs-18{font-size:18px;}
.fs-22{font-size:22px;}
.fl{float:left;}
.fr{float:right;}
.w-50{width:50px!important;}
.w-80{width:80px!important;}
.w-100{width:100px!important;}
.w-150{width:150px!important;}
.w-200{width:200px!important;}
.w-300{width:300px!important;}
.w-500{width:500px!important;}
.common-width{
width:1200px;
margin:0 auto;
}
/* 等待加载样式 */
#loading{
display:none;
background: url(/public/img/loading.gif) rgba(12,12,12,.2) no-repeat center center;
position: fixed;
width: 100%;
height: 100%;
top:0;
left:0;
z-index:10000;
}
/****阿里icon*****/
@font-face {
font-family: 'iconfont'; /* project id 769227 */
src: url('//at.alicdn.com/t/font_769227_f7de0h0gpza.eot');
src: url('//at.alicdn.com/t/font_769227_f7de0h0gpza.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_769227_f7de0h0gpza.woff2') format('woff2'),
url('//at.alicdn.com/t/font_769227_f7de0h0gpza.woff') format('woff'),
url('//at.alicdn.com/t/font_769227_f7de0h0gpza.ttf') format('truetype'),
url('//at.alicdn.com/t/font_769227_f7de0h0gpza.svg#iconfont') format('svg');
}
.iconfont {
font-family:"iconfont";
font-size:16px;
font-style:normal;
vertical-align: middle;
}
/* body content widht */
#body_content{
overflow-y: auto;
font-size:14px;
margin-left:180px;
padding:50px 0 30px;
}
.content{
padding:20px;
}
.com_title{
font-size:30px;
font-weight: 300;
}
/* common table block */
.com_table_block{
overflow:hidden;
background:#fff;
box-shadow: 5px 5px 10px #eee
}
.com_table_block .table_header{
height:50px;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding:20px;
border-bottom:solid 1px #eee;
}
.com_table_block .l{
font-size:15px;
}
.common_pages{
display: flex;
flex-direction: row;
justify-content: center;
padding:20px 0 30px;
}
.com_model_main{
overflow:hidden;
padding:0 10px;
}
.com_model_block{
display: flex;
flex-direction: row;
align-items: center;
margin-bottom:20px;
min-height:40px;
}
.com_model_block .left{
width:100px;
}
.com_model_block .inp{
width:250px;
}
.com_model_main .btns{
margin-top:30px;
display: flex;
flex-direction: row;
justify-content: center;
}
.com_top{
background: #fff;
padding:20px;
margin:20px 0;
box-shadow: 5px 5px 10px #eee
}
.com_top .inp{
width:250px;
}
.common_tops{
font-size:12px;
color:#999;
}
.common_tops .el-icon-warning{
color:#409eff;
margin-right:6px;
}
/* 公共输入框 */
.text_comm_tarea{
width:100%;
height:300px;
background:#000;
padding:20px;
border:solid 1px #000;
color:#fff;
font-size:16px;
}
/*滚动条样式*/
.text_comm_tarea::-webkit-scrollbar {
width: 4px;
height: 4px;
}
.text_comm_tarea::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.6);
}
.text_comm_tarea::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,.1);
}
/* build model */
.comm_shell_model{}
.comm_shell_model .mask {
position: fixed;
left:0;
top:0;
width:100%;
height:100%;
background: rgba(0,0,0,.1);
z-index:3000;
}
.comm_shell_model .comm_shell_model_content{
position: fixed;
left:0;
top:0;
width:calc(70%);
height: calc(80%);
margin-left:calc(15%);
margin-top:calc(5%);
background:#000;
border-radius:3px;
overflow:hidden;
z-index:3002;
}
.comm_shell_model .close{
position: absolute;
right:10px;
top:3px;
font-size:20px;
cursor:pointer;
color:#c7c7c7;
z-index:3001;
}
.comm_shell_model .menu{
right:150px;
}
.comm_shell_model .plus{
right:100px;
}
.comm_shell_model .minus{
right:50px;
}
.comm_shell_model .comm_shell_navs{
position: absolute;
left:0;
top:0;
width:100%;
background:#383838;
display: flex;
flex-direction: row;
align-items: center;
height:25px;
z-index:110;
}
.comm_shell_model .comm_shell_navs .item{
display: flex;
flex-direction: row;
align-items: center;
border-right:solid 1px #aaa;
white-space: nowrap;
padding:0 10px;
height:100%;
font-size:12px;
font-weight:300;
cursor:pointer;
}
.comm_shell_model .comm_shell_navs .active{
color:#000;
background:#e0e0e0;
}
.comm_shell_model .terminal{
position: absolute;
left:8px;
top:10px;
width:calc(100% - 30px);
height:calc(100% - 60px);
z-index:1;
}
.comm_shell_model .comm_content_body{
display: flex;
flex-direction: row;
flex-wrap: wrap;
overflow:auto;
padding: 10px;
height:calc(95%);
overflow:auto;
margin-top:20px;
}
.comm_shell_model .comm_content_body::-webkit-scrollbar {
width: 4px;
height: 4px;
}
.comm_shell_model .comm_content_body::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
background: rgba(0,0,0,0.6);
}
.comm_shell_model .comm_content_body::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 5px rgba(0,0,0,0.2);
border-radius: 0;
background: rgba(0,0,0,.1);
}
.comm_shell_model .com_content_list{
background:#000;
}
.xterm.fullscreen {
position: fixed!important;
top: 0!important;
bottom: 0!important;
left: 0!important;
right: 0!important;
width: auto!important;
height: auto!important;
z-index: 255!important;
padding:10px!important;
}
/* element-ui-common */
.el-button{
padding: 9px 20px!important;
border-radius: 0px!important;
}
.el-table td, .el-table th {
padding: 8px 0!important;
}
.el-button--medium {
padding: 8px 10px!important;
font-size:12px!important;
}
.el-button--small, .el-button--small.is-round {
padding: 6px 10px!important;
}
.el-input__inner {
height: 35px!important;
line-height: 35px!important;
border-radius:0px!important;
}
.el-input__icon{
line-height: 35px!important;
}
================================================
FILE: app/public/css/home.css
================================================
================================================
FILE: app/public/iconfont/iconfont.css
================================================
@font-face {font-family: "iconfont";
src: url('iconfont.eot?t=1551324590500'); /* IE9 */
src: url('iconfont.eot?t=1551324590500#iefix') format('embedded-opentype'), /* IE6-IE8 */
url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAMEAAsAAAAABtgAAAK4AAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEIGVgCCcAqBZIFrATYCJAMICwYABCAFhG0HLxsQBhHVk6NkPwvsZuoVJmhyDRpllUYjUD422PchiFCXzUrri0JYJU+Msv2AXAFw/TUhV8BlOtrcrLpGRSiW5Dz4X56Rjk0IS31baHSmCoCLQ9VMoIDMB0mc5tyUC2A4QAEca9FoC1ZvQQrgHcYueIH7IUAKFaiHdBv6eRyKPUwAmWWnjscVHCjKwg4h0TBXkZ0EOLPJPBawI/p9+SuaiANDYLGzBk3pPolOPwqcKLuyfCWjAgTM5XQAWwQWqAcoiG8MDMAiDGdJoVSqAIq6f1BeHqiQo/7zkAR2ahoAhZDxTEyP9ahFBgDl2UNdgGUYq18QpKVluLzxb39E737Gb76Hr7+teP3av3kTvnsXv327PIrbdpC49YTeh2NSojFMLZw1LZJISmoowjiK4hF9h/swLP9/UKikHxwZVPI5WVb64UtXtKREIfcKpUEO/iZ6asjWbb3Kuhwa/2LquSNxxTAcUa/FdZr/YuO/2oVPrut8sX3bicV37o6eMXBxpy17505cvqzzrKZT9vaZfnxE9qlJ9cPtM5r1PXjqP0Pg3DMfjc1sV+xSFYD3nUejAeUrFbsScHdiFPijzIENarBtpVGN2RgxdCG407IUUoBysCWHr1Ml+bevE1yBycCQRBFYHNWQiq0HAak0gwSOjpBCXXouTiWXBVhEk4E6rAMgZHEMDBlcA0sWT5CK/QIBBfyHBFliIYVIctdMpYZgVnYlnBhXmB+wS07KVbOM01+ojzBRnh3hf0i7dUNbNeXwiAlpiQn7qTtmBYpyhAEchiFkKJQdLlwZ5tLXtWp6UrXkKCRdCSfGFeYH7JKTClqzrPz8C/URJuqoq1P/kHbbObRVMwA5CtKgukd5ZD91x6xAUY4wgF4YQobS3MvhwpWZ4Ct97TRTQwXV9qL4d9uAFGypEaeLJZhkN3sIAQ==') format('woff2'),
url('iconfont.woff?t=1551324590500') format('woff'),
url('iconfont.ttf?t=1551324590500') format('truetype'), /* chrome, firefox, opera, Safari, Android, iOS 4.2+ */
url('iconfont.svg?t=1551324590500#iconfont') format('svg'); /* iOS 4.1- */
}
.iconfont {
font-family: "iconfont" !important;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.icon-diqiu:before {
content: "\e616";
}
================================================
FILE: app/public/js/config.js
================================================
'use strict';
const config = {
// 登陆页面
loginUrl: '/login',
// 登陆成功后需要跳转到的页面
homeUrl: '/',
// 根接口
baseApi: '/',
// ajax 请求超时时间
ajaxtimeout: 15000,
// 发送验证码时间间隔
msgTime: 60,
// 七牛图片根地址
imgBaseUrl: 'http://ormfcl92t.bkt.clouddn.com/',
// 隐藏显示时间
containerShowTime: 10,
// pagesize 分页数量
pageSize: 50,
};
window.config = config; // eslint-disable-line
window.baseUrl = ""//"http://test-pc.juxingyi.com"
================================================
FILE: app/public/js/util.js
================================================
/* eslint-disable */
'use strict';
// 时间格式化
if (!new Date().format) {
Date.prototype.format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"H+": this.getHours() > 12 ? this.getHours() - 12 : this.getHours(),
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
};
let XTEAMLIST = [];
let MODELTYPE = '';
let SOCKET = null;
let CONSOLEXTEAM = [];
// util 公共对象函数
class utilfn {
// 初始化对象
constructor() {
this.win = window.top;
this.UA = navigator.userAgent;
this.isPC = this.UA.indexOf('Windows NT') > -1;
this.isAndroid = this.UA.indexOf('Android') > -1;
this.isIos = this.UA.indexOf('Mac OS X') > -1;
this.isIphone = this.UA.indexOf('iPhone;') > -1;
this.isIpad = this.UA.indexOf('iPad;') > -1;
this.isIE7 = this.UA.indexOf('MSIE 7.0;') > -1;
this.isIE8 = this.UA.indexOf('MSIE 8.0;') > -1;
this.isIE9 = this.UA.indexOf('MSIE 9.0;') > -1;
this.isIE10 = this.UA.indexOf('MSIE 10.0;') > -1;
this.isIE11 = this.UA.indexOf('Trident') > -1;
};
/*封装的ajax函数
*type 类型 get|post
*url api地址
*data 请求的json数据
*noLoading ajax执行时是否显示遮罩
*nohideloading ajax执行完成之后是否隐藏遮罩
*notimeout 是否有请求超时
*complete ajax完成后执行(失败成功后都会执行)
*beforeSend 请求发送前执行
*success 成功之后执行
*error 失败之后执行
*goingError 是否执行自定义error回调
*timeout ajax超时时间
*isGoingLogin 是否跳转到登录界面
*/
ajax(json) {
let This = this;
let noError = true;
let url = null;
let asyncVal = typeof(json.async) == 'boolean' ? json.async : true;
if (!json.nohideloading) {
This.showLoading();
};
//是否有请求超时
if (!json.notimeout) {
var timeout = setTimeout(function() {
This.hideLoading();
// 请求超时
noError = false;
asyncVal && popup.alert({
type: 'msg',
title: '您的网络太慢了哦,请刷新重试!'
});
}, json.timeout || config.ajaxtimeout);
}
// 增加时间戳参数
if (json.url.indexOf('?') != -1) {
url = json.url + '&_=' + this.time();
} else {
url = json.url + '?_=' + this.time();
};
return $.ajax({
type: json.type || "post",
url: url,
data: json.data || "",
dataType: "json",
async: asyncVal,
beforeSend: function(xhr) {
xhr.setRequestHeader("x-csrf-token", $.cookie('csrfToken')||'');
json.beforeSend && json.beforeSend(xhr);
},
success: function(data) {
if (!json.nohideloading) {
This.hideLoading();
};
clearTimeout(timeout);
if (typeof(data) == 'string') {
This.error(JSON.parse(data), json);
} else {
This.error(data, json);
}
},
complete: function(XMLHttpRequest) {
if (!json.nohideloading) {
This.hideLoading();
};
clearTimeout(timeout);
if (json.complete) {
json.complete(XMLHttpRequest);
}
},
error: function(XMLHttpRequest) {
This.hideLoading();
clearTimeout(timeout);
if (noError) {
This._error(XMLHttpRequest, json);
};
}
});
};
//error 处理函数
error(data, json) {
//判断code 并处理
var dataCode = parseInt(data.code);
if (!json.isGoingLogin && dataCode == 1004) {
// 判断app或者web
if (window.location.href.indexOf(config.loginUrl) == -1) {
$('#main').html('');
function login(){
sessionStorage.setItem("weixin-url", window.location.href); //记录没有登陆前的访问页面
location.href = config.loginUrl + '?redirecturl=' + encodeURIComponent(location.href);
}
popup.confirm({ maskHide: false, title: data.desc || '登录失败,请重新登录!', yes: () => { login() }, no: () => { login() } });
} else {
popup.alert({
type: 'msg',
title: '用户未登陆,请登录!'
});
}
} else {
switch (dataCode) {
case 1000:
json.success && json.success(data);
break;
default:
if (json.goingError) {
//走error回调
json.error && json.error(data);
} else {
//直接弹出错误信息
popup.alert({
type: 'msg',
title: data.desc
});
};
}
};
}
// _error 处理函数
_error(XMLHttpRequest, json) {
this.hideLoading();
if (json.code) {
json.error(JSON.parse(XMLHttpRequest.responseText));
} else {
switch (XMLHttpRequest.status) {
case 401:
if (window.location.href.indexOf(config.loginUrl) == -1) {
sessionStorage.setItem("weixin-url", window.location.href); //记录没有登陆前的访问页面
window.location.href = config.loginUrl;
} else {
popup.alert({
type: 'msg',
title: "你需要登录哦"
});
};
break;
case 400:
popup.alert({
type: 'msg',
title: "您的请求不合法呢"
});
break;
case 404:
popup.alert({
type: 'msg',
title: "访问的地址可能不存在哦"
});
break;
case 500:
case 502:
popup.alert({
type: 'msg',
title: "服务器内部错误"
});
break;
// default:
// popup.alert({type:'msg',title:"未知错误。程序员欧巴正在赶来修改哦"});
}
}
}
// 获取当前时间毫秒
time() {
return new Date().getTime();
}
/*根据参数生成常用的正则表达式
*string type 生成的正则表达式类型
*array numArr 生成正则的条件数组 例如:[6,16] 也可省略
*/
regCombination(type, numArr) {
var reg = "";
switch (type) {
case "*": //"*":"不能为空!"
if (numArr) {
reg = new RegExp("^[\\w\\W]{" + numArr[0] + "," + numArr[1] + "}$");
} else {
reg = new RegExp("^[\\w\\W]+$");
}
break;
case "n": //"number":"请填写数字!
if (numArr) {
reg = new RegExp("^\\d{" + numArr[0] + "," + numArr[1] + "}$");
} else {
reg = new RegExp("^\\d+$");
}
break;
case "s": //"s":"不能输入特殊字符!"
if (numArr) {
reg = new RegExp("^[\\u4E00-\\u9FA5\\uf900-\\ufa2d\\w\\.\\s]{" + numArr[0] + "," + numArr[1] + "}$");
} else {
reg = new RegExp("^[\\u4E00-\\u9FA5\\uf900-\\ufa2d\\w\\.\\s]+$");
}
break;
case "c": //"z":"中文验证"
reg = new RegExp("^[\\u4E00-\\u9FA5\\uf900-\\ufa2d]{" + numArr[0] + "," + numArr[1] + "}$");
break;
case "p": //"p":"邮政编码!
reg = new RegExp("^[0-9]{6}$");
break;
case "m": //"m":"写手机号码!"
reg = new RegExp("^13[0-9]{9}$|14[0-9]{9}$|15[0-9]{9}$|17[0-9]{9}$|18[0-9]{9}$");
break;
case "e": //"e":"邮箱地址格式
reg = new RegExp("^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
break;
case "id": //"id":验证身份证
reg = new RegExp("^\\d{17}[\\dXx]|\\d{14}[\\dXx]$");
break;
case "money": //钱
reg = new RegExp("^[\\d\\.]+$");
break;
case "url": //"url":"网址"
reg = new RegExp("^(\\w+:\\/\\/)?\\w+(\\.\\w+)+.*$");
break;
case "u": //
reg = new RegExp("^[A-Z\\d]+$");
break;
case "numLimitTo2": //保留2位小数点正整数
reg = new RegExp("^-{0,0}\\d+(.\\d{0,2})?$");
break;
case "spec": //校验特殊字符
reg = new RegExp("[`~!@#$^&*()=|{}':;',\\[\\].<>/?~!@#¥……&*()——|{}【】‘;:”“'。,、?%+_]");
break;
}
return reg;
}
/*extent json函数
*json1 原始数据
*json2 新数据
*/
extend(json1, json2) {
var newJson = json1;
for (var j in json2) {
newJson[j] = json2[j];
}
return newJson;
}
//showLoading
showLoading() {
$('#loading').stop().show();
}
//hideLoading
hideLoading() {
$('#loading').stop().hide();
}
/*生成随机字符串*/
randomString(len) {
len = len || 15;
var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';
var maxPos = $chars.length;
var pwd = '';
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos));
}
return pwd;
}
/*获取url hash*/
getQueryString(name, hash) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
if (hash) {
if (!window.location.hash) {
return '';
};
var r = decodeURIComponent(window.location.hash).substr(1).match(reg);
} else {
var r = decodeURIComponent(window.location.search).substr(1).match(reg);
}
if (r != null) {
return r[2];
}
return null;
}
/*获取 storage 缓存数据
* type 类型 local:localStorage session:sessionStorage
* name 缓存数据name名
*/
getStorage(type, name) {
var type = type || 'local';
if (type == 'local') {
var result = localStorage.getItem(name) ? localStorage.getItem(name) : "";
} else if (type == 'session') {
var result = sessionStorage.getItem(name) ? sessionStorage.getItem(name) : "";
}
return result;
}
/*设置 storage 缓存数据
*type 类型 local:localStorage session:sessionStorage
*name 缓存数据name名
*content 缓存的数据内容
*/
setStorage(type, name, content) {
var type = type || 'local';
var data = content;
if (typeof(data) == 'object') {
data = JSON.stringify(content)
};
if (type == 'local') {
localStorage.setItem(name, data);
} else if (type == 'session') {
sessionStorage.setItem(name, data);
}
}
/*vue获得checkbox的值*/
getCheckBoxVal(arr){
let result=""
if(!arr.length) return result;
arr.forEach((item)=>{
if(item.checked){
result+=item.value+','
}
})
return result.slice(0,-1);
}
/*vue转换checkbox的值*/
setCheckBoxVal(arr,str){
let copyarr = arr;
if(!str) return copyarr;
let newArr=str.split(',')
copyarr.forEach((itemp)=>{
newArr.forEach((item)=>{
if(itemp.value == item){
itemp.checked=true;
}
})
})
return copyarr;
}
goBack(){
window.history.go(-1);
}
// 获得查询时间
getSearchTime() {
let json = {
beginTime: '',
endTime: ''
}
let selecttimes = util.getStorage('local', 'userselectTime') || 60000
selecttimes = selecttimes * 1
if (selecttimes) {
let endTime = new Date().getTime()
let beginTime = endTime - selecttimes
json.beginTime = new Date(beginTime).format('yyyy/MM/dd hh:mm:ss')
json.endTime = new Date(endTime).format('yyyy/MM/dd hh:mm:ss')
}
return json
}
// 应用构建socket、xtram
startSocketXteam(json = {}) {
const assetsList = json.assetsList || [];
const taskItem = json.taskItem || {};
const buildType = json.buildType || '';
const startType = json.startType || 'new';
if (!Array.isArray(assetsList) && !assetsList.length) return;
const buildLogs = {}
const result = [];
if (startType === 'switch') {
for (let i = 0; i < XTEAMLIST.length; i++) { XTEAMLIST[i] && XTEAMLIST[i].destroy() }
XTEAMLIST = [];
} else if (startType === 'agein') {
return {
xteamList: XTEAMLIST,
socket: SOCKET,
};
} else if (startType === 'new') {
XTEAMLIST = [];
}
// socket
const socket = SOCKET = io.connect('/');
Terminal.applyAddon(fit);
Terminal.applyAddon(fullscreen);
Terminal.applyAddon(attach);
// list
assetsList.forEach((item, index) => {
// 先执行 xteam
let xteam = new Terminal({
cursorBlink:true,
fontSize:14,
fontFamily: '"Monaco", "Consolas", "monospace"',
});
xteam.open(document.getElementById('terminal'+index));
xteam.focus()
xteam.fit()
xteam.attach(socket)
const data = 'process_data_' + index;
const resize = 'process_resize_' + index;
const end = 'process_end_' + index;
const close = 'process_close_' + index;
xteam.on('data', function (res) {
socket.emit(data, res)
})
// socket
socket.on(data, function (res) {
xteam.write(res);
});
// end
socket.on(end, function (res) {
json.callback && json.callback(res)
});
XTEAMLIST.push(xteam);
result.push({
assitsItem:{
name: item.name,
lan_ip: item.lan_ip,
outer_ip: item.outer_ip,
port: item.port,
user: item.user,
password: item.password,
},
data, resize, close, end
})
})
const userMsg = util.getStorage('local', 'userMsg');
const user_name = userMsg ? JSON.parse(userMsg).user_name : '';
socket.emit('socket', {
taskItem,
data: result, buildType,
id: json.id || '',
user_name,
cols: XTEAMLIST[0].cols,
rows: XTEAMLIST[0].rows} || 'begin'
);
window.addEventListener('resize', this.resizeScreen.bind(this, XTEAMLIST, socket), false)
socket.on('close', msg => { close(msg); });
socket.on('disconnect', msg => { close(msg); });
socket.on('disconnecting', () => { close(); });
socket.on('error', (err) => { close(err); });
function close(msg){
XTEAMLIST.forEach(item => {
item.write(msg || '服务器close,请刷新重试。');
})
}
return {
xteamList: XTEAMLIST,
socket,
};
// xteam.clear() xteam.reset() xteam.destroy()
}
resizeScreen(XTEAMLIST, socket) {
for (let i = 0; i < XTEAMLIST.length; i++) { XTEAMLIST[i] && XTEAMLIST[i].fit() }
socket.emit('resize', { cols: XTEAMLIST[0].cols, rows: XTEAMLIST[0].rows })
}
// 设置xteam窗口大小
setSocketXteam(type, xteamlist = [], socket) {
if (MODELTYPE === type) return;
MODELTYPE = type;
const comm_mocel = document.querySelector('.comm_shell_model_content');
const terminal_item = document.querySelectorAll('.terminal');
const content_list = document.querySelectorAll('.com_content_list');
if(type === 1){
// 放大
comm_mocel.style.width = 'calc(100% - 30px)'
comm_mocel.style.height = 'calc(100% - 20px)'
comm_mocel.style.marginLeft = '15px'
comm_mocel.style.marginTop = '10px'
}else if(type === 2){
// 缩小
comm_mocel.style.width = 'calc(70%)'
comm_mocel.style.height = 'calc(80%)'
comm_mocel.style.marginLeft = 'calc(15%)'
comm_mocel.style.marginTop = 'calc(5%)'
} else if (type === 3){
for (let i = 0; i < terminal_item.length;i++) {
terminal_item[i].style.top = '0'
}
for (let i = 0; i < content_list.length; i++) {
content_list[i].style.marginTop = '10px'
content_list[i].style.position = 'relative'
content_list[i].style.width = 'calc(49%)'
if (i % 2 === 0) content_list[i].style.marginRight = '2%'
content_list[i].style.height = '500px'
}
comm_mocel.style.background = '#3e3e3e'
comm_mocel.style.overflow = 'auto'
} else if (type === 4) {
for (let i = 0; i < terminal_item.length; i++) {
terminal_item[i].style.top = '10px'
}
for (let i = 0; i < content_list.length; i++) {
content_list[i].style.position = 'static'
}
comm_mocel.style.background = '#000'
comm_mocel.style.overflow = 'hidden'
}
setTimeout(()=>{
this.resizeScreen(xteamlist, socket)
})
}
/* socket.io实现
* fn 信息回调触发
* query socket 参数
*/
socket(json = {}) {
const socket = io.connect('/');
socket.on('close', msg => { close() });
socket.on('disconnect', msg => { close() });
socket.on('disconnecting', () => { close() });
socket.on('error', (err) => { close() });
function close(msg){
CONSOLEXTEAM.forEach(item => {
item.write(msg || '服务器close.');
})
}
return socket;
}
/* xteam 实现
* id
*/
xteam(json = {}){
const { socket, index, assetsItem} = json;
const result = [];
const data = 'console_data_' + index;
const resize = 'console_resize_' + index;
const close = 'console_close_' + index;
const end = 'console_end_' + index;
Terminal.applyAddon(fit);
Terminal.applyAddon(fullscreen);
Terminal.applyAddon(attach);
let xteam = new Terminal({
cursorBlink: true,
fontSize: 14,
fontFamily: '"Monaco", "Consolas", "monospace"',
});
xteam.open(document.getElementById('console_terminal_' + index));
xteam.focus()
xteam.fit()
xteam.attach(socket)
xteam.on('data', function (res) {
socket.emit(data, res)
})
xteam.write(`开始连接到 ${assetsItem.user}@${assetsItem.name}-${assetsItem.outer_ip}-${assetsItem.lan_ip}\r\n`)
// socket
socket.on(data, function (res) {
xteam.write(res);
});
result.push({
assitsItem: {
name: assetsItem.name,
lan_ip: assetsItem.lan_ip,
outer_ip: assetsItem.outer_ip,
port: assetsItem.port,
user: assetsItem.user,
password: assetsItem.password,
},
data, resize, close, end
})
socket.emit('socket', { data: result, buildType: 'sshonline', cols: xteam.cols, rows: xteam.rows } || 'begin');
window.addEventListener('resize', this.resizeScreen.bind(this, [xteam], socket), false)
this.resizeScreen([xteam], socket)
CONSOLEXTEAM.push(xteam)
return xteam;
}
}
//初始化util对象
window.util = new utilfn();
================================================
FILE: app/public/js/vue-components.js
================================================
/* eslint-disable */
let Component = {
commonsearch:{
template: `<div class="component_search mr20">
<a href="/selectype"><button class="btn btn-main">+添加应用</button></a>
<div class="select">
<span class="times"><span class="iconfont"></span>{{timeText}}<span class="iconfont"></span></span>
<div class="select-time">
<li data-time="60000" data-text="最近1分钟">1分钟</li>
<li data-time="300000" data-text="最近5分钟">5分钟</li>
<li data-time="600000" data-text="最近10分钟">10分钟</li>
<li data-time="1800000" data-text="最近30分钟">30分钟</li>
<li data-time="3600000" data-text="最近1小时">1小时</li>
<li data-time="21600000" data-text="最近6小时">6小时</li>
<li data-time="43200000" data-text="最近12小时">12小时</li>
<li data-time="86400000" data-text="最近1天">1天</li>
<button @click="timeSure" class="btn">确定</button>
</div>
</div>
</div>`,
props:{
done:{
type:Function,
default:()=>{}
},
},
data:function(){
return{
timeText:'全部'
}
},
mounted(){
let _this=this;
// 添加active样式
let selecttimes = util.getStorage('local', 'userselectTime') || 60000
let objs = $('.select-time li')
for(let i=0,len=objs.length;i<len;i++){
let times = $(objs[i]).attr('data-time')
let text = $(objs[i]).attr('data-text')
if(times == selecttimes){
_this.timeText = text
$(objs[i]).addClass('active')
}
}
// active样式
$('.times').on('click',(e) => {
e.stopPropagation();
$('.select-time').show();
});
$(document).on('click',function(e){
$('.select-time').hide();
});
$('.select-time').click(function(e){
e.stopPropagation();
})
$('.select-time li').on('click',function(e){
$('.select-time li').removeClass('active')
$(this).addClass('active')
let time = $(this).attr('data-time')
let text = $(this).attr('data-text')
_this.timeText = text
util.setStorage('local','userselectTime',time)
})
},
methods:{
timeSure(){
$('.select-time').hide();
this.done&&this.done()
}
},
}
}
for(let n in Component){
Vue.component(n, Component[n])
}
================================================
FILE: app/public/js/vue-filters.js
================================================
/* eslint-disable */
// 时间格式化
if(!new Date().format){
Date.prototype.format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"H+":this.getHours()>12?this.getHours()-12:this.getHours(),
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
};
let Filter = {
// 图片地址过滤器
imgBaseUrl:function(img) {
if (!img) return '../images/index/bg-0.png';
if (img.indexOf('http:') !== -1 || img.indexOf('HTTP:') !== -1 || img.indexOf('https:') !== -1 || img.indexOf('HTTPS:') !== -1) {
return img + '?imageslim';
} else {
return config.imgBaseUrl + img + '?imageslim';
}
},
toFixed(val,type=false){
val = parseFloat(val)
if(type){
val = val/1000
return val>0?val.toFixed(3)+' s':val.toFixed(2);
}else{
return val.toFixed(2)+' ms';
}
},
toSize(val){
val=val*1
if(val>=1024){
return (val/1024).toFixed(2)+' KB'
}else if(val>0){
return val.toFixed(2)+' B'
}else{
return 0
}
},
// 时间过滤器
date(value, gengefu, full) {
if (!value) return;
let ty = gengefu || '-';
if (full) {
return new Date(value).format('yyyy' + ty + 'MM' + ty + 'dd hh:mm:ss');
} else {
return new Date(value).format('yyyy' + ty + 'MM' + ty + 'dd');
};
},
//limitTo过滤器
limitTo(value, num) {
if (!value) return;
var text = "";
if (value.length < num) {
text = value;
} else {
text = value.substring(0, num) + '···';
}
return text;
},
// 应用类型过滤器
systemType(val) {
let result = '';
switch (val) {
case 'web':
result = 'WEB浏览器';
break;
case 'wx':
result = '微信小程序';
break;
}
return result;
},
// 流量单位
flow(val = 0) {
let result = 0;
let value = val;
let index = 0;
while (value >= 1024) {
value = value / 1024
index++;
}
value = value.toFixed(2);
if (index >= 4) {
value = value + 'T'
} else if (index >= 3) {
value = value + 'G'
} else if (index >= 2) {
value = value + 'M'
} else if (index >= 1) {
value = value + 'KB'
} else {
value = value + 'B'
}
return value;
},
}
window.Filter = {};
for(let n in Filter){
window['Filter'][n] = Filter[n];
}
================================================
FILE: app/public/lib/bootstrap/css/bootstrap-theme.css
================================================
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
.btn-default,
.btn-primary,
.btn-success,
.btn-info,
.btn-warning,
.btn-danger {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 1px rgba(0, 0, 0, .075);
}
.btn-default:active,
.btn-primary:active,
.btn-success:active,
.btn-info:active,
.btn-warning:active,
.btn-danger:active,
.btn-default.active,
.btn-primary.active,
.btn-success.active,
.btn-info.active,
.btn-warning.active,
.btn-danger.active {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-default.disabled,
.btn-primary.disabled,
.btn-success.disabled,
.btn-info.disabled,
.btn-warning.disabled,
.btn-danger.disabled,
.btn-default[disabled],
.btn-primary[disabled],
.btn-success[disabled],
.btn-info[disabled],
.btn-warning[disabled],
.btn-danger[disabled],
fieldset[disabled] .btn-default,
fieldset[disabled] .btn-primary,
fieldset[disabled] .btn-success,
fieldset[disabled] .btn-info,
fieldset[disabled] .btn-warning,
fieldset[disabled] .btn-danger {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-default .badge,
.btn-primary .badge,
.btn-success .badge,
.btn-info .badge,
.btn-warning .badge,
.btn-danger .badge {
text-shadow: none;
}
.btn:active,
.btn.active {
background-image: none;
}
.btn-default {
text-shadow: 0 1px 0 #fff;
background-image: -webkit-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -o-linear-gradient(top, #fff 0%, #e0e0e0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#e0e0e0));
background-image: linear-gradient(to bottom, #fff 0%, #e0e0e0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe0e0e0', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #dbdbdb;
border-color: #ccc;
}
.btn-default:hover,
.btn-default:focus {
background-color: #e0e0e0;
background-position: 0 -15px;
}
.btn-default:active,
.btn-default.active {
background-color: #e0e0e0;
border-color: #dbdbdb;
}
.btn-default.disabled,
.btn-default[disabled],
fieldset[disabled] .btn-default,
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus,
.btn-default.disabled:active,
.btn-default[disabled]:active,
fieldset[disabled] .btn-default:active,
.btn-default.disabled.active,
.btn-default[disabled].active,
fieldset[disabled] .btn-default.active {
background-color: #e0e0e0;
background-image: none;
}
.btn-primary {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #265a88 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#265a88));
background-image: linear-gradient(to bottom, #337ab7 0%, #265a88 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff265a88', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #245580;
}
.btn-primary:hover,
.btn-primary:focus {
background-color: #265a88;
background-position: 0 -15px;
}
.btn-primary:active,
.btn-primary.active {
background-color: #265a88;
border-color: #245580;
}
.btn-primary.disabled,
.btn-primary[disabled],
fieldset[disabled] .btn-primary,
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus,
.btn-primary.disabled:active,
.btn-primary[disabled]:active,
fieldset[disabled] .btn-primary:active,
.btn-primary.disabled.active,
.btn-primary[disabled].active,
fieldset[disabled] .btn-primary.active {
background-color: #265a88;
background-image: none;
}
.btn-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #419641 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#419641));
background-image: linear-gradient(to bottom, #5cb85c 0%, #419641 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff419641', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #3e8f3e;
}
.btn-success:hover,
.btn-success:focus {
background-color: #419641;
background-position: 0 -15px;
}
.btn-success:active,
.btn-success.active {
background-color: #419641;
border-color: #3e8f3e;
}
.btn-success.disabled,
.btn-success[disabled],
fieldset[disabled] .btn-success,
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus,
.btn-success.disabled:active,
.btn-success[disabled]:active,
fieldset[disabled] .btn-success:active,
.btn-success.disabled.active,
.btn-success[disabled].active,
fieldset[disabled] .btn-success.active {
background-color: #419641;
background-image: none;
}
.btn-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #2aabd2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#2aabd2));
background-image: linear-gradient(to bottom, #5bc0de 0%, #2aabd2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2aabd2', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #28a4c9;
}
.btn-info:hover,
.btn-info:focus {
background-color: #2aabd2;
background-position: 0 -15px;
}
.btn-info:active,
.btn-info.active {
background-color: #2aabd2;
border-color: #28a4c9;
}
.btn-info.disabled,
.btn-info[disabled],
fieldset[disabled] .btn-info,
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus,
.btn-info.disabled:active,
.btn-info[disabled]:active,
fieldset[disabled] .btn-info:active,
.btn-info.disabled.active,
.btn-info[disabled].active,
fieldset[disabled] .btn-info.active {
background-color: #2aabd2;
background-image: none;
}
.btn-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #eb9316 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#eb9316));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #eb9316 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffeb9316', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #e38d13;
}
.btn-warning:hover,
.btn-warning:focus {
background-color: #eb9316;
background-position: 0 -15px;
}
.btn-warning:active,
.btn-warning.active {
background-color: #eb9316;
border-color: #e38d13;
}
.btn-warning.disabled,
.btn-warning[disabled],
fieldset[disabled] .btn-warning,
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus,
.btn-warning.disabled:active,
.btn-warning[disabled]:active,
fieldset[disabled] .btn-warning:active,
.btn-warning.disabled.active,
.btn-warning[disabled].active,
fieldset[disabled] .btn-warning.active {
background-color: #eb9316;
background-image: none;
}
.btn-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c12e2a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c12e2a));
background-image: linear-gradient(to bottom, #d9534f 0%, #c12e2a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc12e2a', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-color: #b92c28;
}
.btn-danger:hover,
.btn-danger:focus {
background-color: #c12e2a;
background-position: 0 -15px;
}
.btn-danger:active,
.btn-danger.active {
background-color: #c12e2a;
border-color: #b92c28;
}
.btn-danger.disabled,
.btn-danger[disabled],
fieldset[disabled] .btn-danger,
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus,
.btn-danger.disabled:active,
.btn-danger[disabled]:active,
fieldset[disabled] .btn-danger:active,
.btn-danger.disabled.active,
.btn-danger[disabled].active,
fieldset[disabled] .btn-danger.active {
background-color: #c12e2a;
background-image: none;
}
.thumbnail,
.img-thumbnail {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
background-color: #e8e8e8;
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
background-color: #2e6da4;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.navbar-default {
background-image: -webkit-linear-gradient(top, #fff 0%, #f8f8f8 100%);
background-image: -o-linear-gradient(top, #fff 0%, #f8f8f8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fff), to(#f8f8f8));
background-image: linear-gradient(to bottom, #fff 0%, #f8f8f8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff8f8f8', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .15), 0 1px 5px rgba(0, 0, 0, .075);
}
.navbar-default .navbar-nav > .open > a,
.navbar-default .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -o-linear-gradient(top, #dbdbdb 0%, #e2e2e2 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dbdbdb), to(#e2e2e2));
background-image: linear-gradient(to bottom, #dbdbdb 0%, #e2e2e2 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdbdbdb', endColorstr='#ffe2e2e2', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .075);
}
.navbar-brand,
.navbar-nav > li > a {
text-shadow: 0 1px 0 rgba(255, 255, 255, .25);
}
.navbar-inverse {
background-image: -webkit-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -o-linear-gradient(top, #3c3c3c 0%, #222 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#3c3c3c), to(#222));
background-image: linear-gradient(to bottom, #3c3c3c 0%, #222 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff3c3c3c', endColorstr='#ff222222', GradientType=0);
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
background-repeat: repeat-x;
border-radius: 4px;
}
.navbar-inverse .navbar-nav > .open > a,
.navbar-inverse .navbar-nav > .active > a {
background-image: -webkit-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -o-linear-gradient(top, #080808 0%, #0f0f0f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#080808), to(#0f0f0f));
background-image: linear-gradient(to bottom, #080808 0%, #0f0f0f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff080808', endColorstr='#ff0f0f0f', GradientType=0);
background-repeat: repeat-x;
-webkit-box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
box-shadow: inset 0 3px 9px rgba(0, 0, 0, .25);
}
.navbar-inverse .navbar-brand,
.navbar-inverse .navbar-nav > li > a {
text-shadow: 0 -1px 0 rgba(0, 0, 0, .25);
}
.navbar-static-top,
.navbar-fixed-top,
.navbar-fixed-bottom {
border-radius: 0;
}
@media (max-width: 767px) {
.navbar .navbar-nav .open .dropdown-menu > .active > a,
.navbar .navbar-nav .open .dropdown-menu > .active > a:hover,
.navbar .navbar-nav .open .dropdown-menu > .active > a:focus {
color: #fff;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
}
.alert {
text-shadow: 0 1px 0 rgba(255, 255, 255, .2);
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .25), 0 1px 2px rgba(0, 0, 0, .05);
}
.alert-success {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #c8e5bc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#c8e5bc));
background-image: linear-gradient(to bottom, #dff0d8 0%, #c8e5bc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffc8e5bc', GradientType=0);
background-repeat: repeat-x;
border-color: #b2dba1;
}
.alert-info {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #b9def0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#b9def0));
background-image: linear-gradient(to bottom, #d9edf7 0%, #b9def0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffb9def0', GradientType=0);
background-repeat: repeat-x;
border-color: #9acfea;
}
.alert-warning {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #f8efc0 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#f8efc0));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #f8efc0 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fff8efc0', GradientType=0);
background-repeat: repeat-x;
border-color: #f5e79e;
}
.alert-danger {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #e7c3c3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#e7c3c3));
background-image: linear-gradient(to bottom, #f2dede 0%, #e7c3c3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffe7c3c3', GradientType=0);
background-repeat: repeat-x;
border-color: #dca7a7;
}
.progress {
background-image: -webkit-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #ebebeb 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#ebebeb), to(#f5f5f5));
background-image: linear-gradient(to bottom, #ebebeb 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffebebeb', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #286090 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#286090));
background-image: linear-gradient(to bottom, #337ab7 0%, #286090 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff286090', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-success {
background-image: -webkit-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -o-linear-gradient(top, #5cb85c 0%, #449d44 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5cb85c), to(#449d44));
background-image: linear-gradient(to bottom, #5cb85c 0%, #449d44 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5cb85c', endColorstr='#ff449d44', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-info {
background-image: -webkit-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -o-linear-gradient(top, #5bc0de 0%, #31b0d5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#5bc0de), to(#31b0d5));
background-image: linear-gradient(to bottom, #5bc0de 0%, #31b0d5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff31b0d5', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-warning {
background-image: -webkit-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -o-linear-gradient(top, #f0ad4e 0%, #ec971f 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f0ad4e), to(#ec971f));
background-image: linear-gradient(to bottom, #f0ad4e 0%, #ec971f 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0ad4e', endColorstr='#ffec971f', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-danger {
background-image: -webkit-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -o-linear-gradient(top, #d9534f 0%, #c9302c 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9534f), to(#c9302c));
background-image: linear-gradient(to bottom, #d9534f 0%, #c9302c 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9534f', endColorstr='#ffc9302c', GradientType=0);
background-repeat: repeat-x;
}
.progress-bar-striped {
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
background-image: linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);
}
.list-group {
border-radius: 4px;
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
box-shadow: 0 1px 2px rgba(0, 0, 0, .075);
}
.list-group-item.active,
.list-group-item.active:hover,
.list-group-item.active:focus {
text-shadow: 0 -1px 0 #286090;
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2b669a 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2b669a));
background-image: linear-gradient(to bottom, #337ab7 0%, #2b669a 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2b669a', GradientType=0);
background-repeat: repeat-x;
border-color: #2b669a;
}
.list-group-item.active .badge,
.list-group-item.active:hover .badge,
.list-group-item.active:focus .badge {
text-shadow: none;
}
.panel {
-webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
box-shadow: 0 1px 2px rgba(0, 0, 0, .05);
}
.panel-default > .panel-heading {
background-image: -webkit-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -o-linear-gradient(top, #f5f5f5 0%, #e8e8e8 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f5f5f5), to(#e8e8e8));
background-image: linear-gradient(to bottom, #f5f5f5 0%, #e8e8e8 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#ffe8e8e8', GradientType=0);
background-repeat: repeat-x;
}
.panel-primary > .panel-heading {
background-image: -webkit-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -o-linear-gradient(top, #337ab7 0%, #2e6da4 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#337ab7), to(#2e6da4));
background-image: linear-gradient(to bottom, #337ab7 0%, #2e6da4 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff337ab7', endColorstr='#ff2e6da4', GradientType=0);
background-repeat: repeat-x;
}
.panel-success > .panel-heading {
background-image: -webkit-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -o-linear-gradient(top, #dff0d8 0%, #d0e9c6 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#dff0d8), to(#d0e9c6));
background-image: linear-gradient(to bottom, #dff0d8 0%, #d0e9c6 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdff0d8', endColorstr='#ffd0e9c6', GradientType=0);
background-repeat: repeat-x;
}
.panel-info > .panel-heading {
background-image: -webkit-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -o-linear-gradient(top, #d9edf7 0%, #c4e3f3 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#d9edf7), to(#c4e3f3));
background-image: linear-gradient(to bottom, #d9edf7 0%, #c4e3f3 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffd9edf7', endColorstr='#ffc4e3f3', GradientType=0);
background-repeat: repeat-x;
}
.panel-warning > .panel-heading {
background-image: -webkit-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -o-linear-gradient(top, #fcf8e3 0%, #faf2cc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#fcf8e3), to(#faf2cc));
background-image: linear-gradient(to bottom, #fcf8e3 0%, #faf2cc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffcf8e3', endColorstr='#fffaf2cc', GradientType=0);
background-repeat: repeat-x;
}
.panel-danger > .panel-heading {
background-image: -webkit-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -o-linear-gradient(top, #f2dede 0%, #ebcccc 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#f2dede), to(#ebcccc));
background-image: linear-gradient(to bottom, #f2dede 0%, #ebcccc 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2dede', endColorstr='#ffebcccc', GradientType=0);
background-repeat: repeat-x;
}
.well {
background-image: -webkit-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -o-linear-gradient(top, #e8e8e8 0%, #f5f5f5 100%);
background-image: -webkit-gradient(linear, left top, left bottom, from(#e8e8e8), to(#f5f5f5));
background-image: linear-gradient(to bottom, #e8e8e8 0%, #f5f5f5 100%);
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe8e8e8', endColorstr='#fff5f5f5', GradientType=0);
background-repeat: repeat-x;
border-color: #dcdcdc;
-webkit-box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
box-shadow: inset 0 1px 3px rgba(0, 0, 0, .05), 0 1px 0 rgba(255, 255, 255, .1);
}
/*# sourceMappingURL=bootstrap-theme.css.map */
================================================
FILE: app/public/lib/bootstrap/css/bootstrap.css
================================================
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
*/
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
html {
font-family: sans-serif;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
body {
margin: 0;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
audio,
canvas,
progress,
video {
display: inline-block;
vertical-align: baseline;
}
audio:not([controls]) {
display: none;
height: 0;
}
[hidden],
template {
display: none;
}
a {
background-color: transparent;
}
a:active,
a:hover {
outline: 0;
}
abbr[title] {
border-bottom: 1px dotted;
}
b,
strong {
font-weight: bold;
}
dfn {
font-style: italic;
}
h1 {
margin: .67em 0;
font-size: 2em;
}
mark {
color: #000;
background: #ff0;
}
small {
font-size: 80%;
}
sub,
sup {
position: relative;
font-size: 75%;
line-height: 0;
vertical-align: baseline;
}
sup {
top: -.5em;
}
sub {
bottom: -.25em;
}
img {
border: 0;
}
svg:not(:root) {
overflow: hidden;
}
figure {
margin: 1em 40px;
}
hr {
height: 0;
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
}
pre {
overflow: auto;
}
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
button,
input,
optgroup,
select,
textarea {
margin: 0;
font: inherit;
color: inherit;
}
button {
overflow: visible;
}
button,
select {
text-transform: none;
}
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
cursor: pointer;
}
button[disabled],
html input[disabled] {
cursor: default;
}
button::-moz-focus-inner,
input::-moz-focus-inner {
padding: 0;
border: 0;
}
input {
line-height: normal;
}
input[type="checkbox"],
input[type="radio"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
input[type="search"] {
-webkit-box-sizing: content-box;
-moz-box-sizing: content-box;
box-sizing: content-box;
-webkit-appearance: textfield;
}
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
fieldset {
padding: .35em .625em .75em;
margin: 0 2px;
border: 1px solid #c0c0c0;
}
legend {
padding: 0;
border: 0;
}
textarea {
overflow: auto;
}
optgroup {
font-weight: bold;
}
table {
border-spacing: 0;
border-collapse: collapse;
}
td,
th {
padding: 0;
}
/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */
@media print {
*,
*:before,
*:after {
color: #000 !important;
text-shadow: none !important;
background: transparent !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
a,
a:visited {
text-decoration: underline;
}
a[href]:after {
content: " (" attr(href) ")";
}
abbr[title]:after {
content: " (" attr(title) ")";
}
a[href^="#"]:after,
a[href^="javascript:"]:after {
content: "";
}
pre,
blockquote {
border: 1px solid #999;
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
tr,
img {
page-break-inside: avoid;
}
img {
max-width: 100% !important;
}
p,
h2,
h3 {
orphans: 3;
widows: 3;
}
h2,
h3 {
page-break-after: avoid;
}
.navbar {
display: none;
}
.btn > .caret,
.dropup > .btn > .caret {
border-top-color: #000 !important;
}
.label {
border: 1px solid #000;
}
.table {
border-collapse: collapse !important;
}
.table td,
.table th {
background-color: #fff !important;
}
.table-bordered th,
.table-bordered td {
border: 1px solid #ddd !important;
}
}
@font-face {
font-family: 'Glyphicons Halflings';
src: url('../fonts/glyphicons-halflings-regular.eot');
src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');
}
.glyphicon {
position: relative;
top: 1px;
display: inline-block;
font-family: 'Glyphicons Halflings';
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.glyphicon-asterisk:before {
content: "\002a";
}
.glyphicon-plus:before {
content: "\002b";
}
.glyphicon-euro:before,
.glyphicon-eur:before {
content: "\20ac";
}
.glyphicon-minus:before {
content: "\2212";
}
.glyphicon-cloud:before {
content: "\2601";
}
.glyphicon-envelope:before {
content: "\2709";
}
.glyphicon-pencil:before {
content: "\270f";
}
.glyphicon-glass:before {
content: "\e001";
}
.glyphicon-music:before {
content: "\e002";
}
.glyphicon-search:before {
content: "\e003";
}
.glyphicon-heart:before {
content: "\e005";
}
.glyphicon-star:before {
content: "\e006";
}
.glyphicon-star-empty:before {
content: "\e007";
}
.glyphicon-user:before {
content: "\e008";
}
.glyphicon-film:before {
content: "\e009";
}
.glyphicon-th-large:before {
content: "\e010";
}
.glyphicon-th:before {
content: "\e011";
}
.glyphicon-th-list:before {
content: "\e012";
}
.glyphicon-ok:before {
content: "\e013";
}
.glyphicon-remove:before {
content: "\e014";
}
.glyphicon-zoom-in:before {
content: "\e015";
}
.glyphicon-zoom-out:before {
content: "\e016";
}
.glyphicon-off:before {
content: "\e017";
}
.glyphicon-signal:before {
content: "\e018";
}
.glyphicon-cog:before {
content: "\e019";
}
.glyphicon-trash:before {
content: "\e020";
}
.glyphicon-home:before {
content: "\e021";
}
.glyphicon-file:before {
content: "\e022";
}
.glyphicon-time:before {
content: "\e023";
}
.glyphicon-road:before {
content: "\e024";
}
.glyphicon-download-alt:before {
content: "\e025";
}
.glyphicon-download:before {
content: "\e026";
}
.glyphicon-upload:before {
content: "\e027";
}
.glyphicon-inbox:before {
content: "\e028";
}
.glyphicon-play-circle:before {
content: "\e029";
}
.glyphicon-repeat:before {
content: "\e030";
}
.glyphicon-refresh:before {
content: "\e031";
}
.glyphicon-list-alt:before {
content: "\e032";
}
.glyphicon-lock:before {
content: "\e033";
}
.glyphicon-flag:before {
content: "\e034";
}
.glyphicon-headphones:before {
content: "\e035";
}
.glyphicon-volume-off:before {
content: "\e036";
}
.glyphicon-volume-down:before {
content: "\e037";
}
.glyphicon-volume-up:before {
content: "\e038";
}
.glyphicon-qrcode:before {
content: "\e039";
}
.glyphicon-barcode:before {
content: "\e040";
}
.glyphicon-tag:before {
content: "\e041";
}
.glyphicon-tags:before {
content: "\e042";
}
.glyphicon-book:before {
content: "\e043";
}
.glyphicon-bookmark:before {
content: "\e044";
}
.glyphicon-print:before {
content: "\e045";
}
.glyphicon-camera:before {
content: "\e046";
}
.glyphicon-font:before {
content: "\e047";
}
.glyphicon-bold:before {
content: "\e048";
}
.glyphicon-italic:before {
content: "\e049";
}
.glyphicon-text-height:before {
content: "\e050";
}
.glyphicon-text-width:before {
content: "\e051";
}
.glyphicon-align-left:before {
content: "\e052";
}
.glyphicon-align-center:before {
content: "\e053";
}
.glyphicon-align-right:before {
content: "\e054";
}
.glyphicon-align-justify:before {
content: "\e055";
}
.glyphicon-list:before {
content: "\e056";
}
.glyphicon-indent-left:before {
content: "\e057";
}
.glyphicon-indent-right:before {
content: "\e058";
}
.glyphicon-facetime-video:before {
content: "\e059";
}
.glyphicon-picture:before {
content: "\e060";
}
.glyphicon-map-marker:before {
content: "\e062";
}
.glyphicon-adjust:before {
content: "\e063";
}
.glyphicon-tint:before {
content: "\e064";
}
.glyphicon-edit:before {
content: "\e065";
}
.glyphicon-share:before {
content: "\e066";
}
.glyphicon-check:before {
content: "\e067";
}
.glyphicon-move:before {
content: "\e068";
}
.glyphicon-step-backward:before {
content: "\e069";
}
.glyphicon-fast-backward:before {
content: "\e070";
}
.glyphicon-backward:before {
content: "\e071";
}
.glyphicon-play:before {
content: "\e072";
}
.glyphicon-pause:before {
content: "\e073";
}
.glyphicon-stop:before {
content: "\e074";
}
.glyphicon-forward:before {
content: "\e075";
}
.glyphicon-fast-forward:before {
content: "\e076";
}
.glyphicon-step-forward:before {
content: "\e077";
}
.glyphicon-eject:before {
content: "\e078";
}
.glyphicon-chevron-left:before {
content: "\e079";
}
.glyphicon-chevron-right:before {
content: "\e080";
}
.glyphicon-plus-sign:before {
content: "\e081";
}
.glyphicon-minus-sign:before {
content: "\e082";
}
.glyphicon-remove-sign:before {
content: "\e083";
}
.glyphicon-ok-sign:before {
content: "\e084";
}
.glyphicon-question-sign:before {
content: "\e085";
}
.glyphicon-info-sign:before {
content: "\e086";
}
.glyphicon-screenshot:before {
content: "\e087";
}
.glyphicon-remove-circle:before {
content: "\e088";
}
.glyphicon-ok-circle:before {
content: "\e089";
}
.glyphicon-ban-circle:before {
content: "\e090";
}
.glyphicon-arrow-left:before {
content: "\e091";
}
.glyphicon-arrow-right:before {
content: "\e092";
}
.glyphicon-arrow-up:before {
content: "\e093";
}
.glyphicon-arrow-down:before {
content: "\e094";
}
.glyphicon-share-alt:before {
content: "\e095";
}
.glyphicon-resize-full:before {
content: "\e096";
}
.glyphicon-resize-small:before {
content: "\e097";
}
.glyphicon-exclamation-sign:before {
content: "\e101";
}
.glyphicon-gift:before {
content: "\e102";
}
.glyphicon-leaf:before {
content: "\e103";
}
.glyphicon-fire:before {
content: "\e104";
}
.glyphicon-eye-open:before {
content: "\e105";
}
.glyphicon-eye-close:before {
content: "\e106";
}
.glyphicon-warning-sign:before {
content: "\e107";
}
.glyphicon-plane:before {
content: "\e108";
}
.glyphicon-calendar:before {
content: "\e109";
}
.glyphicon-random:before {
content: "\e110";
}
.glyphicon-comment:before {
content: "\e111";
}
.glyphicon-magnet:before {
content: "\e112";
}
.glyphicon-chevron-up:before {
content: "\e113";
}
.glyphicon-chevron-down:before {
content: "\e114";
}
.glyphicon-retweet:before {
content: "\e115";
}
.glyphicon-shopping-cart:before {
content: "\e116";
}
.glyphicon-folder-close:before {
content: "\e117";
}
.glyphicon-folder-open:before {
content: "\e118";
}
.glyphicon-resize-vertical:before {
content: "\e119";
}
.glyphicon-resize-horizontal:before {
content: "\e120";
}
.glyphicon-hdd:before {
content: "\e121";
}
.glyphicon-bullhorn:before {
content: "\e122";
}
.glyphicon-bell:before {
content: "\e123";
}
.glyphicon-certificate:before {
content: "\e124";
}
.glyphicon-thumbs-up:before {
content: "\e125";
}
.glyphicon-thumbs-down:before {
content: "\e126";
}
.glyphicon-hand-right:before {
content: "\e127";
}
.glyphicon-hand-left:before {
content: "\e128";
}
.glyphicon-hand-up:before {
content: "\e129";
}
.glyphicon-hand-down:before {
content: "\e130";
}
.glyphicon-circle-arrow-right:before {
content: "\e131";
}
.glyphicon-circle-arrow-left:before {
content: "\e132";
}
.glyphicon-circle-arrow-up:before {
content: "\e133";
}
.glyphicon-circle-arrow-down:before {
content: "\e134";
}
.glyphicon-globe:before {
content: "\e135";
}
.glyphicon-wrench:before {
content: "\e136";
}
.glyphicon-tasks:before {
content: "\e137";
}
.glyphicon-filter:before {
content: "\e138";
}
.glyphicon-briefcase:before {
content: "\e139";
}
.glyphicon-fullscreen:before {
content: "\e140";
}
.glyphicon-dashboard:before {
content: "\e141";
}
.glyphicon-paperclip:before {
content: "\e142";
}
.glyphicon-heart-empty:before {
content: "\e143";
}
.glyphicon-link:before {
content: "\e144";
}
.glyphicon-phone:before {
content: "\e145";
}
.glyphicon-pushpin:before {
content: "\e146";
}
.glyphicon-usd:before {
content: "\e148";
}
.glyphicon-gbp:before {
content: "\e149";
}
.glyphicon-sort:before {
content: "\e150";
}
.glyphicon-sort-by-alphabet:before {
content: "\e151";
}
.glyphicon-sort-by-alphabet-alt:before {
content: "\e152";
}
.glyphicon-sort-by-order:before {
content: "\e153";
}
.glyphicon-sort-by-order-alt:before {
content: "\e154";
}
.glyphicon-sort-by-attributes:before {
content: "\e155";
}
.glyphicon-sort-by-attributes-alt:before {
content: "\e156";
}
.glyphicon-unchecked:before {
content: "\e157";
}
.glyphicon-expand:before {
content: "\e158";
}
.glyphicon-collapse-down:before {
content: "\e159";
}
.glyphicon-collapse-up:before {
content: "\e160";
}
.glyphicon-log-in:before {
content: "\e161";
}
.glyphicon-flash:before {
content: "\e162";
}
.glyphicon-log-out:before {
content: "\e163";
}
.glyphicon-new-window:before {
content: "\e164";
}
.glyphicon-record:before {
content: "\e165";
}
.glyphicon-save:before {
content: "\e166";
}
.glyphicon-open:before {
content: "\e167";
}
.glyphicon-saved:before {
content: "\e168";
}
.glyphicon-import:before {
content: "\e169";
}
.glyphicon-export:before {
content: "\e170";
}
.glyphicon-send:before {
content: "\e171";
}
.glyphicon-floppy-disk:before {
content: "\e172";
}
.glyphicon-floppy-saved:before {
content: "\e173";
}
.glyphicon-floppy-remove:before {
content: "\e174";
}
.glyphicon-floppy-save:before {
content: "\e175";
}
.glyphicon-floppy-open:before {
content: "\e176";
}
.glyphicon-credit-card:before {
content: "\e177";
}
.glyphicon-transfer:before {
content: "\e178";
}
.glyphicon-cutlery:before {
content: "\e179";
}
.glyphicon-header:before {
content: "\e180";
}
.glyphicon-compressed:before {
content: "\e181";
}
.glyphicon-earphone:before {
content: "\e182";
}
.glyphicon-phone-alt:before {
content: "\e183";
}
.glyphicon-tower:before {
content: "\e184";
}
.glyphicon-stats:before {
content: "\e185";
}
.glyphicon-sd-video:before {
content: "\e186";
}
.glyphicon-hd-video:before {
content: "\e187";
}
.glyphicon-subtitles:before {
content: "\e188";
}
.glyphicon-sound-stereo:before {
content: "\e189";
}
.glyphicon-sound-dolby:before {
content: "\e190";
}
.glyphicon-sound-5-1:before {
content: "\e191";
}
.glyphicon-sound-6-1:before {
content: "\e192";
}
.glyphicon-sound-7-1:before {
content: "\e193";
}
.glyphicon-copyright-mark:before {
content: "\e194";
}
.glyphicon-registration-mark:before {
content: "\e195";
}
.glyphicon-cloud-download:before {
content: "\e197";
}
.glyphicon-cloud-upload:before {
content: "\e198";
}
.glyphicon-tree-conifer:before {
content: "\e199";
}
.glyphicon-tree-deciduous:before {
content: "\e200";
}
.glyphicon-cd:before {
content: "\e201";
}
.glyphicon-save-file:before {
content: "\e202";
}
.glyphicon-open-file:before {
content: "\e203";
}
.glyphicon-level-up:before {
content: "\e204";
}
.glyphicon-copy:before {
content: "\e205";
}
.glyphicon-paste:before {
content: "\e206";
}
.glyphicon-alert:before {
content: "\e209";
}
.glyphicon-equalizer:before {
content: "\e210";
}
.glyphicon-king:before {
content: "\e211";
}
.glyphicon-queen:before {
content: "\e212";
}
.glyphicon-pawn:before {
content: "\e213";
}
.glyphicon-bishop:before {
content: "\e214";
}
.glyphicon-knight:before {
content: "\e215";
}
.glyphicon-baby-formula:before {
content: "\e216";
}
.glyphicon-tent:before {
content: "\26fa";
}
.glyphicon-blackboard:before {
content: "\e218";
}
.glyphicon-bed:before {
content: "\e219";
}
.glyphicon-apple:before {
content: "\f8ff";
}
.glyphicon-erase:before {
content: "\e221";
}
.glyphicon-hourglass:before {
content: "\231b";
}
.glyphicon-lamp:before {
content: "\e223";
}
.glyphicon-duplicate:before {
content: "\e224";
}
.glyphicon-piggy-bank:before {
content: "\e225";
}
.glyphicon-scissors:before {
content: "\e226";
}
.glyphicon-bitcoin:before {
content: "\e227";
}
.glyphicon-btc:before {
content: "\e227";
}
.glyphicon-xbt:before {
content: "\e227";
}
.glyphicon-yen:before {
content: "\00a5";
}
.glyphicon-jpy:before {
content: "\00a5";
}
.glyphicon-ruble:before {
content: "\20bd";
}
.glyphicon-rub:before {
content: "\20bd";
}
.glyphicon-scale:before {
content: "\e230";
}
.glyphicon-ice-lolly:before {
content: "\e231";
}
.glyphicon-ice-lolly-tasted:before {
content: "\e232";
}
.glyphicon-education:before {
content: "\e233";
}
.glyphicon-option-horizontal:before {
content: "\e234";
}
.glyphicon-option-vertical:before {
content: "\e235";
}
.glyphicon-menu-hamburger:before {
content: "\e236";
}
.glyphicon-modal-window:before {
content: "\e237";
}
.glyphicon-oil:before {
content: "\e238";
}
.glyphicon-grain:before {
content: "\e239";
}
.glyphicon-sunglasses:before {
content: "\e240";
}
.glyphicon-text-size:before {
content: "\e241";
}
.glyphicon-text-color:before {
content: "\e242";
}
.glyphicon-text-background:before {
content: "\e243";
}
.glyphicon-object-align-top:before {
content: "\e244";
}
.glyphicon-object-align-bottom:before {
content: "\e245";
}
.glyphicon-object-align-horizontal:before {
content: "\e246";
}
.glyphicon-object-align-left:before {
content: "\e247";
}
.glyphicon-object-align-vertical:before {
content: "\e248";
}
.glyphicon-object-align-right:before {
content: "\e249";
}
.glyphicon-triangle-right:before {
content: "\e250";
}
.glyphicon-triangle-left:before {
content: "\e251";
}
.glyphicon-triangle-bottom:before {
content: "\e252";
}
.glyphicon-triangle-top:before {
content: "\e253";
}
.glyphicon-console:before {
content: "\e254";
}
.glyphicon-superscript:before {
content: "\e255";
}
.glyphicon-subscript:before {
content: "\e256";
}
.glyphicon-menu-left:before {
content: "\e257";
}
.glyphicon-menu-right:before {
content: "\e258";
}
.glyphicon-menu-down:before {
content: "\e259";
}
.glyphicon-menu-up:before {
content: "\e260";
}
* {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
*:before,
*:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
html {
font-size: 10px;
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.42857143;
color: #333;
background-color: #fff;
}
input,
button,
select,
textarea {
font-family: inherit;
font-size: inherit;
line-height: inherit;
}
a {
color: #337ab7;
text-decoration: none;
}
a:hover,
a:focus {
color: #23527c;
text-decoration: underline;
}
a:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
figure {
margin: 0;
}
img {
vertical-align: middle;
}
.img-responsive,
.thumbnail > img,
.thumbnail a > img,
.carousel-inner > .item > img,
.carousel-inner > .item > a > img {
display: block;
max-width: 100%;
height: auto;
}
.img-rounded {
border-radius: 6px;
}
.img-thumbnail {
display: inline-block;
max-width: 100%;
height: auto;
padding: 4px;
line-height: 1.42857143;
background-color: #fff;
border: 1px solid #ddd;
border-radius: 4px;
-webkit-transition: all .2s ease-in-out;
-o-transition: all .2s ease-in-out;
transition: all .2s ease-in-out;
}
.img-circle {
border-radius: 50%;
}
hr {
margin-top: 20px;
margin-bottom: 20px;
border: 0;
border-top: 1px solid #eee;
}
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
position: static;
width: auto;
height: auto;
margin: 0;
overflow: visible;
clip: auto;
}
[role="button"] {
cursor: pointer;
}
h1,
h2,
h3,
h4,
h5,
h6,
.h1,
.h2,
.h3,
.h4,
.h5,
.h6 {
font-family: inherit;
font-weight: 500;
line-height: 1.1;
color: inherit;
}
h1 small,
h2 small,
h3 small,
h4 small,
h5 small,
h6 small,
.h1 small,
.h2 small,
.h3 small,
.h4 small,
.h5 small,
.h6 small,
h1 .small,
h2 .small,
h3 .small,
h4 .small,
h5 .small,
h6 .small,
.h1 .small,
.h2 .small,
.h3 .small,
.h4 .small,
.h5 .small,
.h6 .small {
font-weight: normal;
line-height: 1;
color: #777;
}
h1,
.h1,
h2,
.h2,
h3,
.h3 {
margin-top: 20px;
margin-bottom: 10px;
}
h1 small,
.h1 small,
h2 small,
.h2 small,
h3 small,
.h3 small,
h1 .small,
.h1 .small,
h2 .small,
.h2 .small,
h3 .small,
.h3 .small {
font-size: 65%;
}
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 10px;
margin-bottom: 10px;
}
h4 small,
.h4 small,
h5 small,
.h5 small,
h6 small,
.h6 small,
h4 .small,
.h4 .small,
h5 .small,
.h5 .small,
h6 .small,
.h6 .small {
font-size: 75%;
}
h1,
.h1 {
font-size: 36px;
}
h2,
.h2 {
font-size: 30px;
}
h3,
.h3 {
font-size: 24px;
}
h4,
.h4 {
font-size: 18px;
}
h5,
.h5 {
font-size: 14px;
}
h6,
.h6 {
font-size: 12px;
}
p {
margin: 0 0 10px;
}
.lead {
margin-bottom: 20px;
font-size: 16px;
font-weight: 300;
line-height: 1.4;
}
@media (min-width: 768px) {
.lead {
font-size: 21px;
}
}
small,
.small {
font-size: 85%;
}
mark,
.mark {
padding: .2em;
background-color: #fcf8e3;
}
.text-left {
text-align: left;
}
.text-right {
text-align: right;
}
.text-center {
text-align: center;
}
.text-justify {
text-align: justify;
}
.text-nowrap {
white-space: nowrap;
}
.text-lowercase {
text-transform: lowercase;
}
.text-uppercase {
text-transform: uppercase;
}
.text-capitalize {
text-transform: capitalize;
}
.text-muted {
color: #777;
}
.text-primary {
color: #337ab7;
}
a.text-primary:hover,
a.text-primary:focus {
color: #286090;
}
.text-success {
color: #3c763d;
}
a.text-success:hover,
a.text-success:focus {
color: #2b542c;
}
.text-info {
color: #31708f;
}
a.text-info:hover,
a.text-info:focus {
color: #245269;
}
.text-warning {
color: #8a6d3b;
}
a.text-warning:hover,
a.text-warning:focus {
color: #66512c;
}
.text-danger {
color: #a94442;
}
a.text-danger:hover,
a.text-danger:focus {
color: #843534;
}
.bg-primary {
color: #fff;
background-color: #337ab7;
}
a.bg-primary:hover,
a.bg-primary:focus {
background-color: #286090;
}
.bg-success {
background-color: #dff0d8;
}
a.bg-success:hover,
a.bg-success:focus {
background-color: #c1e2b3;
}
.bg-info {
background-color: #d9edf7;
}
a.bg-info:hover,
a.bg-info:focus {
background-color: #afd9ee;
}
.bg-warning {
background-color: #fcf8e3;
}
a.bg-warning:hover,
a.bg-warning:focus {
background-color: #f7ecb5;
}
.bg-danger {
background-color: #f2dede;
}
a.bg-danger:hover,
a.bg-danger:focus {
background-color: #e4b9b9;
}
.page-header {
padding-bottom: 9px;
margin: 40px 0 20px;
border-bottom: 1px solid #eee;
}
ul,
ol {
margin-top: 0;
margin-bottom: 10px;
}
ul ul,
ol ul,
ul ol,
ol ol {
margin-bottom: 0;
}
.list-unstyled {
padding-left: 0;
list-style: none;
}
.list-inline {
padding-left: 0;
margin-left: -5px;
list-style: none;
}
.list-inline > li {
display: inline-block;
padding-right: 5px;
padding-left: 5px;
}
dl {
margin-top: 0;
margin-bottom: 20px;
}
dt,
dd {
line-height: 1.42857143;
}
dt {
font-weight: bold;
}
dd {
margin-left: 0;
}
@media (min-width: 768px) {
.dl-horizontal dt {
float: left;
width: 160px;
overflow: hidden;
clear: left;
text-align: right;
text-overflow: ellipsis;
white-space: nowrap;
}
.dl-horizontal dd {
margin-left: 180px;
}
}
abbr[title],
abbr[data-original-title] {
cursor: help;
border-bottom: 1px dotted #777;
}
.initialism {
font-size: 90%;
text-transform: uppercase;
}
blockquote {
padding: 10px 20px;
margin: 0 0 20px;
font-size: 17.5px;
border-left: 5px solid #eee;
}
blockquote p:last-child,
blockquote ul:last-child,
blockquote ol:last-child {
margin-bottom: 0;
}
blockquote footer,
blockquote small,
blockquote .small {
display: block;
font-size: 80%;
line-height: 1.42857143;
color: #777;
}
blockquote footer:before,
blockquote small:before,
blockquote .small:before {
content: '\2014 \00A0';
}
.blockquote-reverse,
blockquote.pull-right {
padding-right: 15px;
padding-left: 0;
text-align: right;
border-right: 5px solid #eee;
border-left: 0;
}
.blockquote-reverse footer:before,
blockquote.pull-right footer:before,
.blockquote-reverse small:before,
blockquote.pull-right small:before,
.blockquote-reverse .small:before,
blockquote.pull-right .small:before {
content: '';
}
.blockquote-reverse footer:after,
blockquote.pull-right footer:after,
.blockquote-reverse small:after,
blockquote.pull-right small:after,
.blockquote-reverse .small:after,
blockquote.pull-right .small:after {
content: '\00A0 \2014';
}
address {
margin-bottom: 20px;
font-style: normal;
line-height: 1.42857143;
}
code,
kbd,
pre,
samp {
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
}
code {
padding: 2px 4px;
font-size: 90%;
color: #c7254e;
background-color: #f9f2f4;
border-radius: 4px;
}
kbd {
padding: 2px 4px;
font-size: 90%;
color: #fff;
background-color: #333;
border-radius: 3px;
-webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);
}
kbd kbd {
padding: 0;
font-size: 100%;
font-weight: bold;
-webkit-box-shadow: none;
box-shadow: none;
}
pre {
display: block;
padding: 9.5px;
margin: 0 0 10px;
font-size: 13px;
line-height: 1.42857143;
color: #333;
word-break: break-all;
word-wrap: break-word;
background-color: #f5f5f5;
border: 1px solid #ccc;
border-radius: 4px;
}
pre code {
padding: 0;
font-size: inherit;
color: inherit;
white-space: pre-wrap;
background-color: transparent;
border-radius: 0;
}
.pre-scrollable {
max-height: 340px;
overflow-y: scroll;
}
.container {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 992px) {
.container {
width: 970px;
}
}
@media (min-width: 1200px) {
.container {
width: 1170px;
}
}
.container-fluid {
padding-right: 15px;
padding-left: 15px;
margin-right: auto;
margin-left: auto;
}
.row {
margin-right: -15px;
margin-left: -15px;
}
.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {
position: relative;
min-height: 1px;
padding-right: 15px;
padding-left: 15px;
}
.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {
float: left;
}
.col-xs-12 {
width: 100%;
}
.col-xs-11 {
width: 91.66666667%;
}
.col-xs-10 {
width: 83.33333333%;
}
.col-xs-9 {
width: 75%;
}
.col-xs-8 {
width: 66.66666667%;
}
.col-xs-7 {
width: 58.33333333%;
}
.col-xs-6 {
width: 50%;
}
.col-xs-5 {
width: 41.66666667%;
}
.col-xs-4 {
width: 33.33333333%;
}
.col-xs-3 {
width: 25%;
}
.col-xs-2 {
width: 16.66666667%;
}
.col-xs-1 {
width: 8.33333333%;
}
.col-xs-pull-12 {
right: 100%;
}
.col-xs-pull-11 {
right: 91.66666667%;
}
.col-xs-pull-10 {
right: 83.33333333%;
}
.col-xs-pull-9 {
right: 75%;
}
.col-xs-pull-8 {
right: 66.66666667%;
}
.col-xs-pull-7 {
right: 58.33333333%;
}
.col-xs-pull-6 {
right: 50%;
}
.col-xs-pull-5 {
right: 41.66666667%;
}
.col-xs-pull-4 {
right: 33.33333333%;
}
.col-xs-pull-3 {
right: 25%;
}
.col-xs-pull-2 {
right: 16.66666667%;
}
.col-xs-pull-1 {
right: 8.33333333%;
}
.col-xs-pull-0 {
right: auto;
}
.col-xs-push-12 {
left: 100%;
}
.col-xs-push-11 {
left: 91.66666667%;
}
.col-xs-push-10 {
left: 83.33333333%;
}
.col-xs-push-9 {
left: 75%;
}
.col-xs-push-8 {
left: 66.66666667%;
}
.col-xs-push-7 {
left: 58.33333333%;
}
.col-xs-push-6 {
left: 50%;
}
.col-xs-push-5 {
left: 41.66666667%;
}
.col-xs-push-4 {
left: 33.33333333%;
}
.col-xs-push-3 {
left: 25%;
}
.col-xs-push-2 {
left: 16.66666667%;
}
.col-xs-push-1 {
left: 8.33333333%;
}
.col-xs-push-0 {
left: auto;
}
.col-xs-offset-12 {
margin-left: 100%;
}
.col-xs-offset-11 {
margin-left: 91.66666667%;
}
.col-xs-offset-10 {
margin-left: 83.33333333%;
}
.col-xs-offset-9 {
margin-left: 75%;
}
.col-xs-offset-8 {
margin-left: 66.66666667%;
}
.col-xs-offset-7 {
margin-left: 58.33333333%;
}
.col-xs-offset-6 {
margin-left: 50%;
}
.col-xs-offset-5 {
margin-left: 41.66666667%;
}
.col-xs-offset-4 {
margin-left: 33.33333333%;
}
.col-xs-offset-3 {
margin-left: 25%;
}
.col-xs-offset-2 {
margin-left: 16.66666667%;
}
.col-xs-offset-1 {
margin-left: 8.33333333%;
}
.col-xs-offset-0 {
margin-left: 0;
}
@media (min-width: 768px) {
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
float: left;
}
.col-sm-12 {
width: 100%;
}
.col-sm-11 {
width: 91.66666667%;
}
.col-sm-10 {
width: 83.33333333%;
}
.col-sm-9 {
width: 75%;
}
.col-sm-8 {
width: 66.66666667%;
}
.col-sm-7 {
width: 58.33333333%;
}
.col-sm-6 {
width: 50%;
}
.col-sm-5 {
width: 41.66666667%;
}
.col-sm-4 {
width: 33.33333333%;
}
.col-sm-3 {
width: 25%;
}
.col-sm-2 {
width: 16.66666667%;
}
.col-sm-1 {
width: 8.33333333%;
}
.col-sm-pull-12 {
right: 100%;
}
.col-sm-pull-11 {
right: 91.66666667%;
}
.col-sm-pull-10 {
right: 83.33333333%;
}
.col-sm-pull-9 {
right: 75%;
}
.col-sm-pull-8 {
right: 66.66666667%;
}
.col-sm-pull-7 {
right: 58.33333333%;
}
.col-sm-pull-6 {
right: 50%;
}
.col-sm-pull-5 {
right: 41.66666667%;
}
.col-sm-pull-4 {
right: 33.33333333%;
}
.col-sm-pull-3 {
right: 25%;
}
.col-sm-pull-2 {
right: 16.66666667%;
}
.col-sm-pull-1 {
right: 8.33333333%;
}
.col-sm-pull-0 {
right: auto;
}
.col-sm-push-12 {
left: 100%;
}
.col-sm-push-11 {
left: 91.66666667%;
}
.col-sm-push-10 {
left: 83.33333333%;
}
.col-sm-push-9 {
left: 75%;
}
.col-sm-push-8 {
left: 66.66666667%;
}
.col-sm-push-7 {
left: 58.33333333%;
}
.col-sm-push-6 {
left: 50%;
}
.col-sm-push-5 {
left: 41.66666667%;
}
.col-sm-push-4 {
left: 33.33333333%;
}
.col-sm-push-3 {
left: 25%;
}
.col-sm-push-2 {
left: 16.66666667%;
}
.col-sm-push-1 {
left: 8.33333333%;
}
.col-sm-push-0 {
left: auto;
}
.col-sm-offset-12 {
margin-left: 100%;
}
.col-sm-offset-11 {
margin-left: 91.66666667%;
}
.col-sm-offset-10 {
margin-left: 83.33333333%;
}
.col-sm-offset-9 {
margin-left: 75%;
}
.col-sm-offset-8 {
margin-left: 66.66666667%;
}
.col-sm-offset-7 {
margin-left: 58.33333333%;
}
.col-sm-offset-6 {
margin-left: 50%;
}
.col-sm-offset-5 {
margin-left: 41.66666667%;
}
.col-sm-offset-4 {
margin-left: 33.33333333%;
}
.col-sm-offset-3 {
margin-left: 25%;
}
.col-sm-offset-2 {
margin-left: 16.66666667%;
}
.col-sm-offset-1 {
margin-left: 8.33333333%;
}
.col-sm-offset-0 {
margin-left: 0;
}
}
@media (min-width: 992px) {
.col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {
float: left;
}
.col-md-12 {
width: 100%;
}
.col-md-11 {
width: 91.66666667%;
}
.col-md-10 {
width: 83.33333333%;
}
.col-md-9 {
width: 75%;
}
.col-md-8 {
width: 66.66666667%;
}
.col-md-7 {
width: 58.33333333%;
}
.col-md-6 {
width: 50%;
}
.col-md-5 {
width: 41.66666667%;
}
.col-md-4 {
width: 33.33333333%;
}
.col-md-3 {
width: 25%;
}
.col-md-2 {
width: 16.66666667%;
}
.col-md-1 {
width: 8.33333333%;
}
.col-md-pull-12 {
right: 100%;
}
.col-md-pull-11 {
right: 91.66666667%;
}
.col-md-pull-10 {
right: 83.33333333%;
}
.col-md-pull-9 {
right: 75%;
}
.col-md-pull-8 {
right: 66.66666667%;
}
.col-md-pull-7 {
right: 58.33333333%;
}
.col-md-pull-6 {
right: 50%;
}
.col-md-pull-5 {
right: 41.66666667%;
}
.col-md-pull-4 {
right: 33.33333333%;
}
.col-md-pull-3 {
right: 25%;
}
.col-md-pull-2 {
right: 16.66666667%;
}
.col-md-pull-1 {
right: 8.33333333%;
}
.col-md-pull-0 {
right: auto;
}
.col-md-push-12 {
left: 100%;
}
.col-md-push-11 {
left: 91.66666667%;
}
.col-md-push-10 {
left: 83.33333333%;
}
.col-md-push-9 {
left: 75%;
}
.col-md-push-8 {
left: 66.66666667%;
}
.col-md-push-7 {
left: 58.33333333%;
}
.col-md-push-6 {
left: 50%;
}
.col-md-push-5 {
left: 41.66666667%;
}
.col-md-push-4 {
left: 33.33333333%;
}
.col-md-push-3 {
left: 25%;
}
.col-md-push-2 {
left: 16.66666667%;
}
.col-md-push-1 {
left: 8.33333333%;
}
.col-md-push-0 {
left: auto;
}
.col-md-offset-12 {
margin-left: 100%;
}
.col-md-offset-11 {
margin-left: 91.66666667%;
}
.col-md-offset-10 {
margin-left: 83.33333333%;
}
.col-md-offset-9 {
margin-left: 75%;
}
.col-md-offset-8 {
margin-left: 66.66666667%;
}
.col-md-offset-7 {
margin-left: 58.33333333%;
}
.col-md-offset-6 {
margin-left: 50%;
}
.col-md-offset-5 {
margin-left: 41.66666667%;
}
.col-md-offset-4 {
margin-left: 33.33333333%;
}
.col-md-offset-3 {
margin-left: 25%;
}
.col-md-offset-2 {
margin-left: 16.66666667%;
}
.col-md-offset-1 {
margin-left: 8.33333333%;
}
.col-md-offset-0 {
margin-left: 0;
}
}
@media (min-width: 1200px) {
.col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {
float: left;
}
.col-lg-12 {
width: 100%;
}
.col-lg-11 {
width: 91.66666667%;
}
.col-lg-10 {
width: 83.33333333%;
}
.col-lg-9 {
width: 75%;
}
.col-lg-8 {
width: 66.66666667%;
}
.col-lg-7 {
width: 58.33333333%;
}
.col-lg-6 {
width: 50%;
}
.col-lg-5 {
width: 41.66666667%;
}
.col-lg-4 {
width: 33.33333333%;
}
.col-lg-3 {
width: 25%;
}
.col-lg-2 {
width: 16.66666667%;
}
.col-lg-1 {
width: 8.33333333%;
}
.col-lg-pull-12 {
right: 100%;
}
.col-lg-pull-11 {
right: 91.66666667%;
}
.col-lg-pull-10 {
right: 83.33333333%;
}
.col-lg-pull-9 {
right: 75%;
}
.col-lg-pull-8 {
right: 66.66666667%;
}
.col-lg-pull-7 {
right: 58.33333333%;
}
.col-lg-pull-6 {
right: 50%;
}
.col-lg-pull-5 {
right: 41.66666667%;
}
.col-lg-pull-4 {
right: 33.33333333%;
}
.col-lg-pull-3 {
right: 25%;
}
.col-lg-pull-2 {
right: 16.66666667%;
}
.col-lg-pull-1 {
right: 8.33333333%;
}
.col-lg-pull-0 {
right: auto;
}
.col-lg-push-12 {
left: 100%;
}
.col-lg-push-11 {
left: 91.66666667%;
}
.col-lg-push-10 {
left: 83.33333333%;
}
.col-lg-push-9 {
left: 75%;
}
.col-lg-push-8 {
left: 66.66666667%;
}
.col-lg-push-7 {
left: 58.33333333%;
}
.col-lg-push-6 {
left: 50%;
}
.col-lg-push-5 {
left: 41.66666667%;
}
.col-lg-push-4 {
left: 33.33333333%;
}
.col-lg-push-3 {
left: 25%;
}
.col-lg-push-2 {
left: 16.66666667%;
}
.col-lg-push-1 {
left: 8.33333333%;
}
.col-lg-push-0 {
left: auto;
}
.col-lg-offset-12 {
margin-left: 100%;
}
.col-lg-offset-11 {
margin-left: 91.66666667%;
}
.col-lg-offset-10 {
margin-left: 83.33333333%;
}
.col-lg-offset-9 {
margin-left: 75%;
}
.col-lg-offset-8 {
margin-left: 66.66666667%;
}
.col-lg-offset-7 {
margin-left: 58.33333333%;
}
.col-lg-offset-6 {
margin-left: 50%;
}
.col-lg-offset-5 {
margin-left: 41.66666667%;
}
.col-lg-offset-4 {
margin-left: 33.33333333%;
}
.col-lg-offset-3 {
margin-left: 25%;
}
.col-lg-offset-2 {
margin-left: 16.66666667%;
}
.col-lg-offset-1 {
margin-left: 8.33333333%;
}
.col-lg-offset-0 {
margin-left: 0;
}
}
table {
background-color: transparent;
}
caption {
padding-top: 8px;
padding-bottom: 8px;
color: #777;
text-align: left;
}
th {
text-align: left;
}
.table {
width: 100%;
max-width: 100%;
margin-bottom: 20px;
}
.table > thead > tr > th,
.table > tbody > tr > th,
.table > tfoot > tr > th,
.table > thead > tr > td,
.table > tbody > tr > td,
.table > tfoot > tr > td {
padding: 8px;
line-height: 1.42857143;
vertical-align: top;
border-top: 1px solid #ddd;
}
.table > thead > tr > th {
vertical-align: bottom;
border-bottom: 2px solid #ddd;
}
.table > caption + thead > tr:first-child > th,
.table > colgroup + thead > tr:first-child > th,
.table > thead:first-child > tr:first-child > th,
.table > caption + thead > tr:first-child > td,
.table > colgroup + thead > tr:first-child > td,
.table > thead:first-child > tr:first-child > td {
border-top: 0;
}
.table > tbody + tbody {
border-top: 2px solid #ddd;
}
.table .table {
background-color: #fff;
}
.table-condensed > thead > tr > th,
.table-condensed > tbody > tr > th,
.table-condensed > tfoot > tr > th,
.table-condensed > thead > tr > td,
.table-condensed > tbody > tr > td,
.table-condensed > tfoot > tr > td {
padding: 5px;
}
.table-bordered {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > tbody > tr > th,
.table-bordered > tfoot > tr > th,
.table-bordered > thead > tr > td,
.table-bordered > tbody > tr > td,
.table-bordered > tfoot > tr > td {
border: 1px solid #ddd;
}
.table-bordered > thead > tr > th,
.table-bordered > thead > tr > td {
border-bottom-width: 2px;
}
.table-striped > tbody > tr:nth-of-type(odd) {
background-color: #f9f9f9;
}
.table-hover > tbody > tr:hover {
background-color: #f5f5f5;
}
table col[class*="col-"] {
position: static;
display: table-column;
float: none;
}
table td[class*="col-"],
table th[class*="col-"] {
position: static;
display: table-cell;
float: none;
}
.table > thead > tr > td.active,
.table > tbody > tr > td.active,
.table > tfoot > tr > td.active,
.table > thead > tr > th.active,
.table > tbody > tr > th.active,
.table > tfoot > tr > th.active,
.table > thead > tr.active > td,
.table > tbody > tr.active > td,
.table > tfoot > tr.active > td,
.table > thead > tr.active > th,
.table > tbody > tr.active > th,
.table > tfoot > tr.active > th {
background-color: #f5f5f5;
}
.table-hover > tbody > tr > td.active:hover,
.table-hover > tbody > tr > th.active:hover,
.table-hover > tbody > tr.active:hover > td,
.table-hover > tbody > tr:hover > .active,
.table-hover > tbody > tr.active:hover > th {
background-color: #e8e8e8;
}
.table > thead > tr > td.success,
.table > tbody > tr > td.success,
.table > tfoot > tr > td.success,
.table > thead > tr > th.success,
.table > tbody > tr > th.success,
.table > tfoot > tr > th.success,
.table > thead > tr.success > td,
.table > tbody > tr.success > td,
.table > tfoot > tr.success > td,
.table > thead > tr.success > th,
.table > tbody > tr.success > th,
.table > tfoot > tr.success > th {
background-color: #dff0d8;
}
.table-hover > tbody > tr > td.success:hover,
.table-hover > tbody > tr > th.success:hover,
.table-hover > tbody > tr.success:hover > td,
.table-hover > tbody > tr:hover > .success,
.table-hover > tbody > tr.success:hover > th {
background-color: #d0e9c6;
}
.table > thead > tr > td.info,
.table > tbody > tr > td.info,
.table > tfoot > tr > td.info,
.table > thead > tr > th.info,
.table > tbody > tr > th.info,
.table > tfoot > tr > th.info,
.table > thead > tr.info > td,
.table > tbody > tr.info > td,
.table > tfoot > tr.info > td,
.table > thead > tr.info > th,
.table > tbody > tr.info > th,
.table > tfoot > tr.info > th {
background-color: #d9edf7;
}
.table-hover > tbody > tr > td.info:hover,
.table-hover > tbody > tr > th.info:hover,
.table-hover > tbody > tr.info:hover > td,
.table-hover > tbody > tr:hover > .info,
.table-hover > tbody > tr.info:hover > th {
background-color: #c4e3f3;
}
.table > thead > tr > td.warning,
.table > tbody > tr > td.warning,
.table > tfoot > tr > td.warning,
.table > thead > tr > th.warning,
.table > tbody > tr > th.warning,
.table > tfoot > tr > th.warning,
.table > thead > tr.warning > td,
.table > tbody > tr.warning > td,
.table > tfoot > tr.warning > td,
.table > thead > tr.warning > th,
.table > tbody > tr.warning > th,
.table > tfoot > tr.warning > th {
background-color: #fcf8e3;
}
.table-hover > tbody > tr > td.warning:hover,
.table-hover > tbody > tr > th.warning:hover,
.table-hover > tbody > tr.warning:hover > td,
.table-hover > tbody > tr:hover > .warning,
.table-hover > tbody > tr.warning:hover > th {
background-color: #faf2cc;
}
.table > thead > tr > td.danger,
.table > tbody > tr > td.danger,
.table > tfoot > tr > td.danger,
.table > thead > tr > th.danger,
.table > tbody > tr > th.danger,
.table > tfoot > tr > th.danger,
.table > thead > tr.danger > td,
.table > tbody > tr.danger > td,
.table > tfoot > tr.danger > td,
.table > thead > tr.danger > th,
.table > tbody > tr.danger > th,
.table > tfoot > tr.danger > th {
background-color: #f2dede;
}
.table-hover > tbody > tr > td.danger:hover,
.table-hover > tbody > tr > th.danger:hover,
.table-hover > tbody > tr.danger:hover > td,
.table-hover > tbody > tr:hover > .danger,
.table-hover > tbody > tr.danger:hover > th {
background-color: #ebcccc;
}
.table-responsive {
min-height: .01%;
overflow-x: auto;
}
@media screen and (max-width: 767px) {
.table-responsive {
width: 100%;
margin-bottom: 15px;
overflow-y: hidden;
-ms-overflow-style: -ms-autohiding-scrollbar;
border: 1px solid #ddd;
}
.table-responsive > .table {
margin-bottom: 0;
}
.table-responsive > .table > thead > tr > th,
.table-responsive > .table > tbody > tr > th,
.table-responsive > .table > tfoot > tr > th,
.table-responsive > .table > thead > tr > td,
.table-responsive > .table > tbody > tr > td,
.table-responsive > .table > tfoot > tr > td {
white-space: nowrap;
}
.table-responsive > .table-bordered {
border: 0;
}
.table-responsive > .table-bordered > thead > tr > th:first-child,
.table-responsive > .table-bordered > tbody > tr > th:first-child,
.table-responsive > .table-bordered > tfoot > tr > th:first-child,
.table-responsive > .table-bordered > thead > tr > td:first-child,
.table-responsive > .table-bordered > tbody > tr > td:first-child,
.table-responsive > .table-bordered > tfoot > tr > td:first-child {
border-left: 0;
}
.table-responsive > .table-bordered > thead > tr > th:last-child,
.table-responsive > .table-bordered > tbody > tr > th:last-child,
.table-responsive > .table-bordered > tfoot > tr > th:last-child,
.table-responsive > .table-bordered > thead > tr > td:last-child,
.table-responsive > .table-bordered > tbody > tr > td:last-child,
.table-responsive > .table-bordered > tfoot > tr > td:last-child {
border-right: 0;
}
.table-responsive > .table-bordered > tbody > tr:last-child > th,
.table-responsive > .table-bordered > tfoot > tr:last-child > th,
.table-responsive > .table-bordered > tbody > tr:last-child > td,
.table-responsive > .table-bordered > tfoot > tr:last-child > td {
border-bottom: 0;
}
}
fieldset {
min-width: 0;
padding: 0;
margin: 0;
border: 0;
}
legend {
display: block;
width: 100%;
padding: 0;
margin-bottom: 20px;
font-size: 21px;
line-height: inherit;
color: #333;
border: 0;
border-bottom: 1px solid #e5e5e5;
}
label {
display: inline-block;
max-width: 100%;
margin-bottom: 5px;
font-weight: bold;
}
input[type="search"] {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
input[type="radio"],
input[type="checkbox"] {
margin: 4px 0 0;
margin-top: 1px \9;
line-height: normal;
}
input[type="file"] {
display: block;
}
input[type="range"] {
display: block;
width: 100%;
}
select[multiple],
select[size] {
height: auto;
}
input[type="file"]:focus,
input[type="radio"]:focus,
input[type="checkbox"]:focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
output {
display: block;
padding-top: 7px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
}
.form-control {
display: block;
width: 100%;
height: 34px;
padding: 6px 12px;
font-size: 14px;
line-height: 1.42857143;
color: #555;
background-color: #fff;
background-image: none;
border: 1px solid #ccc;
border-radius: 4px;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
-webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;
-o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
}
.form-control:focus {
border-color: #66afe9;
outline: 0;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);
}
.form-control::-moz-placeholder {
color: #999;
opacity: 1;
}
.form-control:-ms-input-placeholder {
color: #999;
}
.form-control::-webkit-input-placeholder {
color: #999;
}
.form-control::-ms-expand {
background-color: transparent;
border: 0;
}
.form-control[disabled],
.form-control[readonly],
fieldset[disabled] .form-control {
background-color: #eee;
opacity: 1;
}
.form-control[disabled],
fieldset[disabled] .form-control {
cursor: not-allowed;
}
textarea.form-control {
height: auto;
}
input[type="search"] {
-webkit-appearance: none;
}
@media screen and (-webkit-min-device-pixel-ratio: 0) {
input[type="date"].form-control,
input[type="time"].form-control,
input[type="datetime-local"].form-control,
input[type="month"].form-control {
line-height: 34px;
}
input[type="date"].input-sm,
input[type="time"].input-sm,
input[type="datetime-local"].input-sm,
input[type="month"].input-sm,
.input-group-sm input[type="date"],
.input-group-sm input[type="time"],
.input-group-sm input[type="datetime-local"],
.input-group-sm input[type="month"] {
line-height: 30px;
}
input[type="date"].input-lg,
input[type="time"].input-lg,
input[type="datetime-local"].input-lg,
input[type="month"].input-lg,
.input-group-lg input[type="date"],
.input-group-lg input[type="time"],
.input-group-lg input[type="datetime-local"],
.input-group-lg input[type="month"] {
line-height: 46px;
}
}
.form-group {
margin-bottom: 15px;
}
.radio,
.checkbox {
position: relative;
display: block;
margin-top: 10px;
margin-bottom: 10px;
}
.radio label,
.checkbox label {
min-height: 20px;
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
cursor: pointer;
}
.radio input[type="radio"],
.radio-inline input[type="radio"],
.checkbox input[type="checkbox"],
.checkbox-inline input[type="checkbox"] {
position: absolute;
margin-top: 4px \9;
margin-left: -20px;
}
.radio + .radio,
.checkbox + .checkbox {
margin-top: -5px;
}
.radio-inline,
.checkbox-inline {
position: relative;
display: inline-block;
padding-left: 20px;
margin-bottom: 0;
font-weight: normal;
vertical-align: middle;
cursor: pointer;
}
.radio-inline + .radio-inline,
.checkbox-inline + .checkbox-inline {
margin-top: 0;
margin-left: 10px;
}
input[type="radio"][disabled],
input[type="checkbox"][disabled],
input[type="radio"].disabled,
input[type="checkbox"].disabled,
fieldset[disabled] input[type="radio"],
fieldset[disabled] input[type="checkbox"] {
cursor: not-allowed;
}
.radio-inline.disabled,
.checkbox-inline.disabled,
fieldset[disabled] .radio-inline,
fieldset[disabled] .checkbox-inline {
cursor: not-allowed;
}
.radio.disabled label,
.checkbox.disabled label,
fieldset[disabled] .radio label,
fieldset[disabled] .checkbox label {
cursor: not-allowed;
}
.form-control-static {
min-height: 34px;
padding-top: 7px;
padding-bottom: 7px;
margin-bottom: 0;
}
.form-control-static.input-lg,
.form-control-static.input-sm {
padding-right: 0;
padding-left: 0;
}
.input-sm {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
select.input-sm {
height: 30px;
line-height: 30px;
}
textarea.input-sm,
select[multiple].input-sm {
height: auto;
}
.form-group-sm .form-control {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.form-group-sm select.form-control {
height: 30px;
line-height: 30px;
}
.form-group-sm textarea.form-control,
.form-group-sm select[multiple].form-control {
height: auto;
}
.form-group-sm .form-control-static {
height: 30px;
min-height: 32px;
padding: 6px 10px;
font-size: 12px;
line-height: 1.5;
}
.input-lg {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
select.input-lg {
height: 46px;
line-height: 46px;
}
textarea.input-lg,
select[multiple].input-lg {
height: auto;
}
.form-group-lg .form-control {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
.form-group-lg select.form-control {
height: 46px;
line-height: 46px;
}
.form-group-lg textarea.form-control,
.form-group-lg select[multiple].form-control {
height: auto;
}
.form-group-lg .form-control-static {
height: 46px;
min-height: 38px;
padding: 11px 16px;
font-size: 18px;
line-height: 1.3333333;
}
.has-feedback {
position: relative;
}
.has-feedback .form-control {
padding-right: 42.5px;
}
.form-control-feedback {
position: absolute;
top: 0;
right: 0;
z-index: 2;
display: block;
width: 34px;
height: 34px;
line-height: 34px;
text-align: center;
pointer-events: none;
}
.input-lg + .form-control-feedback,
.input-group-lg + .form-control-feedback,
.form-group-lg .form-control + .form-control-feedback {
width: 46px;
height: 46px;
line-height: 46px;
}
.input-sm + .form-control-feedback,
.input-group-sm + .form-control-feedback,
.form-group-sm .form-control + .form-control-feedback {
width: 30px;
height: 30px;
line-height: 30px;
}
.has-success .help-block,
.has-success .control-label,
.has-success .radio,
.has-success .checkbox,
.has-success .radio-inline,
.has-success .checkbox-inline,
.has-success.radio label,
.has-success.checkbox label,
.has-success.radio-inline label,
.has-success.checkbox-inline label {
color: #3c763d;
}
.has-success .form-control {
border-color: #3c763d;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-success .form-control:focus {
border-color: #2b542c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;
}
.has-success .input-group-addon {
color: #3c763d;
background-color: #dff0d8;
border-color: #3c763d;
}
.has-success .form-control-feedback {
color: #3c763d;
}
.has-warning .help-block,
.has-warning .control-label,
.has-warning .radio,
.has-warning .checkbox,
.has-warning .radio-inline,
.has-warning .checkbox-inline,
.has-warning.radio label,
.has-warning.checkbox label,
.has-warning.radio-inline label,
.has-warning.checkbox-inline label {
color: #8a6d3b;
}
.has-warning .form-control {
border-color: #8a6d3b;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-warning .form-control:focus {
border-color: #66512c;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;
}
.has-warning .input-group-addon {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #8a6d3b;
}
.has-warning .form-control-feedback {
color: #8a6d3b;
}
.has-error .help-block,
.has-error .control-label,
.has-error .radio,
.has-error .checkbox,
.has-error .radio-inline,
.has-error .checkbox-inline,
.has-error.radio label,
.has-error.checkbox label,
.has-error.radio-inline label,
.has-error.checkbox-inline label {
color: #a94442;
}
.has-error .form-control {
border-color: #a94442;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);
}
.has-error .form-control:focus {
border-color: #843534;
-webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;
}
.has-error .input-group-addon {
color: #a94442;
background-color: #f2dede;
border-color: #a94442;
}
.has-error .form-control-feedback {
color: #a94442;
}
.has-feedback label ~ .form-control-feedback {
top: 25px;
}
.has-feedback label.sr-only ~ .form-control-feedback {
top: 0;
}
.help-block {
display: block;
margin-top: 5px;
margin-bottom: 10px;
color: #737373;
}
@media (min-width: 768px) {
.form-inline .form-group {
display: inline-block;
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .form-control {
display: inline-block;
width: auto;
vertical-align: middle;
}
.form-inline .form-control-static {
display: inline-block;
}
.form-inline .input-group {
display: inline-table;
vertical-align: middle;
}
.form-inline .input-group .input-group-addon,
.form-inline .input-group .input-group-btn,
.form-inline .input-group .form-control {
width: auto;
}
.form-inline .input-group > .form-control {
width: 100%;
}
.form-inline .control-label {
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .radio,
.form-inline .checkbox {
display: inline-block;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
}
.form-inline .radio label,
.form-inline .checkbox label {
padding-left: 0;
}
.form-inline .radio input[type="radio"],
.form-inline .checkbox input[type="checkbox"] {
position: relative;
margin-left: 0;
}
.form-inline .has-feedback .form-control-feedback {
top: 0;
}
}
.form-horizontal .radio,
.form-horizontal .checkbox,
.form-horizontal .radio-inline,
.form-horizontal .checkbox-inline {
padding-top: 7px;
margin-top: 0;
margin-bottom: 0;
}
.form-horizontal .radio,
.form-horizontal .checkbox {
min-height: 27px;
}
.form-horizontal .form-group {
margin-right: -15px;
margin-left: -15px;
}
@media (min-width: 768px) {
.form-horizontal .control-label {
padding-top: 7px;
margin-bottom: 0;
text-align: right;
}
}
.form-horizontal .has-feedback .form-control-feedback {
right: 15px;
}
@media (min-width: 768px) {
.form-horizontal .form-group-lg .control-label {
padding-top: 11px;
font-size: 18px;
}
}
@media (min-width: 768px) {
.form-horizontal .form-group-sm .control-label {
padding-top: 6px;
font-size: 12px;
}
}
.btn {
display: inline-block;
padding: 6px 12px;
margin-bottom: 0;
font-size: 14px;
font-weight: normal;
line-height: 1.42857143;
text-align: center;
white-space: nowrap;
vertical-align: middle;
-ms-touch-action: manipulation;
touch-action: manipulation;
cursor: pointer;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
background-image: none;
border: 1px solid transparent;
border-radius: 4px;
}
.btn:focus,
.btn:active:focus,
.btn.active:focus,
.btn.focus,
.btn:active.focus,
.btn.active.focus {
outline: 5px auto -webkit-focus-ring-color;
outline-offset: -2px;
}
.btn:hover,
.btn:focus,
.btn.focus {
color: #333;
text-decoration: none;
}
.btn:active,
.btn.active {
background-image: none;
outline: 0;
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn.disabled,
.btn[disabled],
fieldset[disabled] .btn {
cursor: not-allowed;
filter: alpha(opacity=65);
-webkit-box-shadow: none;
box-shadow: none;
opacity: .65;
}
a.btn.disabled,
fieldset[disabled] a.btn {
pointer-events: none;
}
.btn-default {
color: #333;
background-color: #fff;
border-color: #ccc;
}
.btn-default:focus,
.btn-default.focus {
color: #333;
background-color: #e6e6e6;
border-color: #8c8c8c;
}
.btn-default:hover {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
color: #333;
background-color: #e6e6e6;
border-color: #adadad;
}
.btn-default:active:hover,
.btn-default.active:hover,
.open > .dropdown-toggle.btn-default:hover,
.btn-default:active:focus,
.btn-default.active:focus,
.open > .dropdown-toggle.btn-default:focus,
.btn-default:active.focus,
.btn-default.active.focus,
.open > .dropdown-toggle.btn-default.focus {
color: #333;
background-color: #d4d4d4;
border-color: #8c8c8c;
}
.btn-default:active,
.btn-default.active,
.open > .dropdown-toggle.btn-default {
background-image: none;
}
.btn-default.disabled:hover,
.btn-default[disabled]:hover,
fieldset[disabled] .btn-default:hover,
.btn-default.disabled:focus,
.btn-default[disabled]:focus,
fieldset[disabled] .btn-default:focus,
.btn-default.disabled.focus,
.btn-default[disabled].focus,
fieldset[disabled] .btn-default.focus {
background-color: #fff;
border-color: #ccc;
}
.btn-default .badge {
color: #fff;
background-color: #333;
}
.btn-primary {
color: #fff;
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary:focus,
.btn-primary.focus {
color: #fff;
background-color: #286090;
border-color: #122b40;
}
.btn-primary:hover {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
color: #fff;
background-color: #286090;
border-color: #204d74;
}
.btn-primary:active:hover,
.btn-primary.active:hover,
.open > .dropdown-toggle.btn-primary:hover,
.btn-primary:active:focus,
.btn-primary.active:focus,
.open > .dropdown-toggle.btn-primary:focus,
.btn-primary:active.focus,
.btn-primary.active.focus,
.open > .dropdown-toggle.btn-primary.focus {
color: #fff;
background-color: #204d74;
border-color: #122b40;
}
.btn-primary:active,
.btn-primary.active,
.open > .dropdown-toggle.btn-primary {
background-image: none;
}
.btn-primary.disabled:hover,
.btn-primary[disabled]:hover,
fieldset[disabled] .btn-primary:hover,
.btn-primary.disabled:focus,
.btn-primary[disabled]:focus,
fieldset[disabled] .btn-primary:focus,
.btn-primary.disabled.focus,
.btn-primary[disabled].focus,
fieldset[disabled] .btn-primary.focus {
background-color: #337ab7;
border-color: #2e6da4;
}
.btn-primary .badge {
color: #337ab7;
background-color: #fff;
}
.btn-success {
color: #fff;
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-success:focus,
.btn-success.focus {
color: #fff;
background-color: #449d44;
border-color: #255625;
}
.btn-success:hover {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
color: #fff;
background-color: #449d44;
border-color: #398439;
}
.btn-success:active:hover,
.btn-success.active:hover,
.open > .dropdown-toggle.btn-success:hover,
.btn-success:active:focus,
.btn-success.active:focus,
.open > .dropdown-toggle.btn-success:focus,
.btn-success:active.focus,
.btn-success.active.focus,
.open > .dropdown-toggle.btn-success.focus {
color: #fff;
background-color: #398439;
border-color: #255625;
}
.btn-success:active,
.btn-success.active,
.open > .dropdown-toggle.btn-success {
background-image: none;
}
.btn-success.disabled:hover,
.btn-success[disabled]:hover,
fieldset[disabled] .btn-success:hover,
.btn-success.disabled:focus,
.btn-success[disabled]:focus,
fieldset[disabled] .btn-success:focus,
.btn-success.disabled.focus,
.btn-success[disabled].focus,
fieldset[disabled] .btn-success.focus {
background-color: #5cb85c;
border-color: #4cae4c;
}
.btn-success .badge {
color: #5cb85c;
background-color: #fff;
}
.btn-info {
color: #fff;
background-color: #5bc0de;
border-color: #46b8da;
}
.btn-info:focus,
.btn-info.focus {
color: #fff;
background-color: #31b0d5;
border-color: #1b6d85;
}
.btn-info:hover {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
color: #fff;
background-color: #31b0d5;
border-color: #269abc;
}
.btn-info:active:hover,
.btn-info.active:hover,
.open > .dropdown-toggle.btn-info:hover,
.btn-info:active:focus,
.btn-info.active:focus,
.open > .dropdown-toggle.btn-info:focus,
.btn-info:active.focus,
.btn-info.active.focus,
.open > .dropdown-toggle.btn-info.focus {
color: #fff;
background-color: #269abc;
border-color: #1b6d85;
}
.btn-info:active,
.btn-info.active,
.open > .dropdown-toggle.btn-info {
background-image: none;
}
.btn-info.disabled:hover,
.btn-info[disabled]:hover,
fieldset[disabled] .btn-info:hover,
.btn-info.disabled:focus,
.btn-info[disabled]:focus,
fieldset[disabled] .btn-info:focus,
.btn-info.disabled.focus,
.btn-info[disabled].focus,
fieldset[disabled] .btn-info.focus {
background-color: #5bc0de;
border-color: #46b8da;
}
.btn-info .badge {
color: #5bc0de;
background-color: #fff;
}
.btn-warning {
color: #fff;
background-color: #f0ad4e;
border-color: #eea236;
}
.btn-warning:focus,
.btn-warning.focus {
color: #fff;
background-color: #ec971f;
border-color: #985f0d;
}
.btn-warning:hover {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
color: #fff;
background-color: #ec971f;
border-color: #d58512;
}
.btn-warning:active:hover,
.btn-warning.active:hover,
.open > .dropdown-toggle.btn-warning:hover,
.btn-warning:active:focus,
.btn-warning.active:focus,
.open > .dropdown-toggle.btn-warning:focus,
.btn-warning:active.focus,
.btn-warning.active.focus,
.open > .dropdown-toggle.btn-warning.focus {
color: #fff;
background-color: #d58512;
border-color: #985f0d;
}
.btn-warning:active,
.btn-warning.active,
.open > .dropdown-toggle.btn-warning {
background-image: none;
}
.btn-warning.disabled:hover,
.btn-warning[disabled]:hover,
fieldset[disabled] .btn-warning:hover,
.btn-warning.disabled:focus,
.btn-warning[disabled]:focus,
fieldset[disabled] .btn-warning:focus,
.btn-warning.disabled.focus,
.btn-warning[disabled].focus,
fieldset[disabled] .btn-warning.focus {
background-color: #f0ad4e;
border-color: #eea236;
}
.btn-warning .badge {
color: #f0ad4e;
background-color: #fff;
}
.btn-danger {
color: #fff;
background-color: #d9534f;
border-color: #d43f3a;
}
.btn-danger:focus,
.btn-danger.focus {
color: #fff;
background-color: #c9302c;
border-color: #761c19;
}
.btn-danger:hover {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
color: #fff;
background-color: #c9302c;
border-color: #ac2925;
}
.btn-danger:active:hover,
.btn-danger.active:hover,
.open > .dropdown-toggle.btn-danger:hover,
.btn-danger:active:focus,
.btn-danger.active:focus,
.open > .dropdown-toggle.btn-danger:focus,
.btn-danger:active.focus,
.btn-danger.active.focus,
.open > .dropdown-toggle.btn-danger.focus {
color: #fff;
background-color: #ac2925;
border-color: #761c19;
}
.btn-danger:active,
.btn-danger.active,
.open > .dropdown-toggle.btn-danger {
background-image: none;
}
.btn-danger.disabled:hover,
.btn-danger[disabled]:hover,
fieldset[disabled] .btn-danger:hover,
.btn-danger.disabled:focus,
.btn-danger[disabled]:focus,
fieldset[disabled] .btn-danger:focus,
.btn-danger.disabled.focus,
.btn-danger[disabled].focus,
fieldset[disabled] .btn-danger.focus {
background-color: #d9534f;
border-color: #d43f3a;
}
.btn-danger .badge {
color: #d9534f;
background-color: #fff;
}
.btn-link {
font-weight: normal;
color: #337ab7;
border-radius: 0;
}
.btn-link,
.btn-link:active,
.btn-link.active,
.btn-link[disabled],
fieldset[disabled] .btn-link {
background-color: transparent;
-webkit-box-shadow: none;
box-shadow: none;
}
.btn-link,
.btn-link:hover,
.btn-link:focus,
.btn-link:active {
border-color: transparent;
}
.btn-link:hover,
.btn-link:focus {
color: #23527c;
text-decoration: underline;
background-color: transparent;
}
.btn-link[disabled]:hover,
fieldset[disabled] .btn-link:hover,
.btn-link[disabled]:focus,
fieldset[disabled] .btn-link:focus {
color: #777;
text-decoration: none;
}
.btn-lg,
.btn-group-lg > .btn {
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
.btn-sm,
.btn-group-sm > .btn {
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.btn-xs,
.btn-group-xs > .btn {
padding: 1px 5px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
.btn-block {
display: block;
width: 100%;
}
.btn-block + .btn-block {
margin-top: 5px;
}
input[type="submit"].btn-block,
input[type="reset"].btn-block,
input[type="button"].btn-block {
width: 100%;
}
.fade {
opacity: 0;
-webkit-transition: opacity .15s linear;
-o-transition: opacity .15s linear;
transition: opacity .15s linear;
}
.fade.in {
opacity: 1;
}
.collapse {
display: none;
}
.collapse.in {
display: block;
}
tr.collapse.in {
display: table-row;
}
tbody.collapse.in {
display: table-row-group;
}
.collapsing {
position: relative;
height: 0;
overflow: hidden;
-webkit-transition-timing-function: ease;
-o-transition-timing-function: ease;
transition-timing-function: ease;
-webkit-transition-duration: .35s;
-o-transition-duration: .35s;
transition-duration: .35s;
-webkit-transition-property: height, visibility;
-o-transition-property: height, visibility;
transition-property: height, visibility;
}
.caret {
display: inline-block;
width: 0;
height: 0;
margin-left: 2px;
vertical-align: middle;
border-top: 4px dashed;
border-top: 4px solid \9;
border-right: 4px solid transparent;
border-left: 4px solid transparent;
}
.dropup,
.dropdown {
position: relative;
}
.dropdown-toggle:focus {
outline: 0;
}
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 160px;
padding: 5px 0;
margin: 2px 0 0;
font-size: 14px;
text-align: left;
list-style: none;
background-color: #fff;
-webkit-background-clip: padding-box;
background-clip: padding-box;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .15);
border-radius: 4px;
-webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
box-shadow: 0 6px 12px rgba(0, 0, 0, .175);
}
.dropdown-menu.pull-right {
right: 0;
left: auto;
}
.dropdown-menu .divider {
height: 1px;
margin: 9px 0;
overflow: hidden;
background-color: #e5e5e5;
}
.dropdown-menu > li > a {
display: block;
padding: 3px 20px;
clear: both;
font-weight: normal;
line-height: 1.42857143;
color: #333;
white-space: nowrap;
}
.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
color: #262626;
text-decoration: none;
background-color: #f5f5f5;
}
.dropdown-menu > .active > a,
.dropdown-menu > .active > a:hover,
.dropdown-menu > .active > a:focus {
color: #fff;
text-decoration: none;
background-color: #337ab7;
outline: 0;
}
.dropdown-menu > .disabled > a,
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
color: #777;
}
.dropdown-menu > .disabled > a:hover,
.dropdown-menu > .disabled > a:focus {
text-decoration: none;
cursor: not-allowed;
background-color: transparent;
background-image: none;
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
}
.open > .dropdown-menu {
display: block;
}
.open > a {
outline: 0;
}
.dropdown-menu-right {
right: 0;
left: auto;
}
.dropdown-menu-left {
right: auto;
left: 0;
}
.dropdown-header {
display: block;
padding: 3px 20px;
font-size: 12px;
line-height: 1.42857143;
color: #777;
white-space: nowrap;
}
.dropdown-backdrop {
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 990;
}
.pull-right > .dropdown-menu {
right: 0;
left: auto;
}
.dropup .caret,
.navbar-fixed-bottom .dropdown .caret {
content: "";
border-top: 0;
border-bottom: 4px dashed;
border-bottom: 4px solid \9;
}
.dropup .dropdown-menu,
.navbar-fixed-bottom .dropdown .dropdown-menu {
top: auto;
bottom: 100%;
margin-bottom: 2px;
}
@media (min-width: 768px) {
.navbar-right .dropdown-menu {
right: 0;
left: auto;
}
.navbar-right .dropdown-menu-left {
right: auto;
left: 0;
}
}
.btn-group,
.btn-group-vertical {
position: relative;
display: inline-block;
vertical-align: middle;
}
.btn-group > .btn,
.btn-group-vertical > .btn {
position: relative;
float: left;
}
.btn-group > .btn:hover,
.btn-group-vertical > .btn:hover,
.btn-group > .btn:focus,
.btn-group-vertical > .btn:focus,
.btn-group > .btn:active,
.btn-group-vertical > .btn:active,
.btn-group > .btn.active,
.btn-group-vertical > .btn.active {
z-index: 2;
}
.btn-group .btn + .btn,
.btn-group .btn + .btn-group,
.btn-group .btn-group + .btn,
.btn-group .btn-group + .btn-group {
margin-left: -1px;
}
.btn-toolbar {
margin-left: -5px;
}
.btn-toolbar .btn,
.btn-toolbar .btn-group,
.btn-toolbar .input-group {
float: left;
}
.btn-toolbar > .btn,
.btn-toolbar > .btn-group,
.btn-toolbar > .input-group {
margin-left: 5px;
}
.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
border-radius: 0;
}
.btn-group > .btn:first-child {
margin-left: 0;
}
.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.btn-group > .btn:last-child:not(:first-child),
.btn-group > .dropdown-toggle:not(:first-child) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group > .btn-group {
float: left;
}
.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group .dropdown-toggle:active,
.btn-group.open .dropdown-toggle {
outline: 0;
}
.btn-group > .btn + .dropdown-toggle {
padding-right: 8px;
padding-left: 8px;
}
.btn-group > .btn-lg + .dropdown-toggle {
padding-right: 12px;
padding-left: 12px;
}
.btn-group.open .dropdown-toggle {
-webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);
}
.btn-group.open .dropdown-toggle.btn-link {
-webkit-box-shadow: none;
box-shadow: none;
}
.btn .caret {
margin-left: 0;
}
.btn-lg .caret {
border-width: 5px 5px 0;
border-bottom-width: 0;
}
.dropup .btn-lg .caret {
border-width: 0 5px 5px;
}
.btn-group-vertical > .btn,
.btn-group-vertical > .btn-group,
.btn-group-vertical > .btn-group > .btn {
display: block;
float: none;
width: 100%;
max-width: 100%;
}
.btn-group-vertical > .btn-group > .btn {
float: none;
}
.btn-group-vertical > .btn + .btn,
.btn-group-vertical > .btn + .btn-group,
.btn-group-vertical > .btn-group + .btn,
.btn-group-vertical > .btn-group + .btn-group {
margin-top: -1px;
margin-left: 0;
}
.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
border-radius: 0;
}
.btn-group-vertical > .btn:first-child:not(:last-child) {
border-top-left-radius: 4px;
border-top-right-radius: 4px;
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn:last-child:not(:first-child) {
border-top-left-radius: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px;
}
.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
border-radius: 0;
}
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
border-bottom-right-radius: 0;
border-bottom-left-radius: 0;
}
.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.btn-group-justified {
display: table;
width: 100%;
table-layout: fixed;
border-collapse: separate;
}
.btn-group-justified > .btn,
.btn-group-justified > .btn-group {
display: table-cell;
float: none;
width: 1%;
}
.btn-group-justified > .btn-group .btn {
width: 100%;
}
.btn-group-justified > .btn-group .dropdown-menu {
left: auto;
}
[data-toggle="buttons"] > .btn input[type="radio"],
[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
[data-toggle="buttons"] > .btn input[type="checkbox"],
[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
position: absolute;
clip: rect(0, 0, 0, 0);
pointer-events: none;
}
.input-group {
position: relative;
display: table;
border-collapse: separate;
}
.input-group[class*="col-"] {
float: none;
padding-right: 0;
padding-left: 0;
}
.input-group .form-control {
position: relative;
z-index: 2;
float: left;
width: 100%;
margin-bottom: 0;
}
.input-group .form-control:focus {
z-index: 3;
}
.input-group-lg > .form-control,
.input-group-lg > .input-group-addon,
.input-group-lg > .input-group-btn > .btn {
height: 46px;
padding: 10px 16px;
font-size: 18px;
line-height: 1.3333333;
border-radius: 6px;
}
select.input-group-lg > .form-control,
select.input-group-lg > .input-group-addon,
select.input-group-lg > .input-group-btn > .btn {
height: 46px;
line-height: 46px;
}
textarea.input-group-lg > .form-control,
textarea.input-group-lg > .input-group-addon,
textarea.input-group-lg > .input-group-btn > .btn,
select[multiple].input-group-lg > .form-control,
select[multiple].input-group-lg > .input-group-addon,
select[multiple].input-group-lg > .input-group-btn > .btn {
height: auto;
}
.input-group-sm > .form-control,
.input-group-sm > .input-group-addon,
.input-group-sm > .input-group-btn > .btn {
height: 30px;
padding: 5px 10px;
font-size: 12px;
line-height: 1.5;
border-radius: 3px;
}
select.input-group-sm > .form-control,
select.input-group-sm > .input-group-addon,
select.input-group-sm > .input-group-btn > .btn {
height: 30px;
line-height: 30px;
}
textarea.input-group-sm > .form-control,
textarea.input-group-sm > .input-group-addon,
textarea.input-group-sm > .input-group-btn > .btn,
select[multiple].input-group-sm > .form-control,
select[multiple].input-group-sm > .input-group-addon,
select[multiple].input-group-sm > .input-group-btn > .btn {
height: auto;
}
.input-group-addon,
.input-group-btn,
.input-group .form-control {
display: table-cell;
}
.input-group-addon:not(:first-child):not(:last-child),
.input-group-btn:not(:first-child):not(:last-child),
.input-group .form-control:not(:first-child):not(:last-child) {
border-radius: 0;
}
.input-group-addon,
.input-group-btn {
width: 1%;
white-space: nowrap;
vertical-align: middle;
}
.input-group-addon {
padding: 6px 12px;
font-size: 14px;
font-weight: normal;
line-height: 1;
color: #555;
text-align: center;
background-color: #eee;
border: 1px solid #ccc;
border-radius: 4px;
}
.input-group-addon.input-sm {
padding: 5px 10px;
font-size: 12px;
border-radius: 3px;
}
.input-group-addon.input-lg {
padding: 10px 16px;
font-size: 18px;
border-radius: 6px;
}
.input-group-addon input[type="radio"],
.input-group-addon input[type="checkbox"] {
margin-top: 0;
}
.input-group .form-control:first-child,
.input-group-addon:first-child,
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group > .btn,
.input-group-btn:first-child > .dropdown-toggle,
.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),
.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.input-group-addon:first-child {
border-right: 0;
}
.input-group .form-control:last-child,
.input-group-addon:last-child,
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group > .btn,
.input-group-btn:last-child > .dropdown-toggle,
.input-group-btn:first-child > .btn:not(:first-child),
.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.input-group-addon:last-child {
border-left: 0;
}
.input-group-btn {
position: relative;
font-size: 0;
white-space: nowrap;
}
.input-group-btn > .btn {
position: relative;
}
.input-group-btn > .btn + .btn {
margin-left: -1px;
}
.input-group-btn > .btn:hover,
.input-group-btn > .btn:focus,
.input-group-btn > .btn:active {
z-index: 2;
}
.input-group-btn:first-child > .btn,
.input-group-btn:first-child > .btn-group {
margin-right: -1px;
}
.input-group-btn:last-child > .btn,
.input-group-btn:last-child > .btn-group {
z-index: 2;
margin-left: -1px;
}
.nav {
padding-left: 0;
margin-bottom: 0;
list-style: none;
}
.nav > li {
position: relative;
display: block;
}
.nav > li > a {
position: relative;
display: block;
padding: 10px 15px;
}
.nav > li > a:hover,
.nav > li > a:focus {
text-decoration: none;
background-color: #eee;
}
.nav > li.disabled > a {
color: #777;
}
.nav > li.disabled > a:hover,
.nav > li.disabled > a:focus {
color: #777;
text-decoration: none;
cursor: not-allowed;
background-color: transparent;
}
.nav .open > a,
.nav .open > a:hover,
.nav .open > a:focus {
background-color: #eee;
border-color: #337ab7;
}
.nav .nav-divider {
height: 1px;
margin: 9px 0;
overflow: hidden;
background-color: #e5e5e5;
}
.nav > li > a > img {
max-width: none;
}
.nav-tabs {
border-bottom: 1px solid #ddd;
}
.nav-tabs > li {
float: left;
margin-bottom: -1px;
}
.nav-tabs > li > a {
margin-right: 2px;
line-height: 1.42857143;
border: 1px solid transparent;
border-radius: 4px 4px 0 0;
}
.nav-tabs > li > a:hover {
border-color: #eee #eee #ddd;
}
.nav-tabs > li.active > a,
.nav-tabs > li.active > a:hover,
.nav-tabs > li.active > a:focus {
color: #555;
cursor: default;
background-color: #fff;
border: 1px solid #ddd;
border-bottom-color: transparent;
}
.nav-tabs.nav-justified {
width: 100%;
border-bottom: 0;
}
.nav-tabs.nav-justified > li {
float: none;
}
.nav-tabs.nav-justified > li > a {
margin-bottom: 5px;
text-align: center;
}
.nav-tabs.nav-justified > .dropdown .dropdown-menu {
top: auto;
left: auto;
}
@media (min-width: 768px) {
.nav-tabs.nav-justified > li {
display: table-cell;
width: 1%;
}
.nav-tabs.nav-justified > li > a {
margin-bottom: 0;
}
}
.nav-tabs.nav-justified > li > a {
margin-right: 0;
border-radius: 4px;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs.nav-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
}
.nav-tabs.nav-justified > .active > a,
.nav-tabs.nav-justified > .active > a:hover,
.nav-tabs.nav-justified > .active > a:focus {
border-bottom-color: #fff;
}
}
.nav-pills > li {
float: left;
}
.nav-pills > li > a {
border-radius: 4px;
}
.nav-pills > li + li {
margin-left: 2px;
}
.nav-pills > li.active > a,
.nav-pills > li.active > a:hover,
.nav-pills > li.active > a:focus {
color: #fff;
background-color: #337ab7;
}
.nav-stacked > li {
float: none;
}
.nav-stacked > li + li {
margin-top: 2px;
margin-left: 0;
}
.nav-justified {
width: 100%;
}
.nav-justified > li {
float: none;
}
.nav-justified > li > a {
margin-bottom: 5px;
text-align: center;
}
.nav-justified > .dropdown .dropdown-menu {
top: auto;
left: auto;
}
@media (min-width: 768px) {
.nav-justified > li {
display: table-cell;
width: 1%;
}
.nav-justified > li > a {
margin-bottom: 0;
}
}
.nav-tabs-justified {
border-bottom: 0;
}
.nav-tabs-justified > li > a {
margin-right: 0;
border-radius: 4px;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
border: 1px solid #ddd;
}
@media (min-width: 768px) {
.nav-tabs-justified > li > a {
border-bottom: 1px solid #ddd;
border-radius: 4px 4px 0 0;
}
.nav-tabs-justified > .active > a,
.nav-tabs-justified > .active > a:hover,
.nav-tabs-justified > .active > a:focus {
border-bottom-color: #fff;
}
}
.tab-content > .tab-pane {
display: none;
}
.tab-content > .active {
display: block;
}
.nav-tabs .dropdown-menu {
margin-top: -1px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.navbar {
position: relative;
min-height: 50px;
margin-bottom: 20px;
border: 1px solid transparent;
}
@media (min-width: 768px) {
.navbar {
border-radius: 4px;
}
}
@media (min-width: 768px) {
.navbar-header {
float: left;
}
}
.navbar-collapse {
padding-right: 15px;
padding-left: 15px;
overflow-x: visible;
-webkit-overflow-scrolling: touch;
border-top: 1px solid transparent;
-webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);
}
.navbar-collapse.in {
overflow-y: auto;
}
@media (min-width: 768px) {
.navbar-collapse {
width: auto;
border-top: 0;
-webkit-box-shadow: none;
box-shadow: none;
}
.navbar-collapse.collapse {
display: block !important;
height: auto !important;
padding-bottom: 0;
overflow: visible !important;
}
.navbar-collapse.in {
overflow-y: visible;
}
.navbar-fixed-top .navbar-collapse,
.navbar-static-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
padding-right: 0;
padding-left: 0;
}
}
.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
max-height: 340px;
}
@media (max-device-width: 480px) and (orientation: landscape) {
.navbar-fixed-top .navbar-collapse,
.navbar-fixed-bottom .navbar-collapse {
max-height: 200px;
}
}
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
margin-right: -15px;
margin-left: -15px;
}
@media (min-width: 768px) {
.container > .navbar-header,
.container-fluid > .navbar-header,
.container > .navbar-collapse,
.container-fluid > .navbar-collapse {
margin-right: 0;
margin-left: 0;
}
}
.navbar-static-top {
z-index: 1000;
border-width: 0 0 1px;
}
@media (min-width: 768px) {
.navbar-static-top {
border-radius: 0;
}
}
.navbar-fixed-top,
.navbar-fixed-bottom {
position: fixed;
right: 0;
left: 0;
z-index: 1030;
}
@media (min-width: 768px) {
.navbar-fixed-top,
.navbar-fixed-bottom {
border-radius: 0;
}
}
.navbar-fixed-top {
top:
gitextract_cteq_eaa/ ├── .autod.conf.js ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app/ │ ├── controller/ │ │ ├── api/ │ │ │ ├── application.js │ │ │ ├── assets.js │ │ │ ├── build.js │ │ │ ├── commtask.js │ │ │ ├── console.js │ │ │ ├── email.js │ │ │ ├── environment.js │ │ │ ├── files.js │ │ │ ├── logs.js │ │ │ ├── qiniu.js │ │ │ ├── team.js │ │ │ ├── user.js │ │ │ └── util.js │ │ ├── home.js │ │ └── web.js │ ├── extend/ │ │ └── application.js │ ├── io/ │ │ ├── controller/ │ │ │ └── nsp.js │ │ └── middleware/ │ │ └── auth.js │ ├── middleware/ │ │ └── token_required.js │ ├── model/ │ │ ├── application.js │ │ ├── assets.js │ │ ├── commtask.js │ │ ├── email.js │ │ ├── environment.js │ │ ├── logs.js │ │ ├── team.js │ │ └── user.js │ ├── public/ │ │ ├── css/ │ │ │ ├── base.css │ │ │ └── home.css │ │ ├── iconfont/ │ │ │ └── iconfont.css │ │ ├── js/ │ │ │ ├── config.js │ │ │ ├── util.js │ │ │ ├── vue-components.js │ │ │ └── vue-filters.js │ │ └── lib/ │ │ ├── bootstrap/ │ │ │ ├── css/ │ │ │ │ ├── bootstrap-theme.css │ │ │ │ └── bootstrap.css │ │ │ └── js/ │ │ │ ├── bootstrap.js │ │ │ └── npm.js │ │ ├── page/ │ │ │ ├── page.css │ │ │ └── page.js │ │ └── popup/ │ │ ├── popup.css │ │ └── popup.js │ ├── router/ │ │ ├── api.js │ │ └── home.js │ ├── router.js │ ├── service/ │ │ ├── application.js │ │ ├── assets.js │ │ ├── build.js │ │ ├── commtask.js │ │ ├── console.js │ │ ├── email.js │ │ ├── environment.js │ │ ├── files.js │ │ ├── logs.js │ │ ├── qiniu.js │ │ ├── team.js │ │ ├── user.js │ │ └── util.js │ ├── tempFile/ │ │ └── install-node.sh │ ├── util/ │ │ ├── sftp.js │ │ ├── socket.js │ │ ├── ssh2.js │ │ └── utils.js │ └── view/ │ ├── appconfig.html │ ├── application.html │ ├── assets.html │ ├── assetsconfig.html │ ├── build.html │ ├── buildprocess.html │ ├── commtask.html │ ├── console.html │ ├── email.html │ ├── environment.html │ ├── footer.html │ ├── header.html │ ├── home.html │ ├── layout.html │ ├── login.html │ ├── logs.html │ ├── reduction.html │ ├── side.html │ ├── team.html │ └── user.html ├── app.js ├── appveyor.yml ├── config/ │ ├── config.default.js │ ├── config.prod.js │ └── plugin.js ├── lib/ │ └── plugin/ │ └── egg-email/ │ ├── LICENSE │ ├── README.md │ ├── app.js │ ├── config/ │ │ └── config.default.js │ ├── lib/ │ │ └── email.js │ └── package.json └── package.json
SYMBOL INDEX (254 symbols across 42 files)
FILE: app/controller/api/application.js
class ApplicationController (line 5) | class ApplicationController extends Controller {
method list (line 7) | async list() {
method all (line 25) | async all() {
method handle (line 35) | async handle() {
method setStatus (line 62) | async setStatus() {
method delete (line 77) | async delete() {
method distribution (line 91) | async distribution() {
method itemdetail (line 108) | async itemdetail() {
method updateConfigs (line 123) | async updateConfigs() {
method handleEmail (line 139) | async handleEmail() {
FILE: app/controller/api/assets.js
class AssetsController (line 5) | class AssetsController extends Controller {
method list (line 7) | async list() {
method all (line 23) | async all() {
method handle (line 33) | async handle() {
method setStatus (line 69) | async setStatus() {
method delete (line 84) | async delete() {
FILE: app/controller/api/build.js
class BuildController (line 5) | class BuildController extends Controller {
method generateBuildConfig (line 8) | async generateBuildConfig() {
method backupApplications (line 27) | async backupApplications() {
method buildApplicationed (line 46) | async buildApplicationed() {
method reductionApplications (line 57) | async reductionApplications() {
FILE: app/controller/api/commtask.js
class CommtaskController (line 5) | class CommtaskController extends Controller {
method list (line 7) | async list() {
method handle (line 17) | async handle() {
method delete (line 37) | async delete() {
FILE: app/controller/api/console.js
class ConsoleController (line 5) | class ConsoleController extends Controller {
method getAssetSshKey (line 8) | async getAssetSshKey() {
method handleShellTasks (line 25) | async handleShellTasks() {
FILE: app/controller/api/email.js
class EmailController (line 5) | class EmailController extends Controller {
method list (line 7) | async list() {
method handle (line 22) | async handle() {
method setStatus (line 44) | async setStatus() {
method delete (line 59) | async delete() {
FILE: app/controller/api/environment.js
class TeamController (line 5) | class TeamController extends Controller {
method list (line 7) | async list() {
method handle (line 21) | async handle() {
method delete (line 41) | async delete() {
FILE: app/controller/api/files.js
class FilesController (line 5) | class FilesController extends Controller {
method updatefile (line 8) | async updatefile() {
method addfile (line 24) | async addfile() {
FILE: app/controller/api/logs.js
class LogsController (line 5) | class LogsController extends Controller {
method list (line 7) | async list() {
method handle (line 24) | async handle() {
method setStatus (line 46) | async setStatus() {
method delete (line 61) | async delete() {
FILE: app/controller/api/qiniu.js
class QiniuController (line 5) | class QiniuController extends Controller {
method getToken (line 7) | async getToken() {
FILE: app/controller/api/team.js
class TeamController (line 5) | class TeamController extends Controller {
method list (line 7) | async list() {
method handle (line 22) | async handle() {
method setStatus (line 44) | async setStatus() {
method delete (line 59) | async delete() {
FILE: app/controller/api/user.js
class UserController (line 5) | class UserController extends Controller {
method login (line 8) | async login() {
method register (line 25) | async register() {
method logout (line 42) | async logout() {
method getUserList (line 57) | async getUserList() {
method handle (line 72) | async handle() {
method setStatus (line 95) | async setStatus() {
method delete (line 111) | async delete() {
method setToken (line 126) | async setToken() {
FILE: app/controller/api/util.js
class UtilController (line 5) | class UtilController extends Controller {
method getAssetSshKey (line 8) | async getAssetSshKey() {
method handleShellTasks (line 25) | async handleShellTasks() {
FILE: app/controller/home.js
class HomeController (line 5) | class HomeController extends Controller {
method index (line 6) | async index() {
FILE: app/controller/web.js
class WebController (line 6) | class WebController extends Controller {
method home (line 8) | async home() {
method team (line 23) | async team() {
method application (line 31) | async application() {
method appconfig (line 39) | async appconfig() {
method assets (line 47) | async assets() {
method environment (line 55) | async environment() {
method emails (line 63) | async emails() {
method build (line 71) | async build() {
method buildprocess (line 79) | async buildprocess() {
method assetsconfig (line 87) | async assetsconfig() {
method commtask (line 95) | async commtask() {
method console (line 103) | async console() {
method logs (line 111) | async logs() {
method reduction (line 119) | async reduction() {
method user (line 127) | async user() {
method login (line 135) | async login() {
FILE: app/extend/application.js
method randomString (line 6) | randomString(len) {
method signwx (line 18) | signwx(json) {
method result (line 49) | result(jn = {}) {
method format (line 56) | format(date, fmt) {
FILE: app/io/controller/nsp.js
class NspController (line 6) | class NspController extends Controller {
method socket (line 8) | async socket() {
method ssh2Client (line 25) | ssh2Client(json = {}) {
method sshOnline (line 80) | async sshOnline(query = {}) {
method buildProcess (line 87) | async buildProcess(query = {}) {
method backUpProject (line 112) | backUpProject(taskItem = {}, assitsItem = {}, backupPath, backupDir) {
FILE: app/public/js/util.js
constant XTEAMLIST (line 25) | let XTEAMLIST = [];
constant MODELTYPE (line 26) | let MODELTYPE = '';
constant SOCKET (line 27) | let SOCKET = null;
constant CONSOLEXTEAM (line 28) | let CONSOLEXTEAM = [];
class utilfn (line 31) | class utilfn {
method constructor (line 33) | constructor() {
method ajax (line 63) | ajax(json) {
method error (line 132) | error(data, json) {
method _error (line 171) | _error(XMLHttpRequest, json) {
method time (line 214) | time() {
method regCombination (line 222) | regCombination(type, numArr) {
method extend (line 284) | extend(json1, json2) {
method showLoading (line 293) | showLoading() {
method hideLoading (line 298) | hideLoading() {
method randomString (line 303) | randomString(len) {
method getQueryString (line 315) | getQueryString(name, hash) {
method getStorage (line 335) | getStorage(type, name) {
method setStorage (line 350) | setStorage(type, name, content) {
method getCheckBoxVal (line 364) | getCheckBoxVal(arr){
method setCheckBoxVal (line 376) | setCheckBoxVal(arr,str){
method goBack (line 390) | goBack(){
method getSearchTime (line 395) | getSearchTime() {
method startSocketXteam (line 413) | startSocketXteam(json = {}) {
method resizeScreen (line 517) | resizeScreen(XTEAMLIST, socket) {
method setSocketXteam (line 523) | setSocketXteam(type, xteamlist = [], socket) {
method socket (line 573) | socket(json = {}) {
method xteam (line 592) | xteam(json = {}){
FILE: app/public/js/vue-components.js
method mounted (line 33) | mounted(){
method timeSure (line 67) | timeSure(){
FILE: app/public/js/vue-filters.js
method toFixed (line 32) | toFixed(val,type=false){
method toSize (line 41) | toSize(val){
method date (line 52) | date(value, gengefu, full) {
method limitTo (line 62) | limitTo(value, num) {
method systemType (line 73) | systemType(val) {
method flow (line 86) | flow(val = 0) {
FILE: app/public/lib/bootstrap/js/bootstrap.js
function transitionEnd (line 34) | function transitionEnd() {
function removeElement (line 126) | function removeElement() {
function Plugin (line 142) | function Plugin(option) {
function Plugin (line 251) | function Plugin(option) {
function Plugin (line 475) | function Plugin(option) {
function getTargetFromTrigger (line 695) | function getTargetFromTrigger($trigger) {
function Plugin (line 707) | function Plugin(option) {
function getParent (line 774) | function getParent($this) {
function clearMenus (line 787) | function clearMenus(e) {
function Plugin (line 880) | function Plugin(option) {
function Plugin (line 1208) | function Plugin(option, _relatedTarget) {
function complete (line 1574) | function complete() {
function Plugin (line 1750) | function Plugin(option) {
function Plugin (line 1859) | function Plugin(option) {
function ScrollSpy (line 1902) | function ScrollSpy(element, options) {
function Plugin (line 2022) | function Plugin(option) {
function next (line 2131) | function next() {
function Plugin (line 2177) | function Plugin(option) {
function Plugin (line 2334) | function Plugin(option) {
FILE: app/public/lib/page/page.js
function Page (line 3) | function Page(json) {
FILE: app/public/lib/popup/popup.js
function PopLayer (line 4) | function PopLayer(){
FILE: app/service/application.js
class ApplicationService (line 6) | class ApplicationService extends Service {
method list (line 9) | async list(pageNo, pageSize, team_code, environ_code, net_type, status...
method all (line 71) | async all() {
method handle (line 86) | async handle(json) {
method setStatus (line 108) | async setStatus(json) {
method delete (line 114) | async delete(_id) {
method distribution (line 119) | async distribution(_id, assets_list = [], net_type) {
method itemdetail (line 125) | async itemdetail(id) {
method updateConfigs (line 129) | async updateConfigs(id, tasklist) {
method handleEmail (line 138) | async handleEmail(id, emaillist) {
FILE: app/service/assets.js
class AssetsService (line 6) | class AssetsService extends Service {
method list (line 9) | async list(pageNo, pageSize, team_code, assets_name, status) {
method all (line 43) | async all() {
method handle (line 59) | async handle(json) {
method setStatus (line 89) | async setStatus(json) {
method delete (line 95) | async delete(_id) {
FILE: app/service/build.js
class BuildService (line 8) | class BuildService extends Service {
method generateBuildConfig (line 11) | async generateBuildConfig(id, taskItem = {}, assetslist = [], user_nam...
method backupApplications (line 47) | async backupApplications(id, taskItem = {}, assetslist = [], user_name) {
method reductionApplications (line 71) | async reductionApplications(id, taskItem = {}, assetslist = [], user_n...
method reductionProject (line 107) | reductionProject(paths, file, asstesItem, taskItem) {
method backUpProject (line 169) | async backUpProject(taskItem, assets, backupPath, backupDir) {
method genConfigsForSsh (line 201) | async genConfigsForSsh(paths, file, asstesItem, taskItem) {
method exec (line 247) | exec(sftp, shell) {
FILE: app/service/commtask.js
class CommtaskService (line 8) | class CommtaskService extends Service {
method list (line 11) | async list() {
method handle (line 19) | async handle(query) {
method delete (line 49) | async delete(id) {
method generateBuildConfig (line 54) | async generateBuildConfig(id, item, assetslist = []) {
FILE: app/service/console.js
class ConsoleService (line 7) | class ConsoleService extends Service {
method getAssetSshKey (line 10) | async getAssetSshKey(query) {
method handleShellTasks (line 30) | async handleShellTasks(query) {
method genConfigsForSsh (line 42) | async genConfigsForSsh(query) {
FILE: app/service/email.js
class EmailService (line 6) | class EmailService extends Service {
method list (line 9) | async list(pageNo, pageSize, status) {
method handle (line 33) | async handle(json) {
method setStatus (line 52) | async setStatus(json) {
method delete (line 58) | async delete(id) {
FILE: app/service/environment.js
class EnvironmentService (line 6) | class EnvironmentService extends Service {
method list (line 9) | async list(pageNo, pageSize) {
method handle (line 30) | async handle(json) {
method delete (line 48) | async delete(id) {
FILE: app/service/files.js
class FilesService (line 9) | class FilesService extends Service {
method addfile (line 12) | async addfile(filename, content, remotePath) {
method updatefile (line 23) | async updatefile(filename, content) {
FILE: app/service/logs.js
class LogsService (line 6) | class LogsService extends Service {
method addLogs (line 9) | async addLogs(json = {}) {
method list (line 23) | async list(pageNo, pageSize, type, name, application_id) {
FILE: app/service/qiniu.js
class QiniuService (line 7) | class QiniuService extends Service {
method init (line 9) | init(){
method getToken (line 16) | getToken(key) {
method getKey (line 29) | getKey(num = 15){
method upload (line 34) | async upload(filePath) {
method uploadFile (line 45) | uploadFile(uptoken, key, localFile) {
FILE: app/service/team.js
class TeamService (line 6) | class TeamService extends Service {
method list (line 9) | async list(pageNo, pageSize, status) {
method handle (line 33) | async handle(json) {
method setStatus (line 52) | async setStatus(json) {
method delete (line 58) | async delete(_id) {
FILE: app/service/user.js
class UserService (line 5) | class UserService extends Service {
method login (line 8) | async login(userName, passWord) {
method logout (line 41) | logout(usertoken) {
method register (line 48) | async register(userName, passWord) {
method getUserInfoForUserName (line 83) | async getUserInfoForUserName(userName) {
method getUserList (line 88) | async getUserList(pageNo, pageSize, userName) {
method handle (line 112) | async handle(json) {
method getUserInfoForUsertoken (line 150) | async getUserInfoForUsertoken(usertoken) {
method setStatus (line 155) | async setStatus(json) {
method delete (line 164) | async delete(id, usertoken) {
method updateUserToken (line 173) | async updateUserToken(opt) {
method finUserForToken (line 190) | async finUserForToken(usertoken) {
method getUserInfoForGithubId (line 203) | async getUserInfoForGithubId(id) {
FILE: app/service/util.js
class UtilService (line 7) | class UtilService extends Service {
method getAssetSshKey (line 10) | async getAssetSshKey(query) {
method handleShellTasks (line 30) | async handleShellTasks(query) {
method genConfigsForSsh (line 42) | async genConfigsForSsh(query) {
FILE: app/util/sftp.js
class Sftp (line 7) | class Sftp {
method constructor (line 8) | constructor() {
method init (line 16) | async init(json = {}) {
method connectStatus (line 24) | async connectStatus() {
method connect (line 33) | async connect() {
method list (line 51) | async list(remoteFilePath) {
method get (line 57) | async get(remoteFilePath) {
method mkdir (line 63) | async mkdir(remoteFilePath, recursive) {
method rmdir (line 69) | async rmdir(localPath, recursive) {
method fastGet (line 75) | async fastGet(remotePath, localPath) {
method fastPut (line 81) | async fastPut(localPath, remotePath) {
method delete (line 87) | async delete(remoteFilePath) {
method rename (line 93) | async rename(remoteSourcePath, remoteDestPath) {
method chmod (line 99) | async chmod(remoteDestPath, mode) {
method end (line 105) | async end() {
FILE: app/util/socket.js
constant SSH (line 5) | const SSH = require('ssh2').Client;
FILE: app/util/ssh2.js
class Ssh2 (line 8) | class Ssh2 {
method constructor (line 10) | constructor() {
method init (line 17) | async init(json = {}) {
method connectStatus (line 25) | async connectStatus() {
method connect (line 35) | async connect() {
method exec (line 50) | async exec(exec) {
method shell (line 74) | async shell(shell) {
method end (line 98) | async end() {
FILE: app/util/utils.js
class Util (line 4) | class Util {
method constructor (line 6) | constructor() {
method isDirEnd (line 11) | isDirEnd(path) {
FILE: config/config.default.js
method all (line 116) | all(err, ctx) {
FILE: lib/plugin/egg-email/lib/email.js
function createOneClient (line 10) | function createOneClient(config, app) {
Condensed preview — 102 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (680K chars).
[
{
"path": ".autod.conf.js",
"chars": 403,
"preview": "'use strict';\n\nmodule.exports = {\n write: true,\n prefix: '^',\n plugin: 'autod-egg',\n test: [\n 'test',\n 'benchm"
},
{
"path": ".eslintignore",
"chars": 17,
"preview": "\ncoverage\n\n\n\n\n\n\n\n"
},
{
"path": ".eslintrc",
"chars": 253,
"preview": "{\n \"extends\": \"eslint-config-egg\",\n \"rules\": {\n \"indent\": [\n \"error\",\n 4\n ]\n "
},
{
"path": ".gitignore",
"chars": 1091,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\n\n# Runtime data\npids\n*.pid\n*.seed\n*.pid.lock\n\n# Directo"
},
{
"path": ".travis.yml",
"chars": 162,
"preview": "sudo: false\nlanguage: node_js\nnode_js:\n - '8'\ninstall:\n - npm i npminstall && npminstall\nscript:\n - npm run ci\nafter_"
},
{
"path": "LICENSE",
"chars": 1125,
"preview": "MIT License\n\nCopyright (c) 2018-2019 zane\n- zane ([@wangweianger](https://github.com/wangweianger))\n\n\nPermission is here"
},
{
"path": "README.md",
"chars": 1596,
"preview": "# APubPlat - [开发文档](http://apub-wiki.seosiwei.com/)\n[.Controller;\n\nclass ApplicationController extends Controller {\n\n asyn"
},
{
"path": "app/controller/api/assets.js",
"chars": 2913,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass AssetsController extends Controller {\n\n async lis"
},
{
"path": "app/controller/api/build.js",
"chars": 2328,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass BuildController extends Controller {\n\n // 生成构建配置\n"
},
{
"path": "app/controller/api/commtask.js",
"chars": 1285,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass CommtaskController extends Controller {\n\n async l"
},
{
"path": "app/controller/api/console.js",
"chars": 1500,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass ConsoleController extends Controller {\n\n // 获得服务器"
},
{
"path": "app/controller/api/email.js",
"chars": 1943,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass EmailController extends Controller {\n\n async list"
},
{
"path": "app/controller/api/environment.js",
"chars": 1442,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass TeamController extends Controller {\n\n async list("
},
{
"path": "app/controller/api/files.js",
"chars": 1211,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass FilesController extends Controller {\n\n // update "
},
{
"path": "app/controller/api/logs.js",
"chars": 2063,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass LogsController extends Controller {\n\n async list("
},
{
"path": "app/controller/api/qiniu.js",
"chars": 337,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass QiniuController extends Controller {\n\n async getT"
},
{
"path": "app/controller/api/team.js",
"chars": 1944,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass TeamController extends Controller {\n\n async list("
},
{
"path": "app/controller/api/user.js",
"chars": 3613,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass UserController extends Controller {\n\n // 用户登录\n "
},
{
"path": "app/controller/api/util.js",
"chars": 1494,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass UtilController extends Controller {\n\n // 获得服务器ssh"
},
{
"path": "app/controller/home.js",
"chars": 193,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\n\nclass HomeController extends Controller {\n async index() "
},
{
"path": "app/controller/web.js",
"chars": 2780,
"preview": "'use strict';\n// const fs = require('fs');\n// const path = require('path');\nconst Controller = require('egg').Controller"
},
{
"path": "app/extend/application.js",
"chars": 2170,
"preview": "'use strict';\nconst md5 = require('md5');\n\nmodule.exports = {\n /* 生成随机字符串 */\n randomString(len) {\n len = le"
},
{
"path": "app/io/controller/nsp.js",
"chars": 4319,
"preview": "'use strict';\n\nconst Controller = require('egg').Controller;\nconst socket = require('../../util/socket');\n\nclass NspCont"
},
{
"path": "app/io/middleware/auth.js",
"chars": 160,
"preview": "'use strict';\n\nmodule.exports = () => {\n return async (ctx, next) => {\n // ctx.socket.emit('response', 'connec"
},
{
"path": "app/middleware/token_required.js",
"chars": 1140,
"preview": "'use strict';\nconst { URL } = require('url');\n\n// 校验用户是否登录\nmodule.exports = () => {\n return async (ctx, next) => {\n "
},
{
"path": "app/model/application.js",
"chars": 795,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/assets.js",
"chars": 725,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/commtask.js",
"chars": 853,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/email.js",
"chars": 421,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/environment.js",
"chars": 373,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/logs.js",
"chars": 675,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/team.js",
"chars": 417,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/model/user.js",
"chars": 571,
"preview": "'use strict';\n\nmodule.exports = app => {\n const mongoose = app.mongoose;\n const Schema = mongoose.Schema;\n\n con"
},
{
"path": "app/public/css/base.css",
"chars": 8435,
"preview": "/*CSS Reset*/\n*, *:before, *:after { -webkit-box-sizing: border-box; box-sizing: border-box; }\n/*设置字体*/\n@font-face{font-"
},
{
"path": "app/public/css/home.css",
"chars": 0,
"preview": ""
},
{
"path": "app/public/iconfont/iconfont.css",
"chars": 1757,
"preview": "@font-face {font-family: \"iconfont\";\n src: url('iconfont.eot?t=1551324590500'); /* IE9 */\n src: url('iconfont.eot?t=15"
},
{
"path": "app/public/js/config.js",
"chars": 471,
"preview": "\n'use strict';\n\nconst config = {\n // 登陆页面\n loginUrl: '/login',\n\n // 登陆成功后需要跳转到的页面\n homeUrl: '/',\n\n // 根接口"
},
{
"path": "app/public/js/util.js",
"chars": 20588,
"preview": "/* eslint-disable */\n\n'use strict';\n\n// 时间格式化\nif (!new Date().format) {\n Date.prototype.format = function (fmt) { //a"
},
{
"path": "app/public/js/vue-components.js",
"chars": 2843,
"preview": "/* eslint-disable */\n\nlet Component = {\n commonsearch:{\n template: `<div class=\"component_search mr20\">\n "
},
{
"path": "app/public/js/vue-filters.js",
"chars": 3242,
"preview": "/* eslint-disable */\n// 时间格式化\nif(!new Date().format){\n Date.prototype.format = function (fmt) { //author: meizz \n "
},
{
"path": "app/public/lib/bootstrap/css/bootstrap-theme.css",
"chars": 26132,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "app/public/lib/bootstrap/css/bootstrap.css",
"chars": 146009,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under MIT (https://gi"
},
{
"path": "app/public/lib/bootstrap/js/bootstrap.js",
"chars": 69707,
"preview": "/*!\n * Bootstrap v3.3.7 (http://getbootstrap.com)\n * Copyright 2011-2016 Twitter, Inc.\n * Licensed under the MIT license"
},
{
"path": "app/public/lib/bootstrap/js/npm.js",
"chars": 484,
"preview": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequ"
},
{
"path": "app/public/lib/page/page.css",
"chars": 774,
"preview": "/*分页插件样式*/\n/**width: 1180px; margin: 0 auto; text-align: center; */\n.copot-page{width: 100%;color:#555555;font-size:12px"
},
{
"path": "app/public/lib/page/page.js",
"chars": 3792,
"preview": "/* eslint-disable */\n\nfunction Page(json) {\n\tthis.nowPage = parseInt(json.nowPage); //当前页\n\tthis.parent = json.parent; //"
},
{
"path": "app/public/lib/popup/popup.css",
"chars": 3754,
"preview": "/*layer-mobile-css*/\n@keyframes popScaleShow{from{opacity: 0;}to{opacity: 1;}}\n@-webkit-keyframes popScaleShow{from{opac"
},
{
"path": "app/public/lib/popup/popup.js",
"chars": 8247,
"preview": "/* eslint-disable */\n\n//构造函数\nfunction PopLayer(){\n this.setting={};\n}\n/*extent json函数*/\nPopLayer.prototype.extend=fun"
},
{
"path": "app/router/api.js",
"chars": 5270,
"preview": "'use strict';\n\nmodule.exports = app => {\n const apiV1Router = app.router.namespace('/api/v1/');\n const { controlle"
},
{
"path": "app/router/home.js",
"chars": 982,
"preview": "'use strict';\nmodule.exports = app => {\n const { router, controller } = app;\n const { web } = controller;\n\n // "
},
{
"path": "app/router.js",
"chars": 113,
"preview": "'use strict';\n\nmodule.exports = app => {\n require('./router/home')(app);\n require('./router/api')(app);\n};\n"
},
{
"path": "app/service/application.js",
"chars": 4704,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass ApplicationService extends Service {\n\n // init"
},
{
"path": "app/service/assets.js",
"chars": 3116,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass AssetsService extends Service {\n\n // init 初始化\n"
},
{
"path": "app/service/build.js",
"chars": 10442,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst fs = require('fs');\nconst path = require('path');\n"
},
{
"path": "app/service/commtask.js",
"chars": 2761,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst fs = require('fs');\nconst path = require('path');\n"
},
{
"path": "app/service/console.js",
"chars": 2095,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst ssh2 = require('../util/ssh2');\nconst path = requi"
},
{
"path": "app/service/email.js",
"chars": 1771,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass EmailService extends Service {\n\n // init 初始化\n "
},
{
"path": "app/service/environment.js",
"chars": 1462,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass EnvironmentService extends Service {\n\n // init"
},
{
"path": "app/service/files.js",
"chars": 902,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst path = require('path');\nconst fs = require('fs');\n"
},
{
"path": "app/service/logs.js",
"chars": 1523,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass LogsService extends Service {\n\n // add logs\n "
},
{
"path": "app/service/qiniu.js",
"chars": 1500,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst qiniu = require('qiniu');\n\nclass QiniuService exte"
},
{
"path": "app/service/team.js",
"chars": 1738,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\n\nclass TeamService extends Service {\n\n // init 初始化\n "
},
{
"path": "app/service/user.js",
"chars": 6515,
"preview": "'use strict';\nconst crypto = require('crypto');\nconst Service = require('egg').Service;\n\nclass UserService extends Servi"
},
{
"path": "app/service/util.js",
"chars": 2089,
"preview": "// 七牛JDK\n'use strict';\n\nconst Service = require('egg').Service;\nconst ssh2 = require('../util/ssh2');\nconst path = requi"
},
{
"path": "app/tempFile/install-node.sh",
"chars": 532,
"preview": "#!/bin/bash\nwget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | NVM_DIR=/usr/local/nvm bash\n"
},
{
"path": "app/util/sftp.js",
"chars": 3127,
"preview": "// 七牛JDK\n'use strict';\n\nconst Client = require('ssh2-sftp-client');\nconst servers = new Client();\nconst sftp = {};\nclass"
},
{
"path": "app/util/socket.js",
"chars": 4418,
"preview": "\n'use strict';\n\nconst debug = require('debug');\nconst SSH = require('ssh2').Client;\n\n// public\nmodule.exports = function"
},
{
"path": "app/util/ssh2.js",
"chars": 2769,
"preview": "// 七牛JDK\n'use strict';\n\nconst Client = require('ssh2').Client;\nconst servers = new Client();\nconst conn = {};\n\nclass Ssh"
},
{
"path": "app/util/utils.js",
"chars": 417,
"preview": "\n'use strict';\n\nclass Util {\n\n constructor() {\n this.name = '';\n }\n\n // 判断路径最后是否有 /\n isDirEnd(path) {"
},
{
"path": "app/view/appconfig.html",
"chars": 20145,
"preview": "<style scoped>\n .config_main{\n padding:20px;\n background: #fff;\n }\n .config_main .row-col{\n "
},
{
"path": "app/view/application.html",
"chars": 25913,
"preview": "<style scoped>\n .com_top .inp{\n width:180px;\n }\n .el-table .disabled-row {\n background: oldlace;\n"
},
{
"path": "app/view/assets.html",
"chars": 15482,
"preview": "<style scoped>\n .el-table .disabled-row {\n background: oldlace;\n }\n .com_model_block .inp{\n width"
},
{
"path": "app/view/assetsconfig.html",
"chars": 16399,
"preview": "<style scoped>\n .config_main {\n padding: 20px;\n background: #fff;\n }\n .bottom .top{\n displ"
},
{
"path": "app/view/build.html",
"chars": 9439,
"preview": "<style scoped>\n .com_top .inp {\n width: 180px;\n }\n\n .el-table .disabled-row {\n background: oldlac"
},
{
"path": "app/view/buildprocess.html",
"chars": 26415,
"preview": "<style scoped>\n .config_main {\n padding: 20px;\n background: #fff;\n box-shadow: 5px 5px 10px #eee"
},
{
"path": "app/view/commtask.html",
"chars": 12223,
"preview": "<style scoped>\n .comm_build_textarea {\n width: 840px;\n height: 180px;\n }\n .com_model_main .com_mo"
},
{
"path": "app/view/console.html",
"chars": 14367,
"preview": "<style scoped>\n body{background:#000;}\n .header,.footer{display:none;}\n #body_content{overflow:hidden;margin-le"
},
{
"path": "app/view/email.html",
"chars": 7765,
"preview": "<style scoped>\n .el-table .disabled-row {\n background: oldlace;\n }\n</style>\n<div class=\"content\" id=\"email\""
},
{
"path": "app/view/environment.html",
"chars": 5783,
"preview": "<style scoped>\n \n</style>\n<div class=\"content\" id=\"environment\" v-cloak>\n <el-row>\n <el-col :span=\"12\">\n "
},
{
"path": "app/view/footer.html",
"chars": 344,
"preview": "<style>\n .apa_footer .content{\n position: fixed;\n left:0;\n bottom:0;\n width:100%;\n "
},
{
"path": "app/view/header.html",
"chars": 2158,
"preview": "<style scoped>\n.header{\n position: fixed;\n left:0;\n top:0;\n width:100%;\n height:50px;\n z-index:10;\n paddin"
},
{
"path": "app/view/home.html",
"chars": 2793,
"preview": "<style scoped>\n .content{\n padding:20px;\n }\n \n .terminal{\n padding:20px;\n }\n</style>\n<div c"
},
{
"path": "app/view/layout.html",
"chars": 2125,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <!-- meta -->\n <title>自动化发布系统</title>\n <meta charset=\"utf-8\" />\n"
},
{
"path": "app/view/login.html",
"chars": 5539,
"preview": "<style scoped>\n .header,.side,.apa_footer{display: none;}\n #body_content{margin-left:0px;}\n .main{\n disp"
},
{
"path": "app/view/logs.html",
"chars": 13077,
"preview": "<style scoped>\n .com_top .inp {\n width: 180px;\n }\n\n .el-table .disabled-row {\n background: oldlac"
},
{
"path": "app/view/reduction.html",
"chars": 21675,
"preview": "<style scoped>\n .config_main {\n padding: 20px;\n background: #fff;\n box-shadow: 5px 5px 10px #eee"
},
{
"path": "app/view/side.html",
"chars": 6129,
"preview": "<style scoped>\n .el-menu-vertical-demo:not(.el-menu--collapse) {\n width: 180px;\n min-height: 400px;\n}\n.side{\n\tpos"
},
{
"path": "app/view/team.html",
"chars": 7529,
"preview": "<style scoped>\n .el-table .disabled-row {\n background: oldlace;\n }\n</style>\n<div class=\"content\" id=\"team\" "
},
{
"path": "app/view/user.html",
"chars": 8836,
"preview": "<style scoped>\n .el-table .disabled-row {\n background: oldlace;\n }\n</style>\n<div class=\"content\" id=\"team\" "
},
{
"path": "app.js",
"chars": 49,
"preview": "'use strict';\n\nmodule.exports = async () => {\n};\n"
},
{
"path": "appveyor.yml",
"chars": 241,
"preview": "environment:\n matrix:\n - nodejs_version: '8'\n\ninstall:\n - ps: Install-Product node $env:nodejs_version\n - npm i np"
},
{
"path": "config/config.default.js",
"chars": 2768,
"preview": "'use strict';\nconst path = require('path');\n\nmodule.exports = appInfo => {\n const config = exports = {};\n\n // use "
},
{
"path": "config/config.prod.js",
"chars": 199,
"preview": "'use strict';\n\nmodule.exports = () => {\n const config = exports = {};\n\n config.debug = false;\n\n // 用于安全校验和回调域名根"
},
{
"path": "config/plugin.js",
"chars": 557,
"preview": "'use strict';\n\nconst path = require('path');\n\nexports.ejs = {\n enable: true,\n package: 'egg-view-ejs',\n};\n\nexports"
},
{
"path": "lib/plugin/egg-email/LICENSE",
"chars": 1120,
"preview": "The MIT License (MIT)\n\nCopyright (c) 2019 Alibaba Group Holding Limited and other contributors.\n\nPermission is hereby gr"
},
{
"path": "lib/plugin/egg-email/README.md",
"chars": 13,
"preview": "# egg-email\n\n"
},
{
"path": "lib/plugin/egg-email/app.js",
"chars": 100,
"preview": "'use strict';\n\nconst email = require('./lib/email');\n\nmodule.exports = app => {\n email(app);\n};\n\n"
},
{
"path": "lib/plugin/egg-email/config/config.default.js",
"chars": 36,
"preview": "'use strict';\n\nexports.email = {\n};\n"
},
{
"path": "lib/plugin/egg-email/lib/email.js",
"chars": 673,
"preview": "'use strict';\n\nconst nodemailer = require('nodemailer');\n// const assert = require('assert');\n\nmodule.exports = app => {"
},
{
"path": "lib/plugin/egg-email/package.json",
"chars": 304,
"preview": "{\n \"name\": \"egg-email\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"main\": \"app.js\",\n \"scripts\": {\n \"test\": \"echo"
},
{
"path": "package.json",
"chars": 1443,
"preview": "{\n \"name\": \"apubplat\",\n \"version\": \"1.0.0\",\n \"description\": \"\",\n \"private\": true,\n \"dependencies\": {\n \"debug\": \""
}
]
About this extraction
This page contains the full source code of the wangweianger/APubPlat GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 102 files (617.9 KB), approximately 162.0k tokens, and a symbol index with 254 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.