From d777f427192e8f15bbacdfbfad497b9dc248bfeb Mon Sep 17 00:00:00 2001
From: Hellohao <923453645@qq.com>
Date: Wed, 7 Aug 2019 23:22:44 +0800
Subject: [PATCH] =?UTF-8?q?2019-08-07=E6=9B=B4=E6=96=B0=20=E5=A2=9E?=
=?UTF-8?q?=E5=8A=A0API=E6=8E=A5=E5=8F=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
sql/picturebed.sql | 144 +-
.../hellohao/controller/AdminController.java | 17 +-
.../hellohao/controller/ClientController.java | 227 ++
.../controller/ExceptionHandling.java | 68 +
.../controller/UpdateImgController.java | 19 +-
.../hellohao/controller/UserController.java | 6 +-
.../cn/hellohao/exception/LoginException.java | 27 +
.../exception/StorageSourceInitException.java | 29 +
.../java/cn/hellohao/pojo/ResultBean.java | 56 +
.../java/cn/hellohao/pojo/UploadConfig.java | 12 +-
src/main/java/cn/hellohao/pojo/User.java | 11 +
.../hellohao/service/impl/COSImageupload.java | 83 +-
.../hellohao/service/impl/FTPImageupload.java | 100 +-
.../service/impl/KODOImageupload.java | 69 +-
.../hellohao/service/impl/NOSImageupload.java | 91 +-
.../hellohao/service/impl/OSSImageupload.java | 40 +-
.../hellohao/service/impl/USSImageupload.java | 44 +-
src/main/java/cn/hellohao/test/test1.java | 18 +-
.../java/cn/hellohao/utils/LocUpdateImg.java | 36 +-
src/main/resources/application.properties | 6 +-
.../resources/mapper/UploadConfigMapper.xml | 5 +-
.../resources/static/js/jquery.qrcode.min.js | 1 +
.../resources/static/webuploade/js/upload.js | 4 +-
.../static/xcc/css/font-awesome.min.css | 4 +
src/main/resources/static/xcc/css/ie8.css | 47 +
src/main/resources/static/xcc/css/ie9.css | 41 +
.../resources/static/xcc/css/images/arrow.svg | 11 +
.../resources/static/xcc/css/images/close.svg | 10 +
.../static/xcc/css/images/spinner.svg | 17 +
src/main/resources/static/xcc/css/main.css | 1987 +++++++++++++++++
.../static/xcc/fonts/FontAwesome.otf | Bin 0 -> 123112 bytes
.../static/xcc/fonts/fontawesome-webfont.eot | Bin 0 -> 75220 bytes
.../static/xcc/fonts/fontawesome-webfont.svg | 685 ++++++
.../static/xcc/fonts/fontawesome-webfont.ttf | Bin 0 -> 150920 bytes
.../static/xcc/fonts/fontawesome-webfont.woff | Bin 0 -> 89076 bytes
.../xcc/fonts/fontawesome-webfont.woff2 | Bin 0 -> 70728 bytes
.../resources/static/xcc/js/ie/html5shiv.js | 8 +
.../resources/static/xcc/js/ie/respond.min.js | 6 +
.../resources/static/xcc/js/jquery.min.js | 5 +
.../static/xcc/js/jquery.poptrox.min.js | 2 +
src/main/resources/static/xcc/js/main.js | 299 +++
src/main/resources/static/xcc/js/skel.min.js | 2 +
src/main/resources/static/xcc/js/util.js | 587 +++++
.../resources/static/xcc/sass/base/_page.scss | 47 +
.../static/xcc/sass/base/_typography.scss | 172 ++
.../static/xcc/sass/components/_button.scss | 89 +
.../static/xcc/sass/components/_form.scss | 203 ++
.../static/xcc/sass/components/_icon.scss | 17 +
.../static/xcc/sass/components/_list.scss | 188 ++
.../static/xcc/sass/components/_panel.scss | 106 +
.../xcc/sass/components/_poptrox-popup.scss | 167 ++
.../static/xcc/sass/components/_table.scss | 81 +
src/main/resources/static/xcc/sass/ie8.scss | 54 +
src/main/resources/static/xcc/sass/ie9.scss | 56 +
.../static/xcc/sass/layout/_footer.scss | 18 +
.../static/xcc/sass/layout/_header.scss | 127 ++
.../static/xcc/sass/layout/_main.scss | 177 ++
.../static/xcc/sass/layout/_wrapper.scss | 88 +
.../static/xcc/sass/libs/_functions.scss | 34 +
.../static/xcc/sass/libs/_mixins.scss | 56 +
.../resources/static/xcc/sass/libs/_skel.scss | 584 +++++
.../resources/static/xcc/sass/libs/_vars.scss | 81 +
src/main/resources/static/xcc/sass/main.scss | 57 +
src/main/resources/templates/admin/api.html | 141 ++
src/main/resources/templates/admin/index.html | 7 +
.../resources/templates/admin/survey.html | 9 +-
src/main/resources/templates/admin/table.html | 256 ++-
.../resources/templates/admin/webconfig.html | 50 +-
src/main/resources/templates/index.html | 14 +-
69 files changed, 7374 insertions(+), 329 deletions(-)
create mode 100644 src/main/java/cn/hellohao/controller/ClientController.java
create mode 100644 src/main/java/cn/hellohao/controller/ExceptionHandling.java
create mode 100644 src/main/java/cn/hellohao/exception/LoginException.java
create mode 100644 src/main/java/cn/hellohao/exception/StorageSourceInitException.java
create mode 100644 src/main/java/cn/hellohao/pojo/ResultBean.java
create mode 100644 src/main/resources/static/js/jquery.qrcode.min.js
create mode 100644 src/main/resources/static/xcc/css/font-awesome.min.css
create mode 100644 src/main/resources/static/xcc/css/ie8.css
create mode 100644 src/main/resources/static/xcc/css/ie9.css
create mode 100644 src/main/resources/static/xcc/css/images/arrow.svg
create mode 100644 src/main/resources/static/xcc/css/images/close.svg
create mode 100644 src/main/resources/static/xcc/css/images/spinner.svg
create mode 100644 src/main/resources/static/xcc/css/main.css
create mode 100644 src/main/resources/static/xcc/fonts/FontAwesome.otf
create mode 100644 src/main/resources/static/xcc/fonts/fontawesome-webfont.eot
create mode 100644 src/main/resources/static/xcc/fonts/fontawesome-webfont.svg
create mode 100644 src/main/resources/static/xcc/fonts/fontawesome-webfont.ttf
create mode 100644 src/main/resources/static/xcc/fonts/fontawesome-webfont.woff
create mode 100644 src/main/resources/static/xcc/fonts/fontawesome-webfont.woff2
create mode 100644 src/main/resources/static/xcc/js/ie/html5shiv.js
create mode 100644 src/main/resources/static/xcc/js/ie/respond.min.js
create mode 100644 src/main/resources/static/xcc/js/jquery.min.js
create mode 100644 src/main/resources/static/xcc/js/jquery.poptrox.min.js
create mode 100644 src/main/resources/static/xcc/js/main.js
create mode 100644 src/main/resources/static/xcc/js/skel.min.js
create mode 100644 src/main/resources/static/xcc/js/util.js
create mode 100644 src/main/resources/static/xcc/sass/base/_page.scss
create mode 100644 src/main/resources/static/xcc/sass/base/_typography.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_button.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_form.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_icon.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_list.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_panel.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_poptrox-popup.scss
create mode 100644 src/main/resources/static/xcc/sass/components/_table.scss
create mode 100644 src/main/resources/static/xcc/sass/ie8.scss
create mode 100644 src/main/resources/static/xcc/sass/ie9.scss
create mode 100644 src/main/resources/static/xcc/sass/layout/_footer.scss
create mode 100644 src/main/resources/static/xcc/sass/layout/_header.scss
create mode 100644 src/main/resources/static/xcc/sass/layout/_main.scss
create mode 100644 src/main/resources/static/xcc/sass/layout/_wrapper.scss
create mode 100644 src/main/resources/static/xcc/sass/libs/_functions.scss
create mode 100644 src/main/resources/static/xcc/sass/libs/_mixins.scss
create mode 100644 src/main/resources/static/xcc/sass/libs/_skel.scss
create mode 100644 src/main/resources/static/xcc/sass/libs/_vars.scss
create mode 100644 src/main/resources/static/xcc/sass/main.scss
create mode 100644 src/main/resources/templates/admin/api.html
diff --git a/sql/picturebed.sql b/sql/picturebed.sql
index aa833fb..8e46211 100644
--- a/sql/picturebed.sql
+++ b/sql/picturebed.sql
@@ -11,8 +11,7 @@
Target Server Version : 50720
File Encoding : 65001
-<<<<<<< HEAD
- Date: 26/07/2019 17:38:26
+ Date: 07/08/2019 23:21:26
*/
SET NAMES utf8mb4;
@@ -23,41 +22,41 @@ SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
DROP TABLE IF EXISTS `config`;
CREATE TABLE `config` (
- `id` int(4) NOT NULL AUTO_INCREMENT,
- `sourcekey` int(4) NULL DEFAULT NULL,
- `emails` int(4) NULL DEFAULT NULL,
- `webname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '网站名',
- `explain` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '首页左下角说明',
- `logos` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '左下角的图片地址',
- `footed` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '页脚版权',
- `links` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '友链',
- `notice` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '公告',
- `baidu` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '百度统计',
- `domain` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '站点域名',
- `background1` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '首页背景图',
- `background2` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传页面背景图',
- `sett` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(4) NOT NULL AUTO_INCREMENT,
+ `sourcekey` int(4) NULL DEFAULT NULL,
+ `emails` int(4) NULL DEFAULT NULL,
+ `webname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '网站名',
+ `explain` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '首页左下角说明',
+ `logos` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '左下角的图片地址',
+ `footed` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '页脚版权',
+ `links` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '友链',
+ `notice` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '公告',
+ `baidu` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '百度统计',
+ `domain` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '站点域名',
+ `background1` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '首页背景图',
+ `background2` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传页面背景图',
+ `sett` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of config
-- ----------------------------
-INSERT INTO `config` VALUES (1, 5, 1, 'Hellohao', '网站由JAVA语言编写应用SpringBoot框架开发,前端全部组件由BootStrap/Layui框架编写。由作者个人更新维护,后期会加入更全面的功能供大家使用,如有BUG请与我反馈。', 'https://hellohao.nos-eastchina1.126.net/%E7%BD%91%E7%AB%99%E7%B4%A0%E6%9D%90/logo2.png', 'Hellohao 切勿上传违反中华人民共和国互联网法律条约资源', '
作者博客高清壁纸json格式化', '也许...|这将是最好用的图床', 'console.log(\'百度统计JS代码\');', 'http://tc.hellohao.cn', 'https://hellohao.oss-cn-beijing.aliyuncs.com/Hellohao/eb83a0714030248.jpg', 'https://hellohao.oss-cn-beijing.aliyuncs.com/Hellohao/086650714030248.jpg', NULL);
+INSERT INTO `config` VALUES (1, 7, 1, 'Hellohao', '网站由JAVA语言编写应用SpringBoot框架开发,前端全部组件由BootStrap/Layui框架编写。由作者个人更新维护,后期会加入更全面的功能供大家使用,如有BUG请与我反馈。', 'https://hellohao.nos-eastchina1.126.net/%E7%BD%91%E7%AB%99%E7%B4%A0%E6%9D%90/logo2.png', 'Hellohao 切勿上传违反中华人民共和国互联网法律条约资源', '作者博客高清壁纸json格式化', '也许...|这将是最好用的图床', 'console.log(\'百度统计JS代码\');', 'http://tc.hellohao.cn', 'https://hellohao.oss-cn-beijing.aliyuncs.com/Hellohao/eb83a0714030248.jpg', 'https://hellohao.oss-cn-beijing.aliyuncs.com/Hellohao/086650714030248.jpg', NULL);
-- ----------------------------
-- Table structure for emailconfig
-- ----------------------------
DROP TABLE IF EXISTS `emailconfig`;
CREATE TABLE `emailconfig` (
- `id` int(2) NOT NULL AUTO_INCREMENT,
- `emails` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
- `emailkey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '授权码',
- `emailurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '服务器',
- `port` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '端口',
- `emailname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
- `using` int(4) NULL DEFAULT NULL COMMENT '1为可用,其他为不使用',
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(2) NOT NULL AUTO_INCREMENT,
+ `emails` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '邮箱',
+ `emailkey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '授权码',
+ `emailurl` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '服务器',
+ `port` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '端口',
+ `emailname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
+ `using` int(4) NULL DEFAULT NULL COMMENT '1为可用,其他为不使用',
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
@@ -70,15 +69,15 @@ INSERT INTO `emailconfig` VALUES (1, NULL, NULL, NULL, NULL, NULL, 0);
-- ----------------------------
DROP TABLE IF EXISTS `imgdata`;
CREATE TABLE `imgdata` (
- `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
- `imgname` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片名',
- `imgurl` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片链接',
- `userid` int(10) NULL DEFAULT NULL COMMENT '用户名',
- `updatetime` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传时间',
- `sizes` int(255) NULL DEFAULT NULL COMMENT '文件大小',
- `abnormal` int(2) NULL DEFAULT NULL COMMENT '异常',
- `source` int(2) NULL DEFAULT NULL COMMENT '存储源',
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `imgname` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片名',
+ `imgurl` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '图片链接',
+ `userid` int(10) NULL DEFAULT NULL COMMENT '用户名',
+ `updatetime` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上传时间',
+ `sizes` int(255) NULL DEFAULT NULL COMMENT '文件大小',
+ `abnormal` int(2) NULL DEFAULT NULL COMMENT '异常',
+ `source` int(2) NULL DEFAULT NULL COMMENT '存储源',
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
@@ -86,13 +85,13 @@ CREATE TABLE `imgdata` (
-- ----------------------------
DROP TABLE IF EXISTS `imgreview`;
CREATE TABLE `imgreview` (
- `id` int(4) NOT NULL AUTO_INCREMENT,
- `app_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `api_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `secret_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `Using` int(4) NULL DEFAULT NULL,
- `count` int(10) NULL DEFAULT NULL COMMENT '拦截数量',
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(4) NOT NULL AUTO_INCREMENT,
+ `app_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `api_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `secret_key` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `Using` int(4) NULL DEFAULT NULL,
+ `count` int(10) NULL DEFAULT NULL COMMENT '拦截数量',
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
@@ -105,14 +104,14 @@ INSERT INTO `imgreview` VALUES (1, NULL, NULL, NULL, 0, 0);
-- ----------------------------
DROP TABLE IF EXISTS `keys`;
CREATE TABLE `keys` (
- `id` int(11) NOT NULL AUTO_INCREMENT,
- `AccessKey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `AccessSecret` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `Endpoint` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `Bucketname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `RequestAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
- `storageType` int(11) NULL DEFAULT NULL,
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(11) NOT NULL AUTO_INCREMENT,
+ `AccessKey` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `AccessSecret` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `Endpoint` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `Bucketname` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `RequestAddress` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
+ `storageType` int(11) NULL DEFAULT NULL,
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
@@ -124,7 +123,7 @@ INSERT INTO `keys` VALUES (3, '123', '123', '0', '123', '123', 3);
INSERT INTO `keys` VALUES (4, '123', '123', '4', '412', 'https://0.0', 4);
INSERT INTO `keys` VALUES (5, '0', '0', '0', '0', '0', 5);
INSERT INTO `keys` VALUES (6, '', '', '', '', '', 6);
-INSERT INTO `keys` VALUES (7, '', '', '', '', '', 7);
+INSERT INTO `keys` VALUES (7, '234', '234124', '234124', '', '234142', 7);
INSERT INTO `keys` VALUES (8, '', '', '', '', '', 8);
INSERT INTO `keys` VALUES (9, '', '', '', '', '', 9);
INSERT INTO `keys` VALUES (10, '0', '', '0', '0', '0', 10);
@@ -134,8 +133,8 @@ INSERT INTO `keys` VALUES (10, '0', '', '0', '0', '0', 10);
-- ----------------------------
DROP TABLE IF EXISTS `notice`;
CREATE TABLE `notice` (
- `id` int(4) NOT NULL,
- `text` varchar(10000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
+ `id` int(4) NOT NULL,
+ `text` varchar(10000) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
@@ -143,36 +142,37 @@ CREATE TABLE `notice` (
-- ----------------------------
DROP TABLE IF EXISTS `uploadconfig`;
CREATE TABLE `uploadconfig` (
- `id` int(2) NOT NULL AUTO_INCREMENT,
- `filesizetourists` int(10) NULL DEFAULT NULL COMMENT '游客上传文件最大',
- `filesizeuser` int(10) NULL DEFAULT NULL COMMENT '用户上传文件最大',
- `imgcounttourists` int(10) NULL DEFAULT NULL COMMENT '游客文件总数量, 超出则不允许加入队列',
- `imgcountuser` int(10) NULL DEFAULT NULL COMMENT '用户文件总数量, 超出则不允许加入队列',
- `suffix` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '支持后缀',
- `urltype` int(2) NULL DEFAULT NULL,
- `isupdate` int(2) NULL DEFAULT NULL COMMENT '禁止游客上传',
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(2) NOT NULL AUTO_INCREMENT,
+ `filesizetourists` int(10) NULL DEFAULT NULL COMMENT '游客上传文件最大',
+ `filesizeuser` int(10) NULL DEFAULT NULL COMMENT '用户上传文件最大',
+ `imgcounttourists` int(10) NULL DEFAULT NULL COMMENT '游客文件总数量, 超出则不允许加入队列',
+ `imgcountuser` int(10) NULL DEFAULT NULL COMMENT '用户文件总数量, 超出则不允许加入队列',
+ `suffix` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '支持后缀',
+ `urltype` int(2) NULL DEFAULT NULL,
+ `isupdate` int(2) NOT NULL COMMENT '游客是否可以上传',
+ `api` int(2) NOT NULL COMMENT '开启api',
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of uploadconfig
-- ----------------------------
-INSERT INTO `uploadconfig` VALUES (1, 3, 5, 1, 5, 'gif,jpg,jpeg,bmp,png', 1, 1);
+INSERT INTO `uploadconfig` VALUES (1, 3, 5, 1, 5, 'gif,jpg,jpeg,bmp,png', 1, 1, 0);
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
- `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
- `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
- `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
- `email` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '邮箱',
- `birthder` date NULL DEFAULT NULL COMMENT '注册时间',
- `level` int(10) NULL DEFAULT NULL COMMENT '等级',
- `uid` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户唯一标识',
- `isok` int(2) NOT NULL,
- PRIMARY KEY (`id`) USING BTREE
+ `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '主键',
+ `username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户名',
+ `password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '密码',
+ `email` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '邮箱',
+ `birthder` date NULL DEFAULT NULL COMMENT '注册时间',
+ `level` int(10) NULL DEFAULT NULL COMMENT '等级',
+ `uid` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户唯一标识',
+ `isok` int(2) NOT NULL,
+ PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
diff --git a/src/main/java/cn/hellohao/controller/AdminController.java b/src/main/java/cn/hellohao/controller/AdminController.java
index 23a83f8..f459a48 100644
--- a/src/main/java/cn/hellohao/controller/AdminController.java
+++ b/src/main/java/cn/hellohao/controller/AdminController.java
@@ -38,11 +38,13 @@ public class AdminController {
private ImgreviewService imgreviewService;
@Autowired
private ConfigService configService;
-
+ @Autowired
+ private UploadConfigService uploadConfigService;
@RequestMapping(value = "/goadmin")
public String goadmin1(HttpSession session, Model model, HttpServletRequest request) {
User user = (User) session.getAttribute("user");
+ UploadConfig uploadConfig = uploadConfigService.getUpdateConfig();
if(user!=null){
if (user.getLevel() == 1) {
model.addAttribute("level", "普通用户");
@@ -53,6 +55,7 @@ public class AdminController {
}
model.addAttribute("levels", user.getLevel());
model.addAttribute("username", user.getUsername());
+ model.addAttribute("api", uploadConfig.getApi());
return "admin/index";
}else{
return "redirect:/";
@@ -331,7 +334,17 @@ public class AdminController {
// -1 用户名重复
return jsonArray.toString();
}
-
+ //进入api
+ @RequestMapping(value = "/toapi")
+ public String toapi(HttpSession session, Model model, HttpServletRequest request) {
+ User u = (User) session.getAttribute("user");
+ Config config = configService.getSourceype();
+ //key信息
+ model.addAttribute("username", u.getUsername());
+ model.addAttribute("level", u.getLevel());
+ model.addAttribute("domain", config.getDomain());
+ return "admin/api";
+ }
@GetMapping(value = "/images/{id}")
@ResponseBody
diff --git a/src/main/java/cn/hellohao/controller/ClientController.java b/src/main/java/cn/hellohao/controller/ClientController.java
new file mode 100644
index 0000000..bae29e4
--- /dev/null
+++ b/src/main/java/cn/hellohao/controller/ClientController.java
@@ -0,0 +1,227 @@
+package cn.hellohao.controller;
+
+import cn.hellohao.pojo.*;
+import cn.hellohao.service.*;
+import cn.hellohao.service.impl.*;
+import cn.hellohao.utils.*;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletRequest;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Hellohao
+ * @version 1.0
+ * @date 2019-07-18 17:22
+ */
+@RestController
+public class ClientController {
+ @Autowired
+ private NOSImageupload nOSImageupload;
+ @Autowired
+ private UserService userService;
+ @Autowired
+ private KeysService keysService;
+ @Autowired
+ private OSSImageupload ossImageupload;
+ @Autowired
+ private ConfigService configService;
+ @Autowired
+ private USSImageupload ussImageupload;
+ @Autowired
+ private KODOImageupload kodoImageupload;
+ @Autowired
+ private UploadConfigService uploadConfigService;
+ @Autowired
+ private NoticeService noticeService;
+ @Autowired
+ private COSImageupload cosImageupload;
+ @Autowired
+ private FTPImageupload ftpImageupload;
+
+ @Value("${systemupdate}")
+ private String systemupdate;
+
+ @PostMapping(value = "/clientupimg")
+ @ResponseBody
+ public ResultBean clientupimg(@RequestParam("file") List file, String email, String pass) throws Exception {
+ ResultBean resultBean = null;
+ JSONArray jsonArray = new JSONArray();
+ UploadConfig uploadConfig = uploadConfigService.getUpdateConfig();
+ if (uploadConfig.getApi() == 1) {
+ if (email != null && pass != null) {
+ Integer ret = userService.login(email, pass);
+ if (ret > 0) {
+ User user = userService.getUsers(email);
+ if (user.getIsok() == 1) {
+ User u = userService.getUsers(email);
+ Config config = configService.getSourceype();//查询当前系统使用的存储源类型。
+ Keys key = keysService.selectKeys(config.getSourcekey());
+ if (key.getStorageType() != 0 && key.getStorageType() != null) {
+ if (key.getStorageType() == 1) {
+ nOSImageupload.Initialize(key);//实例化网易
+ } else if (key.getStorageType() == 2) {
+ OSSImageupload.Initialize(key);
+ } else if (key.getStorageType() == 3) {
+ USSImageupload.Initialize(key);
+ } else if (key.getStorageType() == 4) {
+ KODOImageupload.Initialize(key);
+ } else if (key.getStorageType() == 6) {
+ COSImageupload.Initialize(key);
+ } else if (key.getStorageType() == 7) {
+ FTPImageupload.Initialize(key);
+ } else {
+ System.err.println("客户端:未获取到对象存储参数,初始化失败。");
+ }
+ }
+ Print.Normal("客户端:初始化上传。");
+ Boolean b = false;
+ if (config.getSourcekey() == 5) {
+ b = true;
+ } else {
+ b = StringUtils.doNull(config.getSourcekey(), key);//判断对象是否有空值
+ }
+ if (b) {
+ long stime = System.currentTimeMillis();
+ String userpath = "tourist";
+ if (uploadConfig.getUrltype() == 2) {
+ java.text.DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
+ userpath = dateFormat.format(new Date());
+ } else {
+ if (u != null) {
+ userpath = u.getUsername();
+ }
+ }
+ Map map = new HashMap<>();
+ for (MultipartFile multipartFile : file) {
+ //获取文件名
+ System.out.println(multipartFile.toString());
+ String fileName = multipartFile.getOriginalFilename();
+ String lastname = fileName.substring(fileName.lastIndexOf(".") + 1);//获取文件后缀
+ if (!multipartFile.isEmpty()) { //判断文件是否为空
+ map.put(lastname, multipartFile);
+ }
+ }
+ Map m = null;
+ Map m2 = null;
+ if (key.getStorageType() == 1) {
+ m = nOSImageupload.clientuploadNOS(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 2) {
+ m = ossImageupload.clientuploadOSS(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 3) {
+ m = ussImageupload.clientuploadUSS(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 4) {
+ m = kodoImageupload.clientuploadKODO(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 5) {
+ m2 = LocUpdateImg.clientuploadFTP(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 6) {
+ m = cosImageupload.clientuploadCOS(map, userpath, uploadConfig);
+ } else if (key.getStorageType() == 7) {
+ m = ftpImageupload.clientuploadFTP(map, userpath, uploadConfig);
+ } else {
+ System.err.println("未获取到对象存储参数,上传失败。");
+ }
+ Images img = new Images();
+ SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
+ String times = df.format(new Date());
+ System.out.println("上传图片的时间是:" + times);
+ if (key.getStorageType() == 5) {
+ for (Map.Entry entry : m2.entrySet()) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("Imgname", entry.getKey().getImgname());
+ if (key.getStorageType() == 5) {
+ if (config.getDomain() != null) {
+ jsonObject.put("Imgurl", config.getDomain() + "/links/" + entry.getKey().getImgurl());
+ img.setImgurl(config.getDomain() + "/links/" + entry.getKey().getImgurl());//图片链接
+ } else {
+ jsonObject.put("Imgurl", config.getDomain() + "/links/" + entry.getKey().getImgurl());
+ img.setImgurl("http://" + IPPortUtil.getLocalIP() + ":" + IPPortUtil.getLocalPort() + "/links/" + entry.getKey().getImgurl());//图片链接
+ }
+ } else {
+ jsonObject.put("Imgname", entry.getKey().getImgurl());
+ img.setImgurl(entry.getKey().getImgurl());//图片链接
+ }
+ img.setUpdatetime(times);
+ img.setSource(key.getStorageType());
+ if (u == null) {
+ img.setUserid(0);//用户id
+ } else {
+ img.setUserid(u.getId());//用户id
+ }
+ img.setSizes((entry.getValue()));
+ img.setImgname(SetText.getSubString(entry.getKey().getImgurl(), key.getRequestAddress() + "/", ""));
+ img.setAbnormal(0);
+ //-1证明超出大小,
+ if (entry.getValue() != -1) {
+ userService.insertimg(img);
+ }
+ long etime = System.currentTimeMillis();
+ System.out.println("上传图片所用时长:" + String.valueOf(etime - stime) + "ms");
+ jsonArray.add(jsonObject);
+ }
+ } else {
+ for (Map.Entry entry : m.entrySet()) {
+ JSONObject jsonObject = new JSONObject();
+ jsonObject.put("Imgname", entry.getKey().getImgname());
+ if (key.getStorageType() == 5) {
+ if (config.getDomain() != null) {
+ jsonObject.put("Imgurl", config.getDomain() + "/links/" + entry.getKey().getImgurl());
+ img.setImgurl(config.getDomain() + "/links/" + entry.getKey().getImgurl());//图片链接
+ } else {
+ jsonObject.put("Imgurl", config.getDomain() + "/links/" + entry.getKey().getImgurl());
+ img.setImgurl("http://" + IPPortUtil.getLocalIP() + ":" + IPPortUtil.getLocalPort() + "/links/" + entry.getKey().getImgurl());//图片链接
+ }
+ } else {
+ jsonObject.put("Imgurl", entry.getKey().getImgurl());
+ img.setImgurl(entry.getKey().getImgurl());//图片链接
+ }
+ img.setUpdatetime(times);
+ img.setSource(key.getStorageType());
+ if (u == null) {
+ img.setUserid(0);//用户id
+ } else {
+ img.setUserid(u.getId());//用户id
+ }
+ img.setSizes((entry.getValue()));
+ img.setImgname(SetText.getSubString(entry.getKey().getImgurl(), key.getRequestAddress() + "/", ""));
+ img.setAbnormal(0);
+ //-1证明超出大小,
+ if (entry.getValue() != -1) {
+ userService.insertimg(img);
+ }
+ long etime = System.currentTimeMillis();
+ System.out.println("上传图片所用时长:" + String.valueOf(etime - stime) + "ms");
+ jsonArray.add(jsonObject);
+ }
+ }
+ //上传成功
+ resultBean = ResultBean.success(jsonArray);
+ } else {resultBean = ResultBean.error(-1, "服务器内部错误,请联系管理员");}
+ }
+ } else {resultBean = ResultBean.error(-2, "此用户信息不正确。");}
+ } else {resultBean = ResultBean.error(-3, "邮箱密码为空");}
+ }
+ else{resultBean = ResultBean.error(-4, "管理员关闭了API接口");}
+ //return jsonArray.toString();
+ return resultBean;
+ }
+
+ @GetMapping (value = "/notices")
+ @ResponseBody
+ public String notices() throws Exception {
+
+ return "-1";//-1就是没有公告,客户端不显示
+ }
+
+
+
+}
diff --git a/src/main/java/cn/hellohao/controller/ExceptionHandling.java b/src/main/java/cn/hellohao/controller/ExceptionHandling.java
new file mode 100644
index 0000000..021164b
--- /dev/null
+++ b/src/main/java/cn/hellohao/controller/ExceptionHandling.java
@@ -0,0 +1,68 @@
+package cn.hellohao.controller;
+
+import cn.hellohao.exception.StorageSourceInitException;
+import cn.hellohao.utils.Print;
+import org.springframework.validation.BindException;
+import org.springframework.validation.ObjectError;
+import org.springframework.web.bind.annotation.ControllerAdvice;
+import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.servlet.ModelAndView;
+
+import java.net.SocketException;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author Hellohao
+ * @version 1.0
+ * @date 2019/8/6 8:57
+ */
+
+@ControllerAdvice
+public class ExceptionHandling {
+
+ @ExceptionHandler
+ //@ResponseBody
+ public ModelAndView test(StorageSourceInitException ssie){
+ ModelAndView modelAndView = new ModelAndView("index");
+ Print.Normal("异常拦截成功:"+ ssie.getMessage());
+ modelAndView.addObject("error",ssie.getMessage());
+ //返回错误信息,并显示给用户
+ return modelAndView;
+ }
+
+ @ExceptionHandler
+ public String test4(SocketException e){
+ ModelAndView modelAndView = new ModelAndView("/index");
+ Print.Normal("存储源配置不正确,初始化失败"+ e.getMessage());
+ modelAndView.addObject("error",e.getMessage());
+ //返回错误信息,并显示给用户
+ return e.getMessage();
+ }
+ @ExceptionHandler
+ public String test3(Exception e){
+ ModelAndView modelAndView = new ModelAndView("/index");
+ Print.Normal("系统内部错误:"+ e.getMessage());
+ modelAndView.addObject("error",e.getMessage());
+ //返回错误信息,并显示给用户
+ return e.getMessage();
+ }
+
+
+// @ExceptionHandler
+// public String methodArgumentNotValid(BindException e) {
+// List allErrors = e.getBindingResult().getAllErrors();
+// StringBuilder errorMessage = new StringBuilder();
+// for (int i = 0; i < allErrors.size(); i++) {
+// ObjectError error = allErrors.get(i);
+// errorMessage.append(error.getDefaultMessage());
+// if (i != allErrors.size() - 1) {
+// errorMessage.append(", ");
+// }
+// }
+// // do something
+// System.out.println(errorMessage.toString());// 这里面是错误信息
+// return errorMessage.toString();
+// }
+
+}
diff --git a/src/main/java/cn/hellohao/controller/UpdateImgController.java b/src/main/java/cn/hellohao/controller/UpdateImgController.java
index d6b521b..3412e2b 100644
--- a/src/main/java/cn/hellohao/controller/UpdateImgController.java
+++ b/src/main/java/cn/hellohao/controller/UpdateImgController.java
@@ -6,6 +6,7 @@ import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
+import cn.hellohao.exception.StorageSourceInitException;
import cn.hellohao.pojo.*;
import cn.hellohao.service.*;
import cn.hellohao.service.impl.*;
@@ -65,27 +66,28 @@ public class UpdateImgController {
key= keysService.selectKeys(config.getSourcekey());//然后根据类型再查询key
//b = StringUtils.doNull(key);//判断对象是否有空值
if(key.getStorageType()!=0 && key.getStorageType()!=null){
+ int ret =0;
if(key.getStorageType()==1){
- nOSImageupload.Initialize(key);//实例化网易
+ ret =nOSImageupload.Initialize(key);//实例化网易
}else if (key.getStorageType()==2){
- OSSImageupload.Initialize(key);
+ ret =OSSImageupload.Initialize(key);
}else if(key.getStorageType()==3){
- USSImageupload.Initialize(key);
+ ret = USSImageupload.Initialize(key);
}else if(key.getStorageType()==4){
- KODOImageupload.Initialize(key);
+ ret = KODOImageupload.Initialize(key);
}else if(key.getStorageType()==6){
- COSImageupload.Initialize(key);
+ ret = COSImageupload.Initialize(key);
}else if(key.getStorageType()==7){
- FTPImageupload.Initialize(key);
+ ret = FTPImageupload.Initialize(key);
}
else{
Print.Normal("为获取到存储参数,或者使用存储源是本地的。");
}
+ if(ret<1){model.addAttribute("error", "当前存储源参数配置不完整,请联系管理员配置存储源。");}
+ else{model.addAttribute("error", 1);}
}
}
- //if(b){
- //}
User u = (User) httpSession.getAttribute("user");
String email = (String) httpSession.getAttribute("email");
if (email != null) {
@@ -114,7 +116,6 @@ public class UpdateImgController {
Integer isupdate = 1;
if(uploadConfig.getIsupdate()!=1){
isupdate = (u == null) ? 0: 1;//如果u等于null那么isupdate就等于0,否则等于1
- //isupdate=0;
}
model.addAttribute("ykxz", isupdate);
return "index";
diff --git a/src/main/java/cn/hellohao/controller/UserController.java b/src/main/java/cn/hellohao/controller/UserController.java
index 3fc6354..4f3d2e9 100644
--- a/src/main/java/cn/hellohao/controller/UserController.java
+++ b/src/main/java/cn/hellohao/controller/UserController.java
@@ -7,6 +7,7 @@ import java.util.UUID;
import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
+import javax.validation.Valid;
import cn.hellohao.pojo.Config;
import cn.hellohao.pojo.EmailConfig;
@@ -39,7 +40,7 @@ public class UserController {
@RequestMapping("/register")
@ResponseBody
- public String Register(User user) {
+ public String Register(@Valid User user) {
//取当前时间
JSONObject jsonObject = new JSONObject();
EmailConfig emailConfig = emailConfigService.getemail();
@@ -82,9 +83,10 @@ public class UserController {
return jsonObject.toString();
}
+
@RequestMapping("/login.do")
@ResponseBody
- public String login(HttpServletRequest request, HttpSession httpSession, String email, String password) {
+ public String login( HttpSession httpSession, String email, String password) {
JSONArray jsonArray = new JSONArray();
Integer ret = userService.login(email, password);
diff --git a/src/main/java/cn/hellohao/exception/LoginException.java b/src/main/java/cn/hellohao/exception/LoginException.java
new file mode 100644
index 0000000..343c705
--- /dev/null
+++ b/src/main/java/cn/hellohao/exception/LoginException.java
@@ -0,0 +1,27 @@
+package cn.hellohao.exception;
+
+/**
+ * @author Tiansh
+ * @version 1.0
+ * @date 2019/8/7 9:02
+ */
+public class LoginException extends RuntimeException {
+ public LoginException() {
+ }
+
+ public LoginException(String message) {
+ super(message);
+ }
+
+ public LoginException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public LoginException(Throwable cause) {
+ super(cause);
+ }
+
+ public LoginException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/src/main/java/cn/hellohao/exception/StorageSourceInitException.java b/src/main/java/cn/hellohao/exception/StorageSourceInitException.java
new file mode 100644
index 0000000..f5dcd6d
--- /dev/null
+++ b/src/main/java/cn/hellohao/exception/StorageSourceInitException.java
@@ -0,0 +1,29 @@
+package cn.hellohao.exception;
+
+/**
+ * @author Hellohao
+ * @version 1.0
+ * @date 2019/8/6 8:51
+ */
+//创建自定义异常
+//
+public class StorageSourceInitException extends RuntimeException {
+ public StorageSourceInitException() {
+ }
+
+ public StorageSourceInitException(String message) {
+ super(message);
+ }
+
+ public StorageSourceInitException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public StorageSourceInitException(Throwable cause) {
+ super(cause);
+ }
+
+ public StorageSourceInitException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/src/main/java/cn/hellohao/pojo/ResultBean.java b/src/main/java/cn/hellohao/pojo/ResultBean.java
new file mode 100644
index 0000000..75293fc
--- /dev/null
+++ b/src/main/java/cn/hellohao/pojo/ResultBean.java
@@ -0,0 +1,56 @@
+package cn.hellohao.pojo;
+
+public class ResultBean {
+ private int code;
+ private String msg;
+ private Object data;
+
+ private ResultBean() {
+ }
+
+ public static ResultBean error(int code, String msg) {
+ ResultBean resultBean = new ResultBean();
+ resultBean.setCode(code);
+ resultBean.setmsg(msg);
+ return resultBean;
+ }
+
+ public static ResultBean success() {
+ ResultBean resultBean = new ResultBean();
+ resultBean.setCode(0);
+ resultBean.setmsg("success");
+ return resultBean;
+ }
+
+ public static ResultBean success(Object data) {
+ ResultBean resultBean = new ResultBean();
+ resultBean.setCode(200);
+ resultBean.setmsg("success");
+ resultBean.setData(data);
+ return resultBean;
+ }
+
+ public int getCode() {
+ return code;
+ }
+
+ public void setCode(int code) {
+ this.code = code;
+ }
+
+ public String getmsg() {
+ return msg;
+ }
+
+ public void setmsg(String msg) {
+ this.msg = msg;
+ }
+
+ public Object getData() {
+ return data;
+ }
+
+ public void setData(Object data) {
+ this.data = data;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/cn/hellohao/pojo/UploadConfig.java b/src/main/java/cn/hellohao/pojo/UploadConfig.java
index 09fca85..f76773c 100644
--- a/src/main/java/cn/hellohao/pojo/UploadConfig.java
+++ b/src/main/java/cn/hellohao/pojo/UploadConfig.java
@@ -8,11 +8,12 @@ public class UploadConfig {
private Integer imgcountuser;
private Integer urltype;
private Integer isupdate;
+ private Integer api;
public UploadConfig() {
}
- public UploadConfig(String suffix, Integer filesizetourists, Integer filesizeuser, Integer imgcounttourists, Integer imgcountuser, Integer urltype, Integer isupdate) {
+ public UploadConfig(String suffix, Integer filesizetourists, Integer filesizeuser, Integer imgcounttourists, Integer imgcountuser, Integer urltype, Integer isupdate, Integer api) {
this.suffix = suffix;
this.filesizetourists = filesizetourists;
this.filesizeuser = filesizeuser;
@@ -20,6 +21,7 @@ public class UploadConfig {
this.imgcountuser = imgcountuser;
this.urltype = urltype;
this.isupdate = isupdate;
+ this.api = api;
}
public String getSuffix() {
@@ -77,4 +79,12 @@ public class UploadConfig {
public void setIsupdate(Integer isupdate) {
this.isupdate = isupdate;
}
+
+ public Integer getApi() {
+ return api;
+ }
+
+ public void setApi(Integer api) {
+ this.api = api;
+ }
}
diff --git a/src/main/java/cn/hellohao/pojo/User.java b/src/main/java/cn/hellohao/pojo/User.java
index c484246..410d72b 100644
--- a/src/main/java/cn/hellohao/pojo/User.java
+++ b/src/main/java/cn/hellohao/pojo/User.java
@@ -1,9 +1,20 @@
package cn.hellohao.pojo;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotBlank;
+
public class User {
+
private Integer id;
+ //@NotBlank(message = "用户名不能为空")
+ // @Length(min = 6, max = 20, message = "用户名需要为 6 - 20 个字符")
private String username;
+ //@NotBlank(message = "密码不能为空")
private String password;
+ // @NotBlank(message = "邮箱不能为空")
+ //@Email(message = "邮箱格式不正确")
private String email;
private String birthder;
private Integer level;
diff --git a/src/main/java/cn/hellohao/service/impl/COSImageupload.java b/src/main/java/cn/hellohao/service/impl/COSImageupload.java
index 723c1f0..b4d877d 100644
--- a/src/main/java/cn/hellohao/service/impl/COSImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/COSImageupload.java
@@ -2,6 +2,7 @@ package cn.hellohao.service.impl;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.ImgUrlUtil;
import cn.hellohao.utils.Print;
import com.netease.cloud.auth.BasicCredentials;
@@ -112,56 +113,72 @@ public class COSImageupload {
}
//初始化网易NOS对象存储
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if(k.getEndpoint()!=null && k.getAccessSecret()!=null && k.getEndpoint()!=null
&& k.getBucketname()!=null && k.getRequestAddress()!=null ) {
-// 1 初始化用户身份信息(secretId, secretKey)。
- String secretId = k.getAccessKey();
- String secretKey = k.getAccessSecret();
- COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
-// 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
-// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
- Region region = new Region(k.getEndpoint());
- ClientConfig clientConfig = new ClientConfig(region);
-// 3 生成 cos 客户端。
- cosClient = new COSClient(cred, clientConfig);
- System.out.println("==="+cosClient);
-//查询桶
- try {
- List buckets = cosClient.listBuckets();
- for (Bucket bucket : buckets) {
- if (bucket.getName().equals(k.getBucketname())) {
- Print.Normal("当前桶名称:" + bucket.getName());
- BarrelName = bucket.getName();
- }
- }
- } catch (CosServiceException serverException) {
- serverException.printStackTrace();
- } catch (CosClientException clientException) {
- clientException.printStackTrace();
+ if(!k.getEndpoint().equals("") && !k.getAccessSecret().equals("") && !k.getEndpoint().equals("")
+ && !k.getBucketname().equals("") && !k.getRequestAddress().equals("") ) {
+ // 1 初始化用户身份信息(secretId, secretKey)。
+ String secretId = k.getAccessKey();
+ String secretKey = k.getAccessSecret();
+ COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
+ // 2 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
+ // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
+ Region region = new Region(k.getEndpoint());
+ ClientConfig clientConfig = new ClientConfig(region);
+ // 3 生成 cos 客户端。
+ cosClient = new COSClient(cred, clientConfig);
+ BarrelName = k.getBucketname();
+ //查询桶
+// try {
+// List buckets = cosClient.listBuckets();
+// for (Bucket bucket : buckets) {
+// if (bucket.getName().equals(k.getBucketname())) {
+// Print.Normal("当前桶名称:" + bucket.getName());
+// BarrelName = bucket.getName();
+// }
+// }
+// } catch (CosServiceException serverException) {
+// serverException.printStackTrace();
+// } catch (CosClientException clientException) {
+// clientException.printStackTrace();
+// }
+ key = k;
+ ret = 1;
}
- key = k;
}
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadCOS(Map fileMap, String username) throws Exception {
+ public Map clientuploadCOS(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
for (Map.Entry entry : fileMap.entrySet()) {
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase().substring(0,5);//生成一个没有-的uuid,然后取前5位
java.text.DateFormat format1 = new java.text.SimpleDateFormat("MMddhhmmss");
String times = format1.format(new Date());
file = changeFile(entry.getValue());
try {
- // 指定要上传到 COS 上对象键
- String userkey =username + "/" + uuid+times + "." + entry.getKey();
- PutObjectRequest putObjectRequest = new PutObjectRequest(BarrelName, userkey, file);
- PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
- ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ // 指定要上传到 COS 上对象键
+ String userkey =username + "/" + uuid+times + "." + entry.getKey();
+ PutObjectRequest putObjectRequest = new PutObjectRequest(BarrelName, userkey, file);
+ PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + userkey);
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+// ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ }else{
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
+ }
} catch (Exception e) {
System.out.println("上传报错:" + e.getMessage());
}
diff --git a/src/main/java/cn/hellohao/service/impl/FTPImageupload.java b/src/main/java/cn/hellohao/service/impl/FTPImageupload.java
index 32da0a5..aae42dc 100644
--- a/src/main/java/cn/hellohao/service/impl/FTPImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/FTPImageupload.java
@@ -2,6 +2,7 @@ package cn.hellohao.service.impl;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.FTPUtils;
import cn.hellohao.utils.ImgUrlUtil;
import cn.hellohao.utils.Print;
@@ -100,48 +101,56 @@ public class FTPImageupload {
}
//初始化FTP对象存储
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if(k.getEndpoint()!=null && k.getAccessSecret()!=null && k.getEndpoint()!=null && k.getRequestAddress()!=null ) {
- FTPClient ftp = new FTPClient();
- String[] host = k.getEndpoint().split("\\:");
- String h = host[0];
- Integer p = Integer.parseInt(host[1]);
- try {
- if(!ftp.isConnected()){
- ftp.connect(h,p);
- }
- //如果是需要认证的服务器,就需要账号和密码来登录
- ftp.login(k.getAccessKey(), k.getAccessSecret());
- } catch (IOException e) {
- e.printStackTrace();
+ if(!k.getEndpoint().equals("") && !k.getAccessSecret().equals("") && !k.getEndpoint().equals("") && !k.getRequestAddress().equals("") ) {
+ FTPClient ftp = new FTPClient();
+ int flag = k.getEndpoint().indexOf(":");
+ if(flag>0){
+ String[] host = k.getEndpoint().split("\\:");
+ String h = host[0];
+ Integer p = Integer.parseInt(host[1]);
+ try {
+ if(!ftp.isConnected()){
+ ftp.connect(h,p);
+ }
+ //如果是需要认证的服务器,就需要账号和密码来登录
+ ftp.login(k.getAccessKey(), k.getAccessSecret());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ //获取服务器返回的状态码
+ int reply = ftp.getReplyCode();
+ System.out.println(reply);
+ /*
+ * 判断是否连接成功
+ * 所有以2开头的代码是正完成响应。
+ * FTP服务器将在最终发送一个肯定的完成响应成功完成命令。
+ */
+ if (!FTPReply.isPositiveCompletion(reply)) {
+ try {
+ ftp.disconnect();
+ }catch (IOException e){
+ System.out.println(e);
+ }
+ Print.warning("连接失败");
+ ret = -1;
+ }
+ Print.Normal("链接成功");
+ //boolean isUpload = ftp.storeFile("/ftp/upload.jpg", fis);
+ ftpClient1 = ftp;
+ key = k;
+ ret = 1;
}
- //获取服务器返回的状态码
- int reply = ftp.getReplyCode();
- System.out.println(reply);
- /*
- * 判断是否连接成功
- * 所有以2开头的代码是正完成响应。
- * FTP服务器将在最终发送一个肯定的完成响应成功完成命令。
- */
- if (!FTPReply.isPositiveCompletion(reply)) {
- try {
- ftp.disconnect();
- }catch (IOException e){
- System.out.println(e);
- }
- Print.warning("连接失败");
- return;
}
- Print.Normal("链接成功");
- //boolean isUpload = ftp.storeFile("/ftp/upload.jpg", fis);
- ftpClient1 = ftp;
- key = k;
- }
+ }
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadCOS(Map fileMap, String username) throws Exception {
+ public Map clientuploadFTP(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
String[] host = key.getEndpoint().split("\\:");
String h = host[0];
Integer p = Integer.parseInt(host[1]);
@@ -149,7 +158,7 @@ public class FTPImageupload {
FTPUtils ftps = new FTPUtils(h, p, key.getAccessKey(), key.getAccessSecret());
boolean flag = ftps.open();
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
for (Map.Entry entry : fileMap.entrySet()) {
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase().substring(0,5);//生成一个没有-的uuid,然后取前5位
java.text.DateFormat format1 = new java.text.SimpleDateFormat("MMddhhmmss");
@@ -158,11 +167,22 @@ public class FTPImageupload {
String userkey =username + File.separator+ uuid+times + "." + entry.getKey();
ftps.mkDir(File.separator+username);
if (flag) {
- ftps.upload(file, File.separator+userkey, "");
ReturnImage returnImage = new ReturnImage();
- returnImage.setImgurl(key.getRequestAddress() + File.separator+ userkey);
- ImgUrl.put(key.getRequestAddress() + File.separator+userkey + username + File.separator+userkey + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
- ftps.close();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ ftps.upload(file, File.separator+userkey, "");
+
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + File.separator+ userkey);
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+ //ImgUrl.put(key.getRequestAddress() + File.separator+userkey + username + File.separator+userkey + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ ftps.close();
+ }else{
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
+ ftps.close();
+ }
+
}
}
return ImgUrl;
diff --git a/src/main/java/cn/hellohao/service/impl/KODOImageupload.java b/src/main/java/cn/hellohao/service/impl/KODOImageupload.java
index 8b870e4..0717928 100644
--- a/src/main/java/cn/hellohao/service/impl/KODOImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/KODOImageupload.java
@@ -2,6 +2,7 @@ package cn.hellohao.service.impl;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.ImgUrlUtil;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.ObjectMetadata;
@@ -81,7 +82,6 @@ public class KODOImageupload {
ReturnImage returnImage = new ReturnImage();
returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
ImgUrl.put(returnImage, ImgUrlUtil.getFileSize2(new File(imgurl)));
- //System.out.println(putRet.hash);
new File(imgurl).delete();
} catch (QiniuException ex) {
Response r = ex.response;
@@ -112,37 +112,43 @@ public class KODOImageupload {
}
//初始化
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if (k.getEndpoint() != null && k.getAccessSecret() != null && k.getEndpoint() != null
&& k.getBucketname() != null && k.getRequestAddress() != null) {
- // 初始化
- // 创建KODOClient实例。
- Configuration cfg;
- //构造一个带指定Zone对象的配置类
- if (k.getEndpoint().equals("1")) {
- cfg = new Configuration(Zone.zone0());
- } else if (k.getEndpoint().equals("2")) {
- cfg = new Configuration(Zone.zone1());
- } else if (k.getEndpoint().equals("3")) {
- cfg = new Configuration(Zone.zone2());
- } else if (k.getEndpoint().equals("4")) {
- cfg = new Configuration(Zone.zoneNa0());
- } else {
- cfg = new Configuration(Zone.zoneAs0());
+ if (!k.getEndpoint().equals("") && !k.getAccessSecret() .equals("") && !k.getEndpoint() .equals("")
+ && !k.getBucketname().equals("") && !k.getRequestAddress() .equals("")) {
+ // 初始化
+ // 创建KODOClient实例。
+ Configuration cfg;
+ //构造一个带指定Zone对象的配置类
+ if (k.getEndpoint().equals("1")) {
+ cfg = new Configuration(Zone.zone0());
+ } else if (k.getEndpoint().equals("2")) {
+ cfg = new Configuration(Zone.zone1());
+ } else if (k.getEndpoint().equals("3")) {
+ cfg = new Configuration(Zone.zone2());
+ } else if (k.getEndpoint().equals("4")) {
+ cfg = new Configuration(Zone.zoneNa0());
+ } else {
+ cfg = new Configuration(Zone.zoneAs0());
+ }
+ uploadManager = new UploadManager(cfg);
+ Auth auth = Auth.create(k.getAccessKey(), k.getAccessSecret());
+ upToken = auth.uploadToken(k.getBucketname());
+ key = k;
+ ret = 1;
}
- uploadManager = new UploadManager(cfg);
- Auth auth = Auth.create(k.getAccessKey(), k.getAccessSecret());
- upToken = auth.uploadToken(k.getBucketname());
- key = k;
}
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadKODO(Map fileMap, String username) throws Exception {
+ public Map clientuploadKODO(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
for (Map.Entry entry : fileMap.entrySet()) {
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase().substring(0,5);//生成一个没有-的uuid,然后取前5位
@@ -151,10 +157,21 @@ public class KODOImageupload {
file = changeFile(entry.getValue());
System.out.println("待上传的图片:"+username + "/" + uuid+times + "." + entry.getKey());
try {
- Response response = uploadManager.put(file,username + "/" + uuid+times + "." + entry.getKey(),upToken);
- //解析上传成功的结果
- DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
- ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ Response response = uploadManager.put(file,username + "/" + uuid+times + "." + entry.getKey(),upToken);
+ //解析上传成功的结果
+ DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
+
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+ //ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ }else{
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
+ }
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
diff --git a/src/main/java/cn/hellohao/service/impl/NOSImageupload.java b/src/main/java/cn/hellohao/service/impl/NOSImageupload.java
index 8faa0b1..6255236 100644
--- a/src/main/java/cn/hellohao/service/impl/NOSImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/NOSImageupload.java
@@ -8,7 +8,9 @@ import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
+import cn.hellohao.exception.StorageSourceInitException;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.ImgUrlUtil;
import cn.hellohao.utils.Print;
import com.netease.cloud.services.nos.model.ObjectMetadata;
@@ -50,15 +52,12 @@ public class NOSImageupload {
java.text.DateFormat format1 = new java.text.SimpleDateFormat("MMddhhmmss");
String times = format1.format(new Date());
file = changeFile(entry.getValue());
- try {
- nosClient.putObject(BarrelName, username + "/" + uuid+times + "." + entry.getKey(), file);
- ReturnImage returnImage = new ReturnImage();
- returnImage.setImgname(entry.getValue().getOriginalFilename());
- returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
- ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
- } catch (Exception e) {
- System.out.println("上传报错:" + e.getMessage());
- }
+ nosClient.putObject(BarrelName, username + "/" + uuid+times + "." + entry.getKey(), file);
+ ReturnImage returnImage = new ReturnImage();
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+
}
return ImgUrl;
}else{
@@ -82,7 +81,7 @@ public class NOSImageupload {
}else if(entry.getKey().equals("gif")){
head = "image/gif";
}else{
- System.err.println("位置格式文件,无法定义header头。");
+ System.err.println("未知格式文件,无法定义header头。");
}
meta.setHeader("Content-Type", head);//image/jpeg
File file = new File(imgurl);
@@ -126,53 +125,71 @@ public class NOSImageupload {
//初始化网易NOS对象存储
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if(k.getEndpoint()!=null && k.getAccessSecret()!=null && k.getEndpoint()!=null
&& k.getBucketname()!=null && k.getRequestAddress()!=null ){
- // 初始化
- Credentials credentials = new BasicCredentials(k.getAccessKey(), k.getAccessSecret());
- nosClient = new NosClient(credentials);
- nosClient.setEndpoint(k.getEndpoint());
- // 初始化TransferManager
- TransferManager transferManager = new TransferManager(nosClient);
- // 列举桶
- ArrayList bucketList = new ArrayList();
- for (Bucket bucket : nosClient.listBuckets()) {
- bucketList.add(bucket.getName());
- }
- for (Object object : bucketList) {
- if (object.toString().equals(k.getBucketname())) {
- BarrelName = object.toString();
- }
- }
- key = k;
- }
+ if(!k.getEndpoint().equals("") && !k.getAccessSecret().equals("") && !k.getEndpoint().equals("")
+ && !k.getBucketname().equals("") && !k.getRequestAddress().equals("") ){
+ // 初始化
+ Credentials credentials = new BasicCredentials(k.getAccessKey(), k.getAccessSecret());
+ nosClient = new NosClient(credentials);
+ nosClient.setEndpoint(k.getEndpoint());
+ // 列举桶
+ ArrayList bucketList = new ArrayList();
+ //加入传入的key值不正确,这里会报异常,页面500,如何捕捉异常处理。
+ BarrelName = k.getBucketname();
+ // for (Bucket bucket : nosClient.listBuckets()) {
+ // bucketList.add(bucket.getName());
+ // }
+ // for (Object object : bucketList) {
+ // if (object.toString().equals(k.getBucketname())) {
+ // BarrelName = object.toString();
+ // }
+ // }
+ key = k;
+ ret = 1;
+ }else{
+ ret = -1;
+ }
+ }else{
+ ret = -1;
+ //throw new StorageSourceInitException("当前数据源配置不完整,请管理员前往后台配置。");
+ }
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadNOS(Map fileMap, String username) throws Exception {
-
+ public Map clientuploadNOS(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
for (Map.Entry entry : fileMap.entrySet()) {
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase().substring(0,5);//生成一个没有-的uuid,然后取前5位
java.text.DateFormat format1 = new java.text.SimpleDateFormat("MMddhhmmss");
String times = format1.format(new Date());
file = changeFile(entry.getValue());
try {
- nosClient.putObject(BarrelName, username + "/" + uuid+times + "." + entry.getKey(), file);
- ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
-
+ Print.warning(entry.getValue().getSize());
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ nosClient.putObject(BarrelName, username + "/" + uuid+times + "." + entry.getKey(), file);
+ //ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+ }else{
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
+ }
} catch (Exception e) {
System.out.println("上传报错:" + e.getMessage());
}
}
return ImgUrl;
-
}
-
}
diff --git a/src/main/java/cn/hellohao/service/impl/OSSImageupload.java b/src/main/java/cn/hellohao/service/impl/OSSImageupload.java
index 0baff3e..43081d6 100644
--- a/src/main/java/cn/hellohao/service/impl/OSSImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/OSSImageupload.java
@@ -2,6 +2,7 @@ package cn.hellohao.service.impl;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.ImgUrlUtil;
import cn.hellohao.utils.Print;
import com.aliyun.oss.OSSClient;
@@ -113,24 +114,28 @@ public class OSSImageupload {
}
//初始化
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if(k.getEndpoint()!=null && k.getAccessSecret()!=null && k.getEndpoint()!=null
&& k.getBucketname()!=null && k.getRequestAddress()!=null ) {
- // 初始化
- // 创建OSSClient实例。
- ossClient = new OSSClient(k.getEndpoint(), k.getAccessKey(), k.getAccessSecret());
- key = k;
+ if(!k.getEndpoint().equals("") && !k.getAccessSecret().equals("") && !k.getEndpoint().equals("")
+ && !k.getBucketname().equals("") && !k.getRequestAddress().equals("") ) {
+ ossClient = new OSSClient(k.getEndpoint(), k.getAccessKey(), k.getAccessSecret());
+ key = k;
+ ret=1;
+ }
}
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadOSS(Map fileMap, String username) throws Exception {
+ public Map clientuploadOSS(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
//设置Header
ObjectMetadata meta = new ObjectMetadata();
meta.setHeader("Content-Disposition", "inline");
@@ -153,14 +158,21 @@ public class OSSImageupload {
System.err.println("位置格式文件,无法定义header头。");
}
meta.setHeader("Content-Type", head);//image/jpeg
- // 上传文件流。
- System.out.println("待上传的图片:"+username + "/" + uuid+times + "." + entry.getKey());
- ossClient.putObject(key.getBucketname(), username + "/" + uuid+times + "." + entry.getKey(),file,meta);
- // 关闭OSSClient。
- //ossClient.shutdown();
- Print.Normal(entry.getValue().getSize());
- ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()/1024));
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ // 上传文件流。
+ System.out.println("待上传的图片:"+username + "/" + uuid+times + "." + entry.getKey());
+ ossClient.putObject(key.getBucketname(), username + "/" + uuid+times + "." + entry.getKey(),file,meta);
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+ //ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()/1024));
+ }else{
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
+ }
}
return ImgUrl;
diff --git a/src/main/java/cn/hellohao/service/impl/USSImageupload.java b/src/main/java/cn/hellohao/service/impl/USSImageupload.java
index 0c3e850..93fa2e0 100644
--- a/src/main/java/cn/hellohao/service/impl/USSImageupload.java
+++ b/src/main/java/cn/hellohao/service/impl/USSImageupload.java
@@ -2,6 +2,7 @@ package cn.hellohao.service.impl;
import cn.hellohao.pojo.Keys;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import cn.hellohao.utils.ImgUrlUtil;
import com.UpYun;
import com.aliyun.oss.OSSClient;
@@ -91,23 +92,29 @@ public class USSImageupload {
}
//初始化
- public static void Initialize(Keys k) {
+ public static Integer Initialize(Keys k) {
+ int ret = -1;
if(k.getEndpoint()!=null && k.getAccessSecret()!=null
&& k.getBucketname()!=null && k.getRequestAddress()!=null ) {
- // 初始化
- // 创建UpYun实例。
- upyun = new UpYun(k.getBucketname(), k.getAccessKey(), k.getAccessSecret());
- key = k;
+ if(!k.getEndpoint().equals("") && !k.getAccessSecret().equals("")
+ && !k.getBucketname().equals("") && !k.getRequestAddress().equals("") ) {
+ // 初始化
+ // 创建UpYun实例。
+ upyun = new UpYun(k.getBucketname(), k.getAccessKey(), k.getAccessSecret());
+ key = k;
+ ret = 1;
+ }
}
+ return ret;
}
/**
* 客户端接口
* */
- public Map clientuploadUSS(Map fileMap, String username) throws Exception {
+ public Map clientuploadUSS(Map fileMap, String username, UploadConfig uploadConfig) throws Exception {
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
//设置Header
ObjectMetadata meta = new ObjectMetadata();
meta.setHeader("Content-Disposition", "inline");
@@ -118,13 +125,24 @@ public class USSImageupload {
file = changeFile(entry.getValue());
// 上传文件流。
System.out.println("客户端:待上传的图片:"+username + "/" + uuid+times + "." + entry.getKey());
- // 例2:采用数据流模式上传文件(节省内存),自动创建父级目录
- upyun.setContentMD5(UpYun.md5(file));
- boolean result = upyun.writeFile(username + "/" + uuid+times + "." + entry.getKey(), file, true);
- if(result){
- ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ // 例2:采用数据流模式上传文件(节省内存),自动创建父级目录
+ upyun.setContentMD5(UpYun.md5(file));
+ boolean result = upyun.writeFile(username + "/" + uuid+times + "." + entry.getKey(), file, true);
+ if(result){
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+
+ //ImgUrl.put(key.getRequestAddress() + "/" + username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ }else{
+ System.err.println("上传失败");
+ }
}else{
- System.err.println("上传失败");
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage, -1);
}
}
return ImgUrl;
diff --git a/src/main/java/cn/hellohao/test/test1.java b/src/main/java/cn/hellohao/test/test1.java
index d4c66ac..7e4a428 100644
--- a/src/main/java/cn/hellohao/test/test1.java
+++ b/src/main/java/cn/hellohao/test/test1.java
@@ -11,22 +11,10 @@ public class test1 {
public static void main(String[] args) {
-//匿名登录(无需帐号密码的FTP服务器)
- Ftp ftp = new Ftp("hellohao.cn");
- ftp.init("hellohao.cn",21,"test","test");
-//进入远程目录
- //ftp.cd("/opt/upload");
-//上传本地文件
- ftp.upload("/ftp/222222222.jpg", FileUtil.file("C:\\Users\\tiansh\\Desktop\\11.jpg"));
-//下载远程文件
- //ftp.download("/opt/upload", "test.jpg", FileUtil.file("e:/test2.jpg"));
-//关闭连接
- try {
- ftp.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
+ String str = "hellohao.cn:888";
+ int flag = str.indexOf(":");
+ System.out.println(flag);
}
diff --git a/src/main/java/cn/hellohao/utils/LocUpdateImg.java b/src/main/java/cn/hellohao/utils/LocUpdateImg.java
index 03f7554..b08f827 100644
--- a/src/main/java/cn/hellohao/utils/LocUpdateImg.java
+++ b/src/main/java/cn/hellohao/utils/LocUpdateImg.java
@@ -1,6 +1,7 @@
package cn.hellohao.utils;
import cn.hellohao.pojo.ReturnImage;
+import cn.hellohao.pojo.UploadConfig;
import com.google.gson.Gson;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
@@ -78,10 +79,10 @@ public class LocUpdateImg {
/**
* 客户端接口
* */
- public Map clientuploadKODO(Map fileMap, String username) throws Exception {
+ public static Map clientuploadFTP(Map fileMap, String username, UploadConfig uploadConfig) {
String filePath =File.separator + "HellohaoData" + File.separator;
File file = null;
- Map ImgUrl = new HashMap<>();
+ Map ImgUrl = new HashMap<>();
for (Map.Entry entry : fileMap.entrySet()) {
String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase().substring(0,5);//生成一个没有-的uuid,然后取前5位
java.text.DateFormat format1 = new java.text.SimpleDateFormat("MMddhhmmss");
@@ -89,16 +90,27 @@ public class LocUpdateImg {
//file = SetFiles.changeFile(entry.getValue());
// 上传文件流。
System.out.println("待上传的图片:"+username + "/" + uuid+times + "." + entry.getKey());
- File dest = new File(filePath + username + File.separator+ uuid+times + "." + entry.getKey());
- if (!dest.getParentFile().exists()) {
- dest.getParentFile().mkdirs();
- }
- try {
- entry.getValue().transferTo(dest);
- ImgUrl.put(username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
- } catch (IOException e) {
- e.printStackTrace();
- System.err.println("上传失败");
+ ReturnImage returnImage = new ReturnImage();
+ if(entry.getValue().getSize()/1024<=uploadConfig.getFilesizeuser()*1024){
+ File dest = new File(filePath + username + File.separator+ uuid+times + "." + entry.getKey());
+ if (!dest.getParentFile().exists()) {
+ dest.getParentFile().mkdirs();
+ }
+ try {
+ entry.getValue().transferTo(dest);
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl(username + "/" + uuid+times + "." + entry.getKey());
+ ImgUrl.put(returnImage, (int) (entry.getValue().getSize()));
+ //ImgUrl.put(username + "/" + uuid+times + "." + entry.getKey(), (int) (entry.getValue().getSize()));
+ } catch (IOException e) {
+ e.printStackTrace();
+ System.err.println("上传失败");
+ }
+ }else{
+ //ImgUrl.put("文件超出系统设定大小,不得超过"+uploadConfig.getFilesizeuser()+"M", -1);
+ returnImage.setImgname(entry.getValue().getOriginalFilename());
+ returnImage.setImgurl("文件超出系统设定大小,不得超过");
+ ImgUrl.put(returnImage,-1);
}
}
return ImgUrl;
diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties
index 5b5b57e..d0a85cc 100644
--- a/src/main/resources/application.properties
+++ b/src/main/resources/application.properties
@@ -1,8 +1,8 @@
#ݿ˺
spring.datasource.username=root
-#ݿ
+#ݿtest
spring.datasource.password=root
-#ݿӵַ
+#ݿӵַ129.28.173.126
spring.datasource.url=jdbc:mysql://localhost:3306/picturebed?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
#˿
server.port=8088
@@ -24,7 +24,7 @@ multipart.maxFileSize=10240KB
multipart.maxRequestSize=10240KB
spring.thymeleaf.mode = LEGACYHTML5
spring.http.multipart.location=/data/upload_tmp
-systemupdate=2019-08-01
+systemupdate=2019-08-07
diff --git a/src/main/resources/mapper/UploadConfigMapper.xml b/src/main/resources/mapper/UploadConfigMapper.xml
index 269e8e8..e782400 100644
--- a/src/main/resources/mapper/UploadConfigMapper.xml
+++ b/src/main/resources/mapper/UploadConfigMapper.xml
@@ -28,7 +28,10 @@
`urltype` = #{urltype},
- `isupdate` = #{isupdate}
+ `isupdate` = #{isupdate},
+
+
+ `api` = #{api}
diff --git a/src/main/resources/static/js/jquery.qrcode.min.js b/src/main/resources/static/js/jquery.qrcode.min.js
new file mode 100644
index 0000000..f3be5da
--- /dev/null
+++ b/src/main/resources/static/js/jquery.qrcode.min.js
@@ -0,0 +1 @@
+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.jrQrcode=e():t.jrQrcode=e()}(this,function(){return function(t){function e(o){if(r[o])return r[o].exports;var n=r[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var r={};return e.m=t,e.c=r,e.p="",e(0)}([function(t,e,r){"use strict";t.exports=r(3)},function(t,e){"use strict";!function(){Object.assign||Object.defineProperty(Object,"assign",{enumerable:!1,configurable:!0,writable:!0,value:function(t){if(void 0===t||null===t)throw new TypeError("Cannot convert first argument to object");for(var e=Object(t),r=1;r=1&&n<=127?e+=t.charAt(r):n>2047?(e+=String.fromCharCode(224|n>>12&15),e+=String.fromCharCode(128|n>>6&63),e+=String.fromCharCode(128|n>>0&63)):(e+=String.fromCharCode(192|n>>6&31),e+=String.fromCharCode(128|n>>0&63));return e},t.utf8to16=function(t){var e,r,o,n,i,a;for(e="",o=t.length,r=0;r>4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:e+=t.charAt(r-1);break;case 12:case 13:i=t.charCodeAt(r++),e+=String.fromCharCode((31&n)<<6|63&i);break;case 14:i=t.charCodeAt(r++),a=t.charCodeAt(r++),e+=String.fromCharCode((15&n)<<12|(63&i)<<6|(63&a)<<0)}return e},t}()},function(t,e,r){"use strict";r(1),r(4);var o=r(2),n=function(){function t(t){var e=new QRCode(t.typeNumber,t.correctLevel);e.addData(t.text),e.make();var r=document.createElement("canvas");r.width=t.width,r.height=t.height;var o=r.getContext("2d"),n=(t.width-2*t.padding)/e.getModuleCount(),i=(t.height-2*t.padding)/e.getModuleCount();if(t.reverse){var a="rgba(0, 0, 0, 0)";o.fillStyle=a,t.foreground=a}else o.fillStyle=t.background;o.fillRect(0,0,r.width,r.height);for(var s=0;s=7&&this.setupTypeNumber(t),null==this.dataCache&&(this.dataCache=o.createData(this.typeNumber,this.errorCorrectLevel,this.dataList)),this.mapData(this.dataCache,e)},setupPositionProbePattern:function(t,e){for(var r=-1;r<=7;r++)if(!(t+r<=-1||this.moduleCount<=t+r))for(var o=-1;o<=7;o++)e+o<=-1||this.moduleCount<=e+o||(0<=r&&r<=6&&(0==o||6==o)||0<=o&&o<=6&&(0==r||6==r)||2<=r&&r<=4&&2<=o&&o<=4?this.modules[t+r][e+o]=!0:this.modules[t+r][e+o]=!1)},getBestMaskPattern:function(){for(var t=0,e=0,r=0;r<8;r++){this.makeImpl(!0,r);var o=f.getLostPoint(this);(0==r||t>o)&&(t=o,e=r)}return e},createMovieClip:function(t,e,r){var o=t.createEmptyMovieClip(e,r),n=1;this.make();for(var i=0;i>r&1);this.modules[Math.floor(r/3)][r%3+this.moduleCount-8-3]=o}for(var r=0;r<18;r++){var o=!t&&1==(e>>r&1);this.modules[r%3+this.moduleCount-8-3][Math.floor(r/3)]=o}},setupTypeInfo:function(t,e){for(var r=this.errorCorrectLevel<<3|e,o=f.getBCHTypeInfo(r),n=0;n<15;n++){var i=!t&&1==(o>>n&1);n<6?this.modules[n][8]=i:n<8?this.modules[n+1][8]=i:this.modules[this.moduleCount-15+n][8]=i}for(var n=0;n<15;n++){var i=!t&&1==(o>>n&1);n<8?this.modules[8][this.moduleCount-n-1]=i:n<9?this.modules[8][15-n-1+1]=i:this.modules[8][15-n-1]=i}this.modules[this.moduleCount-8][8]=!t},mapData:function(t,e){for(var r=-1,o=this.moduleCount-1,n=7,i=0,a=this.moduleCount-1;a>0;a-=2)for(6==a&&a--;;){for(var s=0;s<2;s++)if(null==this.modules[o][a-s]){var u=!1;i>>n&1));var h=f.getMask(e,o,a-s);h&&(u=!u),this.modules[o][a-s]=u,n--,n==-1&&(i++,n=7)}if(o+=r,o<0||this.moduleCount<=o){o-=r,r=-r;break}}}},o.PAD0=236,o.PAD1=17,o.createData=function(t,e,r){for(var n=i.getRSBlocks(t,e),s=new a,u=0;u8*l)throw new Error("code length overflow. ("+s.getLengthInBits()+">"+8*l+")");for(s.getLengthInBits()+4<=8*l&&s.put(0,4);s.getLengthInBits()%8!=0;)s.putBit(!1);for(;;){if(s.getLengthInBits()>=8*l)break;if(s.put(o.PAD0,8),s.getLengthInBits()>=8*l)break;s.put(o.PAD1,8)}return o.createBytes(s,n)},o.createBytes=function(t,e){for(var r=0,o=0,i=0,a=new Array(e.length),s=new Array(e.length),u=0;u=0?v.get(m):0}}for(var p=0,g=0;g=0;)e^=f.G15<=0;)e^=f.G18<>>=1;return e},getPatternPosition:function(t){return f.PATTERN_POSITION_TABLE[t-1]},getMask:function(t,e,r){switch(t){case h.PATTERN000:return(e+r)%2==0;case h.PATTERN001:return e%2==0;case h.PATTERN010:return r%3==0;case h.PATTERN011:return(e+r)%3==0;case h.PATTERN100:return(Math.floor(e/2)+Math.floor(r/3))%2==0;case h.PATTERN101:return e*r%2+e*r%3==0;case h.PATTERN110:return(e*r%2+e*r%3)%2==0;case h.PATTERN111:return(e*r%3+(e+r)%2)%2==0;default:throw new Error("bad maskPattern:"+t)}},getErrorCorrectPolynomial:function(t){for(var e=new n([1],0),r=0;r5&&(r+=3+i-5)}for(var o=0;o=256;)t-=255;return l.EXP_TABLE[t]},EXP_TABLE:new Array(256),LOG_TABLE:new Array(256)},g=0;g<8;g++)l.EXP_TABLE[g]=1<>>7-t%8&1)},put:function(t,e){for(var r=0;r>>e-r-1&1))},getLengthInBits:function(){return this.length},putBit:function(t){var e=Math.floor(this.length/8);this.buffer.length<=e&&this.buffer.push(0),t&&(this.buffer[e]|=128>>>this.length%8),this.length++}},window.QRCode=o,window.QRErrorCorrectLevel=u;try{t.exports={QRCode:o,QRErrorCorrectLevel:u}}catch(t){}}])});
\ No newline at end of file
diff --git a/src/main/resources/static/webuploade/js/upload.js b/src/main/resources/static/webuploade/js/upload.js
index 8115ed6..1fa5240 100644
--- a/src/main/resources/static/webuploade/js/upload.js
+++ b/src/main/resources/static/webuploade/js/upload.js
@@ -231,7 +231,7 @@
//alert("文件上传失败")
layui.use('layer', function () {
layer = layui.layer;
- layer.msg("文件上传失败", {icon: 2});
+ layer.msg("文件上传失败,或许你的存储源配置不正确。", {icon: 2});
});
});
@@ -456,7 +456,7 @@
stats = uploader.getStats();
if ( stats.uploadFailNum ) {
text = '已成功上传' + stats.successNum+ '文件,'+
- stats.uploadFailNum + '文件上传失败,重新上传失败或忽略'
+ stats.uploadFailNum + '文件上传失败,重新上传失败或忽略'
}
} else {
diff --git a/src/main/resources/static/xcc/css/font-awesome.min.css b/src/main/resources/static/xcc/css/font-awesome.min.css
new file mode 100644
index 0000000..885b384
--- /dev/null
+++ b/src/main/resources/static/xcc/css/font-awesome.min.css
@@ -0,0 +1,4 @@
+/*!
+ * Font Awesome 4.6.1 by @davegandy - http://fontawesome.io - @fontawesome
+ * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License)
+ */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.6.1');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.6.1') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.6.1') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.6.1') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.6.1') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.6.1#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.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}
diff --git a/src/main/resources/static/xcc/css/ie8.css b/src/main/resources/static/xcc/css/ie8.css
new file mode 100644
index 0000000..57841a3
--- /dev/null
+++ b/src/main/resources/static/xcc/css/ie8.css
@@ -0,0 +1,47 @@
+/*
+ Multiverse by HTML5 UP
+ html5up.net | @n33co
+ Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
+*/
+
+/* Button */
+
+ input[type="submit"],
+ input[type="reset"],
+ input[type="button"],
+ button,
+ .button {
+ border: solid 2px #36383c;
+ }
+
+ input[type="submit"].special,
+ input[type="reset"].special,
+ input[type="button"].special,
+ button.special,
+ .button.special {
+ border: 0;
+ }
+
+/* Panel */
+
+ .panel {
+ background: #242629;
+ display: none;
+ }
+
+ .panel.active {
+ display: block;
+ }
+
+ .panel > .closer:before {
+ content: '\00d7';
+ font-size: 42px;
+ }
+
+/* Main */
+
+ #main .thumb > h2 {
+ text-align: center;
+ width: 100%;
+ left: 0;
+ }
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/css/ie9.css b/src/main/resources/static/xcc/css/ie9.css
new file mode 100644
index 0000000..2dc36d1
--- /dev/null
+++ b/src/main/resources/static/xcc/css/ie9.css
@@ -0,0 +1,41 @@
+/*
+ Multiverse by HTML5 UP
+ html5up.net | @n33co
+ Free for personal and commercial use under the CCA 3.0 license (html5up.net/license)
+*/
+
+/* Panel */
+
+ .panel > .inner.split:after {
+ clear: both;
+ content: '';
+ display: block;
+ }
+
+ .panel > .inner.split > div {
+ float: left;
+ margin-left: 0;
+ padding-left: 0;
+ }
+
+ .panel > .inner.split > :first-child {
+ padding-left: 0;
+ }
+
+/* Wrapper */
+
+ #wrapper:before {
+ display: none;
+ }
+
+/* Main */
+
+ #main:after {
+ clear: both;
+ content: '';
+ display: block;
+ }
+
+ #main .thumb {
+ float: left;
+ }
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/css/images/arrow.svg b/src/main/resources/static/xcc/css/images/arrow.svg
new file mode 100644
index 0000000..2945bb6
--- /dev/null
+++ b/src/main/resources/static/xcc/css/images/arrow.svg
@@ -0,0 +1,11 @@
+
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/css/images/close.svg b/src/main/resources/static/xcc/css/images/close.svg
new file mode 100644
index 0000000..e375a18
--- /dev/null
+++ b/src/main/resources/static/xcc/css/images/close.svg
@@ -0,0 +1,10 @@
+
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/css/images/spinner.svg b/src/main/resources/static/xcc/css/images/spinner.svg
new file mode 100644
index 0000000..de560f5
--- /dev/null
+++ b/src/main/resources/static/xcc/css/images/spinner.svg
@@ -0,0 +1,17 @@
+
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/css/main.css b/src/main/resources/static/xcc/css/main.css
new file mode 100644
index 0000000..787b526
--- /dev/null
+++ b/src/main/resources/static/xcc/css/main.css
@@ -0,0 +1,1987 @@
+@import url(font-awesome.min.css);
+@import url("http://fonts.googleapis.com/css?family=Source+Sans+Pro:300,300italic,400,400italic");
+
+
+/* Reset */
+
+ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ font-size: 100%;
+ font: inherit;
+ vertical-align: baseline;
+ }
+
+ article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section {
+ display: block;
+ }
+
+ body {
+ line-height: 1;
+ }
+
+ ol, ul {
+ list-style: none;
+ }
+
+ blockquote, q {
+ quotes: none;
+ }
+
+ blockquote:before, blockquote:after, q:before, q:after {
+ content: '';
+ content: none;
+ }
+
+ table {
+ border-collapse: collapse;
+ border-spacing: 0;
+ }
+
+ body {
+ -webkit-text-size-adjust: none;
+ }
+.copyrights{
+ text-indent:-9999px;
+ height:0;
+ line-height:0;
+ font-size:0;
+ overflow:hidden;
+}
+/* Box Model */
+
+ *, *:before, *:after {
+ -moz-box-sizing: border-box;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+
+ @-moz-keyframes spinner {
+ 0% {
+ -moz-transform: rotate(0deg);
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -moz-transform: rotate(359deg);
+ -webkit-transform: rotate(359deg);
+ -ms-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+ }
+
+ @-webkit-keyframes spinner {
+ 0% {
+ -moz-transform: rotate(0deg);
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -moz-transform: rotate(359deg);
+ -webkit-transform: rotate(359deg);
+ -ms-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+ }
+
+ @-ms-keyframes spinner {
+ 0% {
+ -moz-transform: rotate(0deg);
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -moz-transform: rotate(359deg);
+ -webkit-transform: rotate(359deg);
+ -ms-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+ }
+
+ @keyframes spinner {
+ 0% {
+ -moz-transform: rotate(0deg);
+ -webkit-transform: rotate(0deg);
+ -ms-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -moz-transform: rotate(359deg);
+ -webkit-transform: rotate(359deg);
+ -ms-transform: rotate(359deg);
+ transform: rotate(359deg);
+ }
+ }
+
+/* Basic */
+
+ @-ms-viewport {
+ width: device-width;
+ }
+
+ body {
+ -ms-overflow-style: scrollbar;
+ }
+
+ @media screen and (max-width: 480px) {
+
+ html, body {
+ min-width: 320px;
+ }
+
+ }
+
+ body {
+ background: #242629;
+ }
+
+ body.loading *, body.loading *:before, body.loading *:after {
+ -moz-animation: none !important;
+ -webkit-animation: none !important;
+ -ms-animation: none !important;
+ animation: none !important;
+ -moz-transition: none !important;
+ -webkit-transition: none !important;
+ -ms-transition: none !important;
+ transition: none !important;
+ }
+
+ body.resizing *, body.resizing *:before, body.resizing *:after {
+ -moz-animation: none !important;
+ -webkit-animation: none !important;
+ -ms-animation: none !important;
+ animation: none !important;
+ -moz-transition: none !important;
+ -webkit-transition: none !important;
+ -ms-transition: none !important;
+ transition: none !important;
+ }
+
+/* Type */
+
+ body, input, select, textarea {
+ color: #a0a0a1;
+ font-family: "Source Sans Pro", Helvetica, sans-serif;
+ font-size: 15pt;
+ font-weight: 300;
+ letter-spacing: 0.025em;
+ line-height: 1.65;
+ }
+
+ @media screen and (max-width: 1680px) {
+
+ body, input, select, textarea {
+ font-size: 11pt;
+ }
+
+ }
+
+ a {
+ -moz-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
+ -webkit-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
+ -ms-transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
+ transition: color 0.2s ease-in-out, border-bottom-color 0.2s ease-in-out;
+ border-bottom: dotted 1px;
+ color: #34a58e;
+ text-decoration: none;
+ }
+
+ a:hover {
+ border-bottom-color: transparent;
+ color: #34a58e !important;
+ }
+
+ strong, b {
+ color: #ffffff;
+ font-weight: 300;
+ }
+
+ em, i {
+ font-style: italic;
+ }
+
+ p {
+ margin: 0 0 2em 0;
+ }
+
+ h1, h2, h3, h4, h5, h6 {
+ color: #ffffff;
+ font-weight: 300;
+ letter-spacing: 0.1em;
+ line-height: 1.5;
+ margin: 0 0 1em 0;
+ text-transform: uppercase;
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a {
+ color: inherit;
+ text-decoration: none;
+ }
+
+ h1 {
+ font-size: 2em;
+ }
+
+ h2 {
+ font-size: 1.25em;
+ }
+
+ h3 {
+ font-size: 1.1em;
+ }
+
+ h4 {
+ font-size: 1em;
+ }
+
+ h5 {
+ font-size: 0.9em;
+ }
+
+ h6 {
+ font-size: 0.7em;
+ }
+
+ @media screen and (max-width: 736px) {
+
+ h2 {
+ font-size: 1em;
+ }
+
+ h3 {
+ font-size: 0.9em;
+ }
+
+ h4 {
+ font-size: 0.8em;
+ }
+
+ h5 {
+ font-size: 0.7em;
+ }
+
+ h6 {
+ font-size: 0.7em;
+ }
+
+ }
+
+ sub {
+ font-size: 0.8em;
+ position: relative;
+ top: 0.5em;
+ }
+
+ sup {
+ font-size: 0.8em;
+ position: relative;
+ top: -0.5em;
+ }
+
+ blockquote {
+ border-left: 4px #36383c;
+ font-style: italic;
+ margin: 0 0 2em 0;
+ padding: 0.5em 0 0.5em 2em;
+ }
+
+ code {
+ background: #34363b;
+ border: solid 1px #36383c;
+ font-family: "Courier New", monospace;
+ font-size: 0.9em;
+ margin: 0 0.25em;
+ padding: 0.25em 0.65em;
+ }
+
+ pre {
+ -webkit-overflow-scrolling: touch;
+ font-family: "Courier New", monospace;
+ font-size: 0.9em;
+ margin: 0 0 2em 0;
+ }
+
+ pre code {
+ display: block;
+ line-height: 1.75;
+ padding: 1em 1.5em;
+ overflow-x: auto;
+ }
+
+ hr {
+ border: 0;
+ border-bottom: solid 1px #36383c;
+ margin: 2em 0;
+ }
+
+ hr.major {
+ margin: 3em 0;
+ }
+
+ .align-left {
+ text-align: left;
+ }
+
+ .align-center {
+ text-align: center;
+ }
+
+ .align-right {
+ text-align: right;
+ }
+
+/* Button */
+
+ input[type="submit"],
+ input[type="reset"],
+ input[type="button"],
+ button,
+ .button {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ -ms-appearance: none;
+ appearance: none;
+ -moz-transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, color 0.2s ease-in-out;
+ -webkit-transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, color 0.2s ease-in-out;
+ -ms-transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, color 0.2s ease-in-out;
+ transition: background-color 0.2s ease-in-out, box-shadow 0.2s ease-in-out, color 0.2s ease-in-out;
+ background-color: transparent;
+ border: 0;
+ border-radius: 0;
+ box-shadow: inset 0 0 0 2px #36383c;
+ color: #ffffff !important;
+ cursor: pointer;
+ display: inline-block;
+ font-size: 0.9em;
+ font-weight: 300;
+ height: 3.05556em;
+ letter-spacing: 0.1em;
+ line-height: 3.05556em;
+ padding: 0 2.5em;
+ text-align: center;
+ text-decoration: none;
+ text-transform: uppercase;
+ white-space: nowrap;
+ }
+
+ input[type="submit"]:hover,
+ input[type="reset"]:hover,
+ input[type="button"]:hover,
+ button:hover,
+ .button:hover {
+ box-shadow: inset 0 0 0 2px #34a58e;
+ color: #34a58e !important;
+ }
+
+ input[type="submit"]:hover:active,
+ input[type="reset"]:hover:active,
+ input[type="button"]:hover:active,
+ button:hover:active,
+ .button:hover:active {
+ background-color: rgba(52, 165, 142, 0.15);
+ color: #34a58e !important;
+ }
+
+ input[type="submit"].icon,
+ input[type="reset"].icon,
+ input[type="button"].icon,
+ button.icon,
+ .button.icon {
+ padding-left: 1.35em;
+ }
+
+ input[type="submit"].icon:before,
+ input[type="reset"].icon:before,
+ input[type="button"].icon:before,
+ button.icon:before,
+ .button.icon:before {
+ margin-right: 0.5em;
+ }
+
+ input[type="submit"].fit,
+ input[type="reset"].fit,
+ input[type="button"].fit,
+ button.fit,
+ .button.fit {
+ display: block;
+ margin: 0 0 1em 0;
+ width: 100%;
+ }
+
+ input[type="submit"].small,
+ input[type="reset"].small,
+ input[type="button"].small,
+ button.small,
+ .button.small {
+ font-size: 0.8em;
+ }
+
+ input[type="submit"].big,
+ input[type="reset"].big,
+ input[type="button"].big,
+ button.big,
+ .button.big {
+ font-size: 1.35em;
+ }
+
+ input[type="submit"].special,
+ input[type="reset"].special,
+ input[type="button"].special,
+ button.special,
+ .button.special {
+ background-color: #34a58e;
+ box-shadow: none;
+ }
+
+ input[type="submit"].special:hover,
+ input[type="reset"].special:hover,
+ input[type="button"].special:hover,
+ button.special:hover,
+ .button.special:hover {
+ background-color: #47c5ab;
+ color: #ffffff !important;
+ }
+
+ input[type="submit"].special:hover:active,
+ input[type="reset"].special:hover:active,
+ input[type="button"].special:hover:active,
+ button.special:hover:active,
+ .button.special:hover:active {
+ background-color: #287e6d;
+ }
+
+ input[type="submit"].disabled, input[type="submit"]:disabled,
+ input[type="reset"].disabled,
+ input[type="reset"]:disabled,
+ input[type="button"].disabled,
+ input[type="button"]:disabled,
+ button.disabled,
+ button:disabled,
+ .button.disabled,
+ .button:disabled {
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ opacity: 0.35;
+ }
+
+/* Form */
+
+ form {
+ margin: 0 0 2em 0;
+ }
+
+ form .field {
+ margin: 0 0 1.3em 0;
+ }
+
+ form .field.half {
+ float: left;
+ padding: 0 0 0 0.65em;
+ width: 50%;
+ }
+
+ form .field.half.first {
+ padding: 0 0.65em 0 0;
+ }
+
+ form > .actions {
+ margin: 1.5em 0 0 0 !important;
+ }
+
+ @media screen and (max-width: 736px) {
+
+ form .field.half {
+ float: none;
+ padding: 0;
+ width: 100%;
+ }
+
+ form .field.half.first {
+ padding: 0;
+ }
+
+ }
+
+ label {
+ color: #ffffff;
+ display: block;
+ font-size: 0.9em;
+ font-weight: 300;
+ margin: 0 0 1em 0;
+ }
+
+ input[type="text"],
+ input[type="password"],
+ input[type="email"],
+ input[type="tel"],
+ select,
+ textarea {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ -ms-appearance: none;
+ appearance: none;
+ background: #34363b;
+ border: 0;
+ border-radius: 0;
+ color: #a0a0a1;
+ display: block;
+ outline: 0;
+ padding: 0 1em;
+ text-decoration: none;
+ width: 100%;
+ }
+
+ input[type="text"]:invalid,
+ input[type="password"]:invalid,
+ input[type="email"]:invalid,
+ input[type="tel"]:invalid,
+ select:invalid,
+ textarea:invalid {
+ box-shadow: none;
+ }
+
+ input[type="text"]:focus,
+ input[type="password"]:focus,
+ input[type="email"]:focus,
+ input[type="tel"]:focus,
+ select:focus,
+ textarea:focus {
+ box-shadow: inset 0 0 0 2px #34a58e;
+ }
+
+ .select-wrapper {
+ text-decoration: none;
+ display: block;
+ position: relative;
+ }
+
+ .select-wrapper:before {
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ text-transform: none !important;
+ }
+
+ .select-wrapper:before {
+ color: #36383c;
+ content: '\f078';
+ display: block;
+ height: 2.75em;
+ line-height: 2.75em;
+ pointer-events: none;
+ position: absolute;
+ right: 0;
+ text-align: center;
+ top: 0;
+ width: 2.75em;
+ }
+
+ .select-wrapper select::-ms-expand {
+ display: none;
+ }
+
+ input[type="text"],
+ input[type="password"],
+ input[type="email"],
+ select {
+ height: 2.75em;
+ }
+
+ textarea {
+ padding: 0.75em 1em;
+ }
+
+ input[type="checkbox"],
+ input[type="radio"] {
+ -moz-appearance: none;
+ -webkit-appearance: none;
+ -ms-appearance: none;
+ appearance: none;
+ display: block;
+ float: left;
+ margin-right: -2em;
+ opacity: 0;
+ width: 1em;
+ z-index: -1;
+ }
+
+ input[type="checkbox"] + label,
+ input[type="radio"] + label {
+ text-decoration: none;
+ color: #a0a0a1;
+ cursor: pointer;
+ display: inline-block;
+ font-size: 1em;
+ font-weight: 300;
+ padding-left: 2.4em;
+ padding-right: 0.75em;
+ position: relative;
+ }
+
+ input[type="checkbox"] + label:before,
+ input[type="radio"] + label:before {
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ text-transform: none !important;
+ }
+
+ input[type="checkbox"] + label:before,
+ input[type="radio"] + label:before {
+ background: #34363b;
+ content: '';
+ display: inline-block;
+ height: 1.65em;
+ left: 0;
+ line-height: 1.58125em;
+ position: absolute;
+ text-align: center;
+ top: 0;
+ width: 1.65em;
+ }
+
+ input[type="checkbox"]:checked + label:before,
+ input[type="radio"]:checked + label:before {
+ background: #34a58e;
+ border-color: #34a58e;
+ color: #ffffff;
+ content: '\f00c';
+ }
+
+ input[type="checkbox"]:focus + label:before,
+ input[type="radio"]:focus + label:before {
+ box-shadow: 0 0 0 2px #34a58e;
+ }
+
+ input[type="radio"] + label:before {
+ border-radius: 100%;
+ }
+
+ ::-webkit-input-placeholder {
+ color: #707071 !important;
+ opacity: 1.0;
+ }
+
+ :-moz-placeholder {
+ color: #707071 !important;
+ opacity: 1.0;
+ }
+
+ ::-moz-placeholder {
+ color: #707071 !important;
+ opacity: 1.0;
+ }
+
+ :-ms-input-placeholder {
+ color: #707071 !important;
+ opacity: 1.0;
+ }
+
+ .formerize-placeholder {
+ color: #707071 !important;
+ opacity: 1.0;
+ }
+
+/* Icon */
+
+ .icon {
+ text-decoration: none;
+ border-bottom: none;
+ position: relative;
+ }
+
+ .icon:before {
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ font-family: FontAwesome;
+ font-style: normal;
+ font-weight: normal;
+ text-transform: none !important;
+ }
+
+ .icon > .label {
+ display: none;
+ }
+
+/* List */
+
+ ol {
+ list-style: decimal;
+ margin: 0 0 2em 0;
+ padding-left: 1.25em;
+ }
+
+ ol li {
+ padding-left: 0.25em;
+ }
+
+ ul {
+ list-style: disc;
+ margin: 0 0 2em 0;
+ padding-left: 1em;
+ }
+
+ ul li {
+ padding-left: 0.5em;
+ }
+
+ ul.alt {
+ list-style: none;
+ padding-left: 0;
+ }
+
+ ul.alt li {
+ border-top: solid 1px #36383c;
+ padding: 0.5em 0;
+ }
+
+ ul.alt li:first-child {
+ border-top: 0;
+ padding-top: 0;
+ }
+
+ ul.icons {
+ cursor: default;
+ list-style: none;
+ padding-left: 0;
+ }
+
+ ul.icons li {
+ display: inline-block;
+ padding: 0 1em 0 0;
+ }
+
+ ul.icons li:last-child {
+ padding-right: 0;
+ }
+
+ ul.icons li .icon {
+ color: #505051;
+ }
+
+ ul.icons li .icon:before {
+ font-size: 1.5em;
+ }
+
+ ul.actions {
+ cursor: default;
+ list-style: none;
+ padding-left: 0;
+ }
+
+ ul.actions li {
+ display: inline-block;
+ padding: 0 1em 0 0;
+ vertical-align: middle;
+ }
+
+ ul.actions li:last-child {
+ padding-right: 0;
+ }
+
+ ul.actions.small li {
+ padding: 0 0.5em 0 0;
+ }
+
+ ul.actions.vertical li {
+ display: block;
+ padding: 1em 0 0 0;
+ }
+
+ ul.actions.vertical li:first-child {
+ padding-top: 0;
+ }
+
+ ul.actions.vertical li > * {
+ margin-bottom: 0;
+ }
+
+ ul.actions.vertical.small li {
+ padding: 0.5em 0 0 0;
+ }
+
+ ul.actions.vertical.small li:first-child {
+ padding-top: 0;
+ }
+
+ ul.actions.fit {
+ display: table;
+ margin-left: -1em;
+ padding: 0;
+ table-layout: fixed;
+ width: calc(100% + 1em);
+ }
+
+ ul.actions.fit li {
+ display: table-cell;
+ padding: 0 0 0 1em;
+ }
+
+ ul.actions.fit li > * {
+ margin-bottom: 0;
+ }
+
+ ul.actions.fit.small {
+ margin-left: -0.5em;
+ width: calc(100% + 0.5em);
+ }
+
+ ul.actions.fit.small li {
+ padding: 0 0 0 0.5em;
+ }
+
+ @media screen and (max-width: 480px) {
+
+ ul.actions {
+ margin: 0 0 2em 0;
+ }
+
+ ul.actions li {
+ padding: 1em 0 0 0;
+ display: block;
+ text-align: center;
+ width: 100%;
+ }
+
+ ul.actions li:first-child {
+ padding-top: 0;
+ }
+
+ ul.actions li > * {
+ width: 100%;
+ margin: 0 !important;
+ }
+
+ ul.actions li > *.icon:before {
+ margin-left: -2em;
+ }
+
+ ul.actions.small li {
+ padding: 0.5em 0 0 0;
+ }
+
+ ul.actions.small li:first-child {
+ padding-top: 0;
+ }
+
+ }
+
+ dl {
+ margin: 0 0 2em 0;
+ }
+
+ dl dt {
+ display: block;
+ font-weight: 300;
+ margin: 0 0 1em 0;
+ }
+
+ dl dd {
+ margin-left: 2em;
+ }
+
+/* Table */
+
+ .table-wrapper {
+ -webkit-overflow-scrolling: touch;
+ overflow-x: auto;
+ }
+
+ table {
+ margin: 0 0 2em 0;
+ width: 100%;
+ }
+
+ table tbody tr {
+ border: solid 1px #36383c;
+ border-left: 0;
+ border-right: 0;
+ }
+
+ table tbody tr:nth-child(2n + 1) {
+ background-color: #34363b;
+ }
+
+ table td {
+ padding: 0.75em 0.75em;
+ }
+
+ table th {
+ color: #ffffff;
+ font-size: 0.9em;
+ font-weight: 300;
+ padding: 0 0.75em 0.75em 0.75em;
+ text-align: left;
+ }
+
+ table thead {
+ border-bottom: solid 2px #36383c;
+ }
+
+ table tfoot {
+ border-top: solid 2px #36383c;
+ }
+
+ table.alt {
+ border-collapse: separate;
+ }
+
+ table.alt tbody tr td {
+ border: solid 1px #36383c;
+ border-left-width: 0;
+ border-top-width: 0;
+ }
+
+ table.alt tbody tr td:first-child {
+ border-left-width: 1px;
+ }
+
+ table.alt tbody tr:first-child td {
+ border-top-width: 1px;
+ }
+
+ table.alt thead {
+ border-bottom: 0;
+ }
+
+ table.alt tfoot {
+ border-top: 0;
+ }
+
+/* Panel */
+
+ .panel {
+ padding: 4em 4em 2em 4em ;
+ -moz-transform: translateY(100vh);
+ -webkit-transform: translateY(100vh);
+ -ms-transform: translateY(100vh);
+ transform: translateY(100vh);
+ -moz-transition: -moz-transform 0.5s ease;
+ -webkit-transition: -webkit-transform 0.5s ease;
+ -ms-transition: -ms-transform 0.5s ease;
+ transition: transform 0.5s ease;
+ -webkit-overflow-scrolling: touch;
+ background: rgba(36, 38, 41, 0.975);
+ bottom: 4em;
+ left: 0;
+ max-height: calc(80vh - 4em);
+ overflow-y: auto;
+ position: fixed;
+ width: 100%;
+ z-index: 10001;
+ }
+
+ .panel.active {
+ -moz-transform: translateY(1px);
+ -webkit-transform: translateY(1px);
+ -ms-transform: translateY(1px);
+ transform: translateY(1px);
+ }
+
+ .panel > .inner {
+ margin: 0 auto;
+ max-width: 100%;
+ width: 75em;
+ }
+
+ .panel > .inner.split {
+ display: -moz-flex;
+ display: -webkit-flex;
+ display: -ms-flex;
+ display: flex;
+ }
+
+ .panel > .inner.split > div {
+ margin-left: 4em;
+ width: 50%;
+ }
+
+ .panel > .inner.split > :first-child {
+ margin-left: 0;
+ }
+
+ .panel > .closer {
+ -moz-transition: opacity 0.2s ease-in-out;
+ -webkit-transition: opacity 0.2s ease-in-out;
+ -ms-transition: opacity 0.2s ease-in-out;
+ transition: opacity 0.2s ease-in-out;
+ background-image: url("images/close.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 3em;
+ cursor: pointer;
+ height: 5em;
+ opacity: 0.25;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 5em;
+ z-index: 2;
+ }
+
+ .panel > .closer:hover {
+ opacity: 1.0;
+ }
+
+ @media screen and (max-width: 1280px) {
+
+ .panel {
+ padding: 3em 3em 1em 3em ;
+ }
+
+ .panel > .inner.split > div {
+ margin-left: 3em;
+ }
+
+ .panel > .closer {
+ background-size: 2.5em;
+ background-position: 75% 25%;
+ }
+
+ }
+
+ @media screen and (max-width: 980px) {
+
+ .panel > .inner.split {
+ -moz-flex-direction: column;
+ -webkit-flex-direction: column;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ }
+
+ .panel > .inner.split > div {
+ margin-left: 0;
+ width: 100%;
+ }
+
+ }
+
+ @media screen and (max-width: 736px) {
+
+ .panel {
+ -moz-transform: translateY(-100vh);
+ -webkit-transform: translateY(-100vh);
+ -ms-transform: translateY(-100vh);
+ transform: translateY(-100vh);
+ padding: 4em 2em 2em 2em ;
+ bottom: auto;
+ top: calc(4em - 1px);
+ }
+
+ .panel.active {
+ -moz-transform: translateY(0);
+ -webkit-transform: translateY(0);
+ -ms-transform: translateY(0);
+ transform: translateY(0);
+ }
+
+ }
+
+/* Poptrox Popup */
+
+ .poptrox-overlay {
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+ }
+
+ .poptrox-popup {
+ background: rgba(31, 34, 36, 0.925);
+ box-shadow: 0 1em 3em 0.5em rgba(0, 0, 0, 0.25);
+ cursor: default;
+ }
+
+ .poptrox-popup:before {
+ -moz-transition: opacity 0.2s ease-in-out;
+ -webkit-transition: opacity 0.2s ease-in-out;
+ -ms-transition: opacity 0.2s ease-in-out;
+ transition: opacity 0.2s ease-in-out;
+ background-image: -moz-linear-gradient(to left, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0)), -moz-linear-gradient(to right, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0));
+ background-image: -webkit-linear-gradient(to left, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0)), -webkit-linear-gradient(to right, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0));
+ background-image: -ms-linear-gradient(to left, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0)), -ms-linear-gradient(to right, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0));
+ background-image: linear-gradient(to left, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0)), linear-gradient(to right, rgba(31,34,36,0.35), rgba(31,34,36,0) 10em, rgba(31,34,36,0));
+ content: '';
+ display: block;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ z-index: 1;
+ opacity: 1;
+ }
+
+ .poptrox-popup .closer {
+ -moz-transition: opacity 0.2s ease-in-out;
+ -webkit-transition: opacity 0.2s ease-in-out;
+ -ms-transition: opacity 0.2s ease-in-out;
+ transition: opacity 0.2s ease-in-out;
+ background-image: url("images/close.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 3em;
+ height: 5em;
+ opacity: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 5em;
+ z-index: 2;
+ }
+
+ .poptrox-popup .nav-previous,
+ .poptrox-popup .nav-next {
+ -moz-transition: opacity 0.2s ease-in-out;
+ -webkit-transition: opacity 0.2s ease-in-out;
+ -ms-transition: opacity 0.2s ease-in-out;
+ transition: opacity 0.2s ease-in-out;
+ background-image: url("images/arrow.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: 5em;
+ cursor: pointer;
+ height: 8em;
+ margin-top: -4em;
+ opacity: 0;
+ position: absolute;
+ top: 50%;
+ width: 6em;
+ z-index: 2;
+ }
+
+ .poptrox-popup .nav-previous {
+ -moz-transform: scaleX(-1);
+ -webkit-transform: scaleX(-1);
+ -ms-transform: scaleX(-1);
+ transform: scaleX(-1);
+ left: 0;
+ }
+
+ .poptrox-popup .nav-next {
+ right: 0;
+ }
+
+ .poptrox-popup .caption {
+ padding: 2em 2em 0.1em 2em ;
+ background-image: -moz-linear-gradient(to top, rgba(16,16,16,0.45) 25%, rgba(16,16,16,0) 100%);
+ background-image: -webkit-linear-gradient(to top, rgba(16,16,16,0.45) 25%, rgba(16,16,16,0) 100%);
+ background-image: -ms-linear-gradient(to top, rgba(16,16,16,0.45) 25%, rgba(16,16,16,0) 100%);
+ background-image: linear-gradient(to top, rgba(16,16,16,0.45) 25%, rgba(16,16,16,0) 100%);
+ bottom: 0;
+ cursor: default;
+ left: 0;
+ position: absolute;
+ text-align: left;
+ width: 100%;
+ z-index: 2;
+ }
+
+ .poptrox-popup .caption h2, .poptrox-popup .caption h3, .poptrox-popup .caption h4, .poptrox-popup .caption h5, .poptrox-popup .caption h6 {
+ margin: 0 0 0.5em 0;
+ }
+
+ .poptrox-popup .caption p {
+ color: #ffffff;
+ }
+
+ .poptrox-popup .loader {
+ -moz-animation: spinner 1s infinite linear !important;
+ -webkit-animation: spinner 1s infinite linear !important;
+ -ms-animation: spinner 1s infinite linear !important;
+ animation: spinner 1s infinite linear !important;
+ background-image: url("images/spinner.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ display: block;
+ font-size: 2em;
+ height: 2em;
+ left: 50%;
+ line-height: 2em;
+ margin: -1em 0 0 -1em;
+ opacity: 0.25;
+ position: absolute;
+ text-align: center;
+ top: 50%;
+ width: 2em;
+ }
+
+ .poptrox-popup:hover .closer,
+ .poptrox-popup:hover .nav-previous,
+ .poptrox-popup:hover .nav-next {
+ opacity: 0.5;
+ }
+
+ .poptrox-popup:hover .closer:hover,
+ .poptrox-popup:hover .nav-previous:hover,
+ .poptrox-popup:hover .nav-next:hover {
+ opacity: 1.0;
+ }
+
+ .poptrox-popup.loading:before {
+ opacity: 0;
+ }
+
+ body.touch .poptrox-popup .closer,
+ body.touch .poptrox-popup .nav-previous,
+ body.touch .poptrox-popup .nav-next {
+ opacity: 1.0 !important;
+ }
+
+ @media screen and (max-width: 980px) {
+
+ .poptrox-popup .closer {
+ background-size: 3em;
+ }
+
+ .poptrox-popup .nav-previous,
+ .poptrox-popup .nav-next {
+ background-size: 4em;
+ }
+
+ }
+
+ @media screen and (max-width: 736px) {
+
+ .poptrox-popup:before {
+ display: none;
+ }
+
+ .poptrox-popup .caption {
+ display: none !important;
+ }
+
+ .poptrox-popup .closer,
+ .poptrox-popup .nav-previous,
+ .poptrox-popup .nav-next {
+ display: none !important;
+ }
+
+ }
+
+/* Wrapper */
+
+ #wrapper {
+ -moz-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -moz-filter 0.5s ease;
+ -webkit-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -webkit-filter 0.5s ease;
+ -ms-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -ms-filter 0.5s ease;
+ transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, filter 0.5s ease;
+ position: relative;
+ }
+
+ #wrapper:after {
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ -moz-transition: opacity 0.5s ease, visibility 0.5s;
+ -webkit-transition: opacity 0.5s ease, visibility 0.5s;
+ -ms-transition: opacity 0.5s ease, visibility 0.5s;
+ transition: opacity 0.5s ease, visibility 0.5s;
+ background: rgba(36, 38, 41, 0.5);
+ content: '';
+ display: block;
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ visibility: hidden;
+ width: 100%;
+ z-index: 1;
+ }
+
+ body.ie #wrapper:after {
+ background: rgba(36, 38, 41, 0.8);
+ }
+
+ body.modal-active #wrapper {
+ -moz-filter: blur(8px);
+ -webkit-filter: blur(8px);
+ -ms-filter: blur(8px);
+ filter: blur(8px);
+ }
+
+ body.modal-active #wrapper:after {
+ -moz-pointer-events: auto;
+ -webkit-pointer-events: auto;
+ -ms-pointer-events: auto;
+ pointer-events: auto;
+ opacity: 1;
+ visibility: visible;
+ z-index: 10003;
+ }
+
+ #wrapper:before {
+ -moz-animation: spinner 1s infinite linear !important;
+ -webkit-animation: spinner 1s infinite linear !important;
+ -ms-animation: spinner 1s infinite linear !important;
+ animation: spinner 1s infinite linear !important;
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ -moz-transition: top 0.75s ease-in-out, opacity 0.35s ease-out, visibility 0.35s;
+ -webkit-transition: top 0.75s ease-in-out, opacity 0.35s ease-out, visibility 0.35s;
+ -ms-transition: top 0.75s ease-in-out, opacity 0.35s ease-out, visibility 0.35s;
+ transition: top 0.75s ease-in-out, opacity 0.35s ease-out, visibility 0.35s;
+ background-image: url("images/spinner.svg");
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: contain;
+ content: '';
+ display: block;
+ font-size: 2em;
+ height: 2em;
+ left: 50%;
+ line-height: 2em;
+ margin: -1em 0 0 -1em;
+ opacity: 0;
+ position: fixed;
+ text-align: center;
+ top: 75%;
+ visibility: hidden;
+ width: 2em;
+ }
+
+ body.loading #wrapper:before {
+ -moz-transition: opacity 1s ease-out !important;
+ -webkit-transition: opacity 1s ease-out !important;
+ -ms-transition: opacity 1s ease-out !important;
+ transition: opacity 1s ease-out !important;
+ -moz-transition-delay: 0.5s !important;
+ -webkit-transition-delay: 0.5s !important;
+ -ms-transition-delay: 0.5s !important;
+ transition-delay: 0.5s !important;
+ opacity: 0.25;
+ top: 50%;
+ visibility: visible;
+ }
+
+/* Header */
+
+ body {
+ padding: 0 0 4em 0;
+ }
+
+ #header {
+ -moz-transform: translateY(0);
+ -webkit-transform: translateY(0);
+ -ms-transform: translateY(0);
+ transform: translateY(0);
+ -moz-transition: -moz-transform 1s ease;
+ -webkit-transition: -webkit-transform 1s ease;
+ -ms-transition: -ms-transform 1s ease;
+ transition: transform 1s ease;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ -webkit-user-select: none;
+ background: #1f2224;
+ bottom: -1em;
+ height: 5em;
+ left: 0;
+ line-height: 4em;
+ padding: 0 1.5em;
+ position: fixed;
+ user-select: none;
+ width: 100%;
+ z-index: 10002;
+ }
+
+ body.loading #header {
+ -moz-transform: translateY(4em);
+ -webkit-transform: translateY(4em);
+ -ms-transform: translateY(4em);
+ transform: translateY(4em);
+ }
+
+ #header h1 {
+ color: #a0a0a1;
+ display: inline-block;
+ font-size: 1em;
+ line-height: 1;
+ margin: 0;
+ vertical-align: middle;
+ }
+
+ #header h1 a {
+ border: 0;
+ color: inherit;
+ }
+
+ #header h1 a:hover {
+ color: inherit !important;
+ }
+
+ #header nav {
+ position: absolute;
+ right: 0;
+ top: 0;
+ }
+
+ #header nav > ul {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+ }
+
+ #header nav > ul > li {
+ display: inline-block;
+ padding: 0;
+ }
+
+ #header nav > ul > li a {
+ -moz-transition: background-color 0.5s ease;
+ -webkit-transition: background-color 0.5s ease;
+ -ms-transition: background-color 0.5s ease;
+ transition: background-color 0.5s ease;
+ border: 0;
+ color: #ffffff;
+ display: inline-block;
+ letter-spacing: 0.1em;
+ padding: 0 1.65em;
+ text-transform: uppercase;
+ }
+
+ #header nav > ul > li a.icon:before {
+ color: #505051;
+ float: right;
+ margin-left: 0.75em;
+ }
+
+ #header nav > ul > li a:hover {
+ color: #ffffff !important;
+ }
+
+ #header nav > ul > li a.active {
+ background-color: #242629;
+ }
+
+ @media screen and (max-width: 736px) {
+
+ body {
+ padding: 4em 0 0 0;
+ }
+
+ #header {
+ -moz-transform: translateY(0);
+ -webkit-transform: translateY(0);
+ -ms-transform: translateY(0);
+ transform: translateY(0);
+ bottom: auto;
+ height: 4em;
+ padding: 0 1em;
+ top: 0;
+ }
+
+ body.loading #header {
+ -moz-transform: translateY(-3.4em);
+ -webkit-transform: translateY(-3.4em);
+ -ms-transform: translateY(-3.4em);
+ transform: translateY(-3.4em);
+ }
+
+ #header h1 {
+ font-size: 0.9em;
+ }
+
+ #header nav > ul > li a {
+ font-size: 0.9em;
+ padding: 0 1.15em;
+ }
+
+ }
+
+/* Main */
+
+ #main {
+ -moz-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -moz-filter 0.5s ease;
+ -webkit-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -webkit-filter 0.5s ease;
+ -ms-transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, -ms-filter 0.5s ease;
+ transition: -moz-filter 0.5s ease, -webkit-filter 0.5s ease, -ms-filter 0.5s ease, filter 0.5s ease;
+ display: -moz-flex;
+ display: -webkit-flex;
+ display: -ms-flex;
+ display: flex;
+ -moz-flex-wrap: wrap;
+ -webkit-flex-wrap: wrap;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+ }
+
+ #main .thumb {
+ -moz-transition: opacity 1.25s ease-in-out;
+ -webkit-transition: opacity 1.25s ease-in-out;
+ -ms-transition: opacity 1.25s ease-in-out;
+ transition: opacity 1.25s ease-in-out;
+ -moz-pointer-events: auto;
+ -webkit-pointer-events: auto;
+ -ms-pointer-events: auto;
+ pointer-events: auto;
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+ opacity: 1;
+ overflow: hidden;
+ position: relative;
+ }
+
+ #main .thumb:after {
+ background-image: -moz-linear-gradient(to top, rgba(10,17,25,0.35) 5%, rgba(10,17,25,0) 35%);
+ background-image: -webkit-linear-gradient(to top, rgba(10,17,25,0.35) 5%, rgba(10,17,25,0) 35%);
+ background-image: -ms-linear-gradient(to top, rgba(10,17,25,0.35) 5%, rgba(10,17,25,0) 35%);
+ background-image: linear-gradient(to top, rgba(10,17,25,0.35) 5%, rgba(10,17,25,0) 35%);
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ background-size: cover;
+ content: '';
+ display: block;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ #main .thumb > .image {
+ -webkit-tap-highlight-color: rgba(255, 255, 255, 0);
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ border: 0;
+ height: 100%;
+ left: 0;
+ position: absolute;
+ top: 0;
+ width: 100%;
+ }
+
+ #main .thumb > h2 {
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ bottom: 1.875em;
+ font-size: 0.8em;
+ left: 2.1875em;
+ margin: 0;
+ position: absolute;
+ z-index: 1;
+ }
+
+ #main .thumb > p {
+ display: none;
+ }
+
+ #main:after {
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ -moz-transition: opacity 0.5s ease, visibility 0.5s;
+ -webkit-transition: opacity 0.5s ease, visibility 0.5s;
+ -ms-transition: opacity 0.5s ease, visibility 0.5s;
+ transition: opacity 0.5s ease, visibility 0.5s;
+ background: rgba(36, 38, 41, 0.25);
+ content: '';
+ display: block;
+ height: 100%;
+ left: 0;
+ opacity: 0;
+ position: absolute;
+ top: 0;
+ visibility: hidden;
+ width: 100%;
+ z-index: 1;
+ }
+
+ body.ie #main:after {
+ background: rgba(36, 38, 41, 0.55);
+ }
+
+ body.content-active #main {
+ -moz-filter: blur(6px);
+ -webkit-filter: blur(6px);
+ -ms-filter: blur(6px);
+ filter: blur(6px);
+ }
+
+ body.content-active #main:after {
+ -moz-pointer-events: auto;
+ -webkit-pointer-events: auto;
+ -ms-pointer-events: auto;
+ pointer-events: auto;
+ opacity: 1;
+ visibility: visible;
+ }
+
+ body.loading #main .thumb {
+ -moz-pointer-events: none;
+ -webkit-pointer-events: none;
+ -ms-pointer-events: none;
+ pointer-events: none;
+ opacity: 0;
+ }
+
+ #main .thumb {
+ -moz-transition-delay: 2.525s;
+ -webkit-transition-delay: 2.525s;
+ -ms-transition-delay: 2.525s;
+ transition-delay: 2.525s;
+ height: calc(40vh - 2em);
+ min-height: 20em;
+ width: 25%;
+ }
+
+ #main .thumb:nth-child(1) {
+ -moz-transition-delay: 0.65s;
+ -webkit-transition-delay: 0.65s;
+ -ms-transition-delay: 0.65s;
+ transition-delay: 0.65s;
+ }
+
+ #main .thumb:nth-child(2) {
+ -moz-transition-delay: 0.8s;
+ -webkit-transition-delay: 0.8s;
+ -ms-transition-delay: 0.8s;
+ transition-delay: 0.8s;
+ }
+
+ #main .thumb:nth-child(3) {
+ -moz-transition-delay: 0.95s;
+ -webkit-transition-delay: 0.95s;
+ -ms-transition-delay: 0.95s;
+ transition-delay: 0.95s;
+ }
+
+ #main .thumb:nth-child(4) {
+ -moz-transition-delay: 1.1s;
+ -webkit-transition-delay: 1.1s;
+ -ms-transition-delay: 1.1s;
+ transition-delay: 1.1s;
+ }
+
+ #main .thumb:nth-child(5) {
+ -moz-transition-delay: 1.25s;
+ -webkit-transition-delay: 1.25s;
+ -ms-transition-delay: 1.25s;
+ transition-delay: 1.25s;
+ }
+
+ #main .thumb:nth-child(6) {
+ -moz-transition-delay: 1.4s;
+ -webkit-transition-delay: 1.4s;
+ -ms-transition-delay: 1.4s;
+ transition-delay: 1.4s;
+ }
+
+ #main .thumb:nth-child(7) {
+ -moz-transition-delay: 1.55s;
+ -webkit-transition-delay: 1.55s;
+ -ms-transition-delay: 1.55s;
+ transition-delay: 1.55s;
+ }
+
+ #main .thumb:nth-child(8) {
+ -moz-transition-delay: 1.7s;
+ -webkit-transition-delay: 1.7s;
+ -ms-transition-delay: 1.7s;
+ transition-delay: 1.7s;
+ }
+
+ #main .thumb:nth-child(9) {
+ -moz-transition-delay: 1.85s;
+ -webkit-transition-delay: 1.85s;
+ -ms-transition-delay: 1.85s;
+ transition-delay: 1.85s;
+ }
+
+ #main .thumb:nth-child(10) {
+ -moz-transition-delay: 2s;
+ -webkit-transition-delay: 2s;
+ -ms-transition-delay: 2s;
+ transition-delay: 2s;
+ }
+
+ #main .thumb:nth-child(11) {
+ -moz-transition-delay: 2.15s;
+ -webkit-transition-delay: 2.15s;
+ -ms-transition-delay: 2.15s;
+ transition-delay: 2.15s;
+ }
+
+ #main .thumb:nth-child(12) {
+ -moz-transition-delay: 2.3s;
+ -webkit-transition-delay: 2.3s;
+ -ms-transition-delay: 2.3s;
+ transition-delay: 2.3s;
+ }
+
+ @media screen and (max-width: 1680px) {
+
+ #main .thumb {
+ -moz-transition-delay: 2.075s;
+ -webkit-transition-delay: 2.075s;
+ -ms-transition-delay: 2.075s;
+ transition-delay: 2.075s;
+ height: calc(40vh - 2em);
+ min-height: 20em;
+ width: 33.33333%;
+ }
+
+ #main .thumb:nth-child(1) {
+ -moz-transition-delay: 0.65s;
+ -webkit-transition-delay: 0.65s;
+ -ms-transition-delay: 0.65s;
+ transition-delay: 0.65s;
+ }
+
+ #main .thumb:nth-child(2) {
+ -moz-transition-delay: 0.8s;
+ -webkit-transition-delay: 0.8s;
+ -ms-transition-delay: 0.8s;
+ transition-delay: 0.8s;
+ }
+
+ #main .thumb:nth-child(3) {
+ -moz-transition-delay: 0.95s;
+ -webkit-transition-delay: 0.95s;
+ -ms-transition-delay: 0.95s;
+ transition-delay: 0.95s;
+ }
+
+ #main .thumb:nth-child(4) {
+ -moz-transition-delay: 1.1s;
+ -webkit-transition-delay: 1.1s;
+ -ms-transition-delay: 1.1s;
+ transition-delay: 1.1s;
+ }
+
+ #main .thumb:nth-child(5) {
+ -moz-transition-delay: 1.25s;
+ -webkit-transition-delay: 1.25s;
+ -ms-transition-delay: 1.25s;
+ transition-delay: 1.25s;
+ }
+
+ #main .thumb:nth-child(6) {
+ -moz-transition-delay: 1.4s;
+ -webkit-transition-delay: 1.4s;
+ -ms-transition-delay: 1.4s;
+ transition-delay: 1.4s;
+ }
+
+ #main .thumb:nth-child(7) {
+ -moz-transition-delay: 1.55s;
+ -webkit-transition-delay: 1.55s;
+ -ms-transition-delay: 1.55s;
+ transition-delay: 1.55s;
+ }
+
+ #main .thumb:nth-child(8) {
+ -moz-transition-delay: 1.7s;
+ -webkit-transition-delay: 1.7s;
+ -ms-transition-delay: 1.7s;
+ transition-delay: 1.7s;
+ }
+
+ #main .thumb:nth-child(9) {
+ -moz-transition-delay: 1.85s;
+ -webkit-transition-delay: 1.85s;
+ -ms-transition-delay: 1.85s;
+ transition-delay: 1.85s;
+ }
+
+ }
+
+ @media screen and (max-width: 1280px) {
+
+ #main .thumb {
+ -moz-transition-delay: 1.625s;
+ -webkit-transition-delay: 1.625s;
+ -ms-transition-delay: 1.625s;
+ transition-delay: 1.625s;
+ height: calc(40vh - 2em);
+ min-height: 20em;
+ width: 50%;
+ }
+
+ #main .thumb:nth-child(1) {
+ -moz-transition-delay: 0.65s;
+ -webkit-transition-delay: 0.65s;
+ -ms-transition-delay: 0.65s;
+ transition-delay: 0.65s;
+ }
+
+ #main .thumb:nth-child(2) {
+ -moz-transition-delay: 0.8s;
+ -webkit-transition-delay: 0.8s;
+ -ms-transition-delay: 0.8s;
+ transition-delay: 0.8s;
+ }
+
+ #main .thumb:nth-child(3) {
+ -moz-transition-delay: 0.95s;
+ -webkit-transition-delay: 0.95s;
+ -ms-transition-delay: 0.95s;
+ transition-delay: 0.95s;
+ }
+
+ #main .thumb:nth-child(4) {
+ -moz-transition-delay: 1.1s;
+ -webkit-transition-delay: 1.1s;
+ -ms-transition-delay: 1.1s;
+ transition-delay: 1.1s;
+ }
+
+ #main .thumb:nth-child(5) {
+ -moz-transition-delay: 1.25s;
+ -webkit-transition-delay: 1.25s;
+ -ms-transition-delay: 1.25s;
+ transition-delay: 1.25s;
+ }
+
+ #main .thumb:nth-child(6) {
+ -moz-transition-delay: 1.4s;
+ -webkit-transition-delay: 1.4s;
+ -ms-transition-delay: 1.4s;
+ transition-delay: 1.4s;
+ }
+
+ }
+
+ @media screen and (max-width: 980px) {
+
+ #main .thumb {
+ -moz-transition-delay: 2.075s;
+ -webkit-transition-delay: 2.075s;
+ -ms-transition-delay: 2.075s;
+ transition-delay: 2.075s;
+ height: calc(28.57143vh - 1.33333em);
+ min-height: 18em;
+ width: 50%;
+ }
+
+ #main .thumb:nth-child(1) {
+ -moz-transition-delay: 0.65s;
+ -webkit-transition-delay: 0.65s;
+ -ms-transition-delay: 0.65s;
+ transition-delay: 0.65s;
+ }
+
+ #main .thumb:nth-child(2) {
+ -moz-transition-delay: 0.8s;
+ -webkit-transition-delay: 0.8s;
+ -ms-transition-delay: 0.8s;
+ transition-delay: 0.8s;
+ }
+
+ #main .thumb:nth-child(3) {
+ -moz-transition-delay: 0.95s;
+ -webkit-transition-delay: 0.95s;
+ -ms-transition-delay: 0.95s;
+ transition-delay: 0.95s;
+ }
+
+ #main .thumb:nth-child(4) {
+ -moz-transition-delay: 1.1s;
+ -webkit-transition-delay: 1.1s;
+ -ms-transition-delay: 1.1s;
+ transition-delay: 1.1s;
+ }
+
+ #main .thumb:nth-child(5) {
+ -moz-transition-delay: 1.25s;
+ -webkit-transition-delay: 1.25s;
+ -ms-transition-delay: 1.25s;
+ transition-delay: 1.25s;
+ }
+
+ #main .thumb:nth-child(6) {
+ -moz-transition-delay: 1.4s;
+ -webkit-transition-delay: 1.4s;
+ -ms-transition-delay: 1.4s;
+ transition-delay: 1.4s;
+ }
+
+ #main .thumb:nth-child(7) {
+ -moz-transition-delay: 1.55s;
+ -webkit-transition-delay: 1.55s;
+ -ms-transition-delay: 1.55s;
+ transition-delay: 1.55s;
+ }
+
+ #main .thumb:nth-child(8) {
+ -moz-transition-delay: 1.7s;
+ -webkit-transition-delay: 1.7s;
+ -ms-transition-delay: 1.7s;
+ transition-delay: 1.7s;
+ }
+
+ #main .thumb:nth-child(9) {
+ -moz-transition-delay: 1.85s;
+ -webkit-transition-delay: 1.85s;
+ -ms-transition-delay: 1.85s;
+ transition-delay: 1.85s;
+ }
+
+ }
+
+ @media screen and (max-width: 480px) {
+
+ #main .thumb {
+ -moz-transition-delay: 1.175s;
+ -webkit-transition-delay: 1.175s;
+ -ms-transition-delay: 1.175s;
+ transition-delay: 1.175s;
+ height: calc(40vh - 2em);
+ min-height: 18em;
+ width: 100%;
+ }
+
+ #main .thumb:nth-child(1) {
+ -moz-transition-delay: 0.65s;
+ -webkit-transition-delay: 0.65s;
+ -ms-transition-delay: 0.65s;
+ transition-delay: 0.65s;
+ }
+
+ #main .thumb:nth-child(2) {
+ -moz-transition-delay: 0.8s;
+ -webkit-transition-delay: 0.8s;
+ -ms-transition-delay: 0.8s;
+ transition-delay: 0.8s;
+ }
+
+ #main .thumb:nth-child(3) {
+ -moz-transition-delay: 0.95s;
+ -webkit-transition-delay: 0.95s;
+ -ms-transition-delay: 0.95s;
+ transition-delay: 0.95s;
+ }
+
+ }
+
+/* Footer */
+
+ #footer .copyright {
+ color: #505051;
+ font-size: 0.9em;
+ }
+
+ #footer .copyright a {
+ color: inherit;
+ }
\ No newline at end of file
diff --git a/src/main/resources/static/xcc/fonts/FontAwesome.otf b/src/main/resources/static/xcc/fonts/FontAwesome.otf
new file mode 100644
index 0000000000000000000000000000000000000000..59853bcda7308254f58c2d74053f3ba55c21b9fb
GIT binary patch
literal 123112
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