+ 旅行便携类 海外TOP 10
+commit cc434cf89f1a4a39d395387c73e114b955831acf Author: liangjiami <2249412933@qq.com> Date: Wed Oct 14 14:00:29 2026 +0800 init: 项目初始代码 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..0b13344 --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +/.idea +/.vscode +/vendor +*.log +.env +/runtime +public/storage/* +public/gitea_webhook.php +public/.user.ini +public/ueditor +*.rar +*.zip +.DS_Store +*.sh +/public/attachmenet/resources/ +.DS_Store +public/.DS_Store +public/GeoLite2-City.mmdb +public/GeoLite2-Country.mmdb +public/admin +public/.well-known +pd.sh +pm.sh \ No newline at end of file diff --git a/.htaccess b/.htaccess new file mode 100644 index 0000000..0519ecb --- /dev/null +++ b/.htaccess @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..36f7b6f --- /dev/null +++ b/.travis.yml @@ -0,0 +1,42 @@ +sudo: false + +language: php + +branches: + only: + - stable + +cache: + directories: + - $HOME/.composer/cache + +before_install: + - composer self-update + +install: + - composer install --no-dev --no-interaction --ignore-platform-reqs + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip . + - composer require --update-no-dev --no-interaction "topthink/think-image:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-migration:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-captcha:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-mongo:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-worker:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-helper:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-queue:^1.0" + - composer require --update-no-dev --no-interaction "topthink/think-angular:^1.0" + - composer require --dev --update-no-dev --no-interaction "topthink/think-testing:^1.0" + - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip . + +script: + - php think unit + +deploy: + provider: releases + api_key: + secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw= + file: + - ThinkPHP_Core.zip + - ThinkPHP_Full.zip + skip_cleanup: true + on: + tags: true diff --git a/404.html b/404.html new file mode 100644 index 0000000..6f17eaf --- /dev/null +++ b/404.html @@ -0,0 +1,7 @@ + +
=="; print_r($list);
+ //去除自己的顶级
+ if (isset($inputData['id']) && $inputData['id'] != '') {
+ //查找当前分类是否有子类。
+ $nav = $this->model->find($inputData['id']);
+ $hasSon = $this->model->where('pid',$inputData['id'])->find();
+
+ if($hasSon) {
+ $tree = [];
+ }
+ else{
+ foreach ($list as $key => $item) {
+ if ($inputData['id'] == $item['id']){
+ unset($list[$key]);
+ break;
+ }
+ }
+ $tree = list_to_tree($list);
+ }
+
+ /*if ($nav) {
+ if (!empty($son)) {
+ $tree = [];
+ } else {
+ foreach ($list as $key => $item) {
+ if ($inputData['id'] == $item['id']){
+ unset($list[$key]);
+ }
+ }
+ $tree = list_to_tree($list);
+ }
+ }*/
+ } else {
+ /*foreach ($list as $key => $item) {
+ if ($inputData['id'] == $item['id']){
+ unset($list[$key]);
+ }
+ }*/
+
+ $tree = list_to_tree($list);
+
+ }
+ //echo "---"; print_r($tree);
+ return $this->msg(200, '获取列表成功', $tree);
+ }
+
+ /**
+ * 修改是否是顶部状态
+ */
+ public function changeStatus():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $inputData['site_id'] = $inputData['language_id'];
+ }
+ if (isset($inputData['language_id'])) {
+ unset($inputData['language_id']);
+ }
+ if (isset($inputData['is_foot']) && $inputData['is_foot'] == '') {
+ unset($inputData['is_foot']);
+ }
+
+ if (isset($inputData['is_top']) && $inputData['is_top'] == '') {
+ unset($inputData['is_top']);
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //不能都提交为空
+ if (count($inputData) < 3) {
+ return $this->msg(504,"参数错误");
+ }
+
+ $result = $this->model->changeStatus($inputData);
+ if ($result) {
+ return $this->msg(200,"操作成功");
+ } else {
+ return $this->msg(504,"操作失败");
+ }
+ }
+
+ /**
+ * 删除
+ */
+ public function del():\think\Response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //查找是否有子类。
+ $hasData = $this->model->getNavigatorIsInUse($inputData);
+ if (!$hasData) {
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ } else {
+ return $this->msg(504,"该导航下有子分类,不能删除");
+ }
+ }
+}
diff --git a/app/api/controller/v1/News.php b/app/api/controller/v1/News.php
new file mode 100644
index 0000000..af2102c
--- /dev/null
+++ b/app/api/controller/v1/News.php
@@ -0,0 +1,135 @@
+validate = new NewsValidate();
+ $this->model = new NewsModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (isset($inputData['News_type_id']) && $inputData['News_type_id'] != '' && $inputData['News_type_id'] != 0) {
+ $this->focus['News_type_id'] = $inputData['News_type_id'];
+ }
+
+ if (isset($inputData['title']) && $inputData['title'] != '') {
+ $this->simple['title'] = $inputData['title'];
+ }
+
+ $this->order['create_time'] = 'desc';
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 新增
+ */
+ public function create():\think\Response\Json
+ {
+ $detail = $this->request->param('detail','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['detail'] = $detail;
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['create_time']) && $inputData['create_time'] != '') {
+ $inputData['create_time'] = intval($inputData['create_time']) / 1000;
+ } else {
+ unset($inputData['create_time']);
+ }
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->addData($inputData);
+
+ if ($result) {
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\Response\Json
+ {
+ $detail = $this->request->param('detail','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['detail'] = $detail;
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['create_time']) && $inputData['create_time'] != '') {
+ $inputData['create_time'] = intval($inputData['create_time']) / 1000;
+ } else {
+ unset($inputData['create_time']);
+ }
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->editData($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * 启用禁用
+ */
+ public function changeStatus():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->changeStatus($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+}
diff --git a/app/api/controller/v1/NewsType.php b/app/api/controller/v1/NewsType.php
new file mode 100644
index 0000000..e88a41a
--- /dev/null
+++ b/app/api/controller/v1/NewsType.php
@@ -0,0 +1,131 @@
+validate = new NewsTypeValidate();
+ $this->model = new NewsTypeModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ //兼容新方式
+ if (isset($inputData['sort']) && $inputData['sort'] != '') {
+ $this->orderby['sort'] = $inputData['sort'];
+ } else {
+ $this->orderby['sort'] = 'asc';
+ }
+
+ $this->field = ['id','platform_id','site_id','icon','name','sort'];
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->orderby,$this->field);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 更新
+ */
+ public function update():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $updateData = $insertData = [];
+ if (count($inputData['data']) > 0) {
+ foreach ($inputData['data'] as &$item) {
+ if (isset($item['id']) && $item['id'] != '') {
+ if (!$this->commonValidate(__FUNCTION__,$item)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $updateData[] =[
+ 'id' => $item['id'],
+ 'site_id' => $item['language_id'],
+ 'name' => $item['name'],
+ 'icon' => $item['icon']??'',
+ 'sort' => $item['sort'],
+ 'platform_id'=>$this->platformId
+ ];
+ } else {
+ if (!$this->commonValidate('create',$item)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $insertData[] = [
+ 'id' => null,
+ 'name' => $item['name'],
+ 'icon' => $item['icon']??'',
+ 'site_id' => $item['language_id'],
+ 'sort' => $item['sort'],
+ 'platform_id'=>$this->platformId
+ ];
+ }
+ }
+ }
+
+ if (!empty($updateData)) {
+ $result = $this->model->batchEditData($updateData);
+ } else {
+ $result = true;
+ }
+ if (!empty($insertData)) {
+ $result1 = $this->model->saveAll($insertData);
+ } else {
+ $result1 = true;
+ }
+
+ if ($result && $result1) {
+ return $this->msg(200,'更新成功');
+ } else {
+ return $this->msg(504,'更新失败');
+ }
+ }
+
+
+ /**
+ * 删除
+ */
+ public function del():\think\Response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //查找是否有子类。
+ $hasData = $this->model->getArticleData($inputData);
+ if (empty($hasData)) {
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ } else {
+ return $this->msg(504,"该类型下有内容,不能删除");
+ }
+ }
+}
diff --git a/app/api/controller/v1/Platform.php b/app/api/controller/v1/Platform.php
new file mode 100644
index 0000000..c0f0c29
--- /dev/null
+++ b/app/api/controller/v1/Platform.php
@@ -0,0 +1,133 @@
+validate = new PlatformValidate();
+ $this->model = new PlatformModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 语言列表
+ */
+ public function languageList():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $this->field = ['id','name','code','icon','status'];
+ $result = $this->model->getLanguageList($this->field,['status'=>0]);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+
+ /**
+ * 新增
+ */
+ public function create():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->addData($inputData);
+ if ($result) {
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ // 已经注册的平台,如果被使用,则不允许修改品牌名
+ //TODO::暂时限制不能更改品牌名称
+ $isExist = $this->model->hasUserPlatform($inputData);
+ if (count($isExist) >= 1) {
+ unset($inputData['name']);
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->editData($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * 详情
+ */
+ public function read():\think\response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->getInfo($inputData);
+ if ($result) {
+ return $this->msg(200,'获取列表成功',$result);
+ } else {
+ return $this->msg(504,'获取列表失败');
+ }
+ }
+
+
+ /**
+ * 删除
+ */
+ public function del():\think\response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //删除前检测
+ $isExist = $this->model->hasUserPlatform($inputData);
+ if (count($isExist) >= 1) {
+ return $this->msg(504,"平台被使用,不能删除");
+ }
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ }
+
+}
diff --git a/app/api/controller/v1/Question.php b/app/api/controller/v1/Question.php
new file mode 100644
index 0000000..d29d10f
--- /dev/null
+++ b/app/api/controller/v1/Question.php
@@ -0,0 +1,549 @@
+validate = new QuestionValidate();
+ $this->model = new QuestionModel();
+ }
+
+ /**
+ * 列表
+ * @return \think\response\Json
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ if (isset($inputData['is_done']) && $inputData['is_done'] != '') {
+ $this->focus['is_done'] = $inputData['is_done'];
+ }
+
+ if (isset($inputData['product_model']) && $inputData['product_model'] != '') {
+ $this->simple['product_model'] = $inputData['product_model'];
+ }
+
+ if (isset($inputData['create_time']) && $inputData['create_time'] != '') {
+ $this->orderby['create_time'] = $inputData['create_time'];
+ }
+
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ if (!empty($this->focus)) {
+ if (!$this->commonValidate(__FUNCTION__,$this->focus)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ }
+
+ if (!empty($this->simple)) {
+ if (!$this->commonValidate(__FUNCTION__,$this->simple)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ }
+
+ if (!empty($this->orderby)) {
+ if (!$this->commonValidate(__FUNCTION__,$this->orderby)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ }
+ //字段过滤
+ $this->field = ['id','platform_id','language_id','site_id','country_id','name','phone','email','order_sn','product_model','os','sort','is_done','create_time'];
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->orderby,$this->field);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 已解决
+ */
+ public function isDone()
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->isDone($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * Excel导出,
+ * @param array $data
+ * @param string $fileName
+ * @param array $options
+ * @return bool
+ */
+ public function export($data = [], $fileName = '', $options = [])
+ {
+ try {
+ if (empty($data)) {
+ return false;
+ }
+
+ set_time_limit(0);
+ $objSpreadsheet = new Spreadsheet();
+ /* 设置默认文字居左,上下居中 */
+ $styleArray = [
+ 'alignment' => [
+ 'horizontal' => Alignment::HORIZONTAL_LEFT,
+ 'vertical' => Alignment::VERTICAL_CENTER,
+ ],
+ ];
+ $objSpreadsheet->getDefaultStyle()->applyFromArray($styleArray);
+ /* 设置Excel Sheet */
+ $activeSheet = $objSpreadsheet->setActiveSheetIndex(0);
+
+ /* 打印设置 */
+ if (isset($options['print']) && $options['print']) {
+ /* 设置打印为A4效果 */
+ $activeSheet->getPageSetup()->setPaperSize(PageSetup:: PAPERSIZE_A4);
+ /* 设置打印时边距 */
+ $pValue = 1 / 2.54;
+ $activeSheet->getPageMargins()->setTop($pValue / 2);
+ $activeSheet->getPageMargins()->setBottom($pValue * 2);
+ $activeSheet->getPageMargins()->setLeft($pValue / 2);
+ $activeSheet->getPageMargins()->setRight($pValue / 2);
+ }
+
+ $row = 2;
+ $col = 0;
+ /* 行数据处理 */
+ foreach ($data as $sKey => $sItem) {
+ /* 默认文本格式 */
+ $pDataType = DataType::TYPE_STRING;
+
+ /* 设置单元格格式 */
+ if (isset($options['format']) && !empty($options['format'])) {
+ $colRow = Coordinate::coordinateFromString($sKey);
+
+ /* 存在该列格式并且有特殊格式 */
+ if (isset($options['format'][$colRow[0]]) &&
+ NumberFormat::FORMAT_GENERAL != $options['format'][$colRow[0]]) {
+ $activeSheet->getStyle($sKey)->getNumberFormat()
+ ->setFormatCode($options['format'][$colRow[0]]);
+
+ if (false !== strpos($options['format'][$colRow[0]], '0.00') &&
+ is_numeric(str_replace(['¥', ','], '', $sItem))) {
+ /* 数字格式转换为数字单元格 */
+ $pDataType = DataType::TYPE_NUMERIC;
+ $sItem = str_replace(['¥', ','], '', $sItem);
+ }
+ } elseif (is_int($sItem)) {
+ $pDataType = DataType::TYPE_NUMERIC;
+ }
+ }
+
+ if ($col < count($options['alignCenter'])) {
+ $activeSheet->getColumnDimension($options['alignCenter'][$col])->setAutoSize(true);
+ }
+ $activeSheet->getRowDimension($row)->setRowHeight(65);
+ $activeSheet->setCellValueExplicit($sKey, $sItem, $pDataType);
+ $row++;
+ $col++;
+ /* 存在:形式的合并行列,列入A1:B2,则对应合并 */
+ if (false !== strstr($sKey, ":")) {
+ $options['mergeCells'][$sKey] = $sKey;
+ }
+
+ if (is_image(Env::get('root_path').'public'.$sItem) && file_exists(Env::get('root_path').'public'.$sItem)) {
+ $activeSheet->setCellValueExplicit($sKey, '', $pDataType);
+ $drawing = new Drawing();
+ $drawing->setName('Logo');
+ $drawing->setDescription('Logo');
+ $drawing->setPath(Env::get('root_path').'public'.$sItem);
+ $drawing->setResizeProportional(false);
+ $drawing->setHeight(50);
+ $drawing->setCoordinates($sKey);
+ $drawing->setOffsetX(12);
+ $drawing->setOffsetY(12);
+ $drawing->getShadow()->setVisible(true);
+// $drawing->getShadow()->setDirection(45);
+ $drawing->setWorksheet($objSpreadsheet->getActiveSheet());
+ }
+ }
+
+ unset($data);
+
+ /* 设置锁定行 */
+ if (isset($options['freezePane']) && !empty($options['freezePane'])) {
+ $activeSheet->freezePane($options['freezePane']);
+ unset($options['freezePane']);
+ }
+
+ /* 设置宽度 */
+ if (isset($options['setWidth']) && !empty($options['setWidth'])) {
+ foreach ($options['setWidth'] as $swKey => $swItem) {
+ $activeSheet->getColumnDimension($swKey)->setWidth($swItem);
+ }
+
+ unset($options['setWidth']);
+ }
+
+ /* 设置背景色 */
+ if (isset($options['setARGB']) && !empty($options['setARGB'])) {
+ foreach ($options['setARGB'] as $sItem) {
+ $activeSheet->getStyle($sItem)
+ ->getFill()->setFillType(Fill::FILL_SOLID)
+ ->getStartColor()->setARGB(Color::COLOR_YELLOW);
+ }
+
+ unset($options['setARGB']);
+ }
+
+ /* 设置公式 */
+ if (isset($options['formula']) && !empty($options['formula'])) {
+ foreach ($options['formula'] as $fKey => $fItem) {
+ $activeSheet->setCellValue($fKey, $fItem);
+ }
+
+ unset($options['formula']);
+ }
+
+ /* 合并行列处理 */
+ if (isset($options['mergeCells']) && !empty($options['mergeCells'])) {
+ $activeSheet->setMergeCells($options['mergeCells']);
+ unset($options['mergeCells']);
+ }
+
+ /* 设置居中 */
+ if (isset($options['alignCenter']) && !empty($options['alignCenter'])) {
+ $styleArray = [
+ 'alignment' => [
+ 'horizontal' => Alignment::HORIZONTAL_CENTER,
+ 'vertical' => Alignment::VERTICAL_CENTER,
+ ],
+ ];
+
+ foreach ($options['alignCenter'] as $acItem) {
+ $activeSheet->getStyle($acItem)->applyFromArray($styleArray);
+ }
+
+ unset($options['alignCenter']);
+ }
+
+ /* 设置加粗 */
+ if (isset($options['bold']) && !empty($options['bold'])) {
+ foreach ($options['bold'] as $bItem) {
+ $activeSheet->getStyle($bItem)->getFont()->setBold(true);
+ }
+
+ unset($options['bold']);
+ }
+
+ /* 设置单元格边框,整个表格设置即可,必须在数据填充后才可以获取到最大行列 */
+ if (isset($options['setBorder']) && $options['setBorder']) {
+ $border = [
+ 'borders' => [
+ 'allBorders' => [
+ 'borderStyle' => Border::BORDER_THIN, // 设置border样式
+ 'color' => ['argb' => 'FF000000'], // 设置border颜色
+ ],
+ ],
+ ];
+ $setBorder = 'A1:' . $activeSheet->getHighestColumn() . $activeSheet->getHighestRow();
+ $activeSheet->getStyle($setBorder)->applyFromArray($border);
+ unset($options['setBorder']);
+ }
+
+ $fileName = !empty($fileName) ? $fileName : (date('YmdHis') . '.xlsx');
+
+ if (!isset($options['savePath'])) {
+ /* 直接导出Excel,无需保存到本地,输出07Excel文件 */
+ header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
+ header(
+ "Content-Disposition:attachment;filename=" . iconv(
+ "utf-8", "GB2312//TRANSLIT", $fileName
+ )
+ );
+ header('Cache-Control: max-age=0');//禁止缓存
+ $savePath = 'php://output';
+ } else {
+ $savePath = $options['savePath'];
+ }
+
+ ob_clean();
+ ob_start();
+ $objWriter = IOFactory::createWriter($objSpreadsheet, 'Xlsx');
+ $objWriter->save($savePath);
+ /* 释放内存 */
+ $objSpreadsheet->disconnectWorksheets();
+ unset($objSpreadsheet);
+ ob_end_flush();
+
+ return true;
+ } catch (\Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * 导入
+ */
+ public function import()
+ {
+ $file = $this->request->request('file');
+ if (!$file) {
+ return $this->msg(504,'Parameter %s can not be empty');
+ }
+ $filePath = Env::get('root_path') . '/public/' . $file;
+ if (!is_file($filePath)) {
+ return $this->msg(504,'No results were found');
+ }
+ //实例化reader
+ $ext = pathinfo($filePath, PATHINFO_EXTENSION);
+ if (!in_array($ext, ['csv', 'xls', 'xlsx'])) {
+ return $this->msg(504,'Unknown data format');
+ }
+ if ($ext === 'csv') {
+ $file = fopen($filePath, 'r');
+ $filePath = tempnam(sys_get_temp_dir(), 'import_csv');
+ $fp = fopen($filePath, "w");
+ $n = 0;
+ while ($line = fgets($file)) {
+ $line = rtrim($line, "\n\r\0");
+ $encoding = mb_detect_encoding($line, ['utf-8', 'gbk', 'latin1', 'big5']);
+ if ($encoding != 'utf-8') {
+ $line = mb_convert_encoding($line, 'utf-8', $encoding);
+ }
+ if ($n == 0 || preg_match('/^".*"$/', $line)) {
+ fwrite($fp, $line . "\n");
+ } else {
+ fwrite($fp, '"' . str_replace(['"', ','], ['""', '","'], $line) . "\"\n");
+ }
+ $n++;
+ }
+ fclose($file) || fclose($fp);
+
+ $reader = new Csv();
+ } elseif ($ext === 'xls') {
+ $reader = new Xls();
+ } else {
+ $reader = new Xlsx();
+ }
+
+ //导入文件首行类型,默认是注释,如果需要使用字段名称请使用name
+ $importHeadType = isset($this->importHeadType) ? $this->importHeadType : 'comment';
+
+ $table = $this->model->getQuery()->getTable();
+ $database = Config::get('database.database');
+ $fieldArr = [];
+ $list = db()->query("SELECT COLUMN_NAME,COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = ? AND TABLE_SCHEMA = ?", [$table, $database]);
+ foreach ($list as $k => $v) {
+ if ($importHeadType == 'comment') {
+ $fieldArr[$v['COLUMN_COMMENT']] = $v['COLUMN_NAME'];
+ } else {
+ $fieldArr[$v['COLUMN_NAME']] = $v['COLUMN_NAME'];
+ }
+ }
+
+ //加载文件
+ $insert = [];
+ try {
+ if (!$PHPExcel = $reader->load($filePath)) {
+ return $this->msg(504,'Unknown data format');
+ }
+ $currentSheet = $PHPExcel->getSheet(0); //读取文件中的第一个工作表
+ $allColumn = $currentSheet->getHighestDataColumn(); //取得最大的列号
+ $allRow = $currentSheet->getHighestRow(); //取得一共有多少行
+ $maxColumnNumber = Coordinate::columnIndexFromString($allColumn);
+ $fields = [];
+ for ($currentRow = 1; $currentRow <= 1; $currentRow++) {
+ for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
+ $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
+ $fields[] = $val;
+ }
+ }
+
+ for ($currentRow = 2; $currentRow <= $allRow; $currentRow++) {
+ $values = [];
+ for ($currentColumn = 1; $currentColumn <= $maxColumnNumber; $currentColumn++) {
+ $val = $currentSheet->getCellByColumnAndRow($currentColumn, $currentRow)->getValue();
+ $values[] = is_null($val) ? '' : $val;
+ }
+ $row = [];
+ $temp = array_combine($fields, $values);
+ foreach ($temp as $k => $v) {
+ if (isset($fieldArr[$k]) && $k !== '') {
+ $row[$fieldArr[$k]] = $v;
+ }
+ }
+ if ($row) {
+ $insert[] = $row;
+ }
+ }
+ } catch (Exception $exception) {
+ return $this->msg(504,$exception->getMessage());
+ }
+ if (!$insert) {
+ return $this->msg(504,'No rows were updated');
+ }
+
+ try {
+ //是否包含admin_id字段
+ $has_admin_id = false;
+ foreach ($fieldArr as $name => $key) {
+ if ($key == 'admin_id') {
+ $has_admin_id = true;
+ break;
+ }
+ }
+ if ($has_admin_id) {
+ $auth = Auth::instance();
+ foreach ($insert as &$val) {
+ if (!isset($val['admin_id']) || empty($val['admin_id'])) {
+ $val['admin_id'] = $auth->isLogin() ? $auth->id : 0;
+ }
+ }
+ }
+ $this->model->saveAll($insert);
+ } catch (PDOException $exception) {
+ $msg = $exception->getMessage();
+ if (preg_match("/.+Integrity constraint violation: 1062 Duplicate entry '(.+)' for key '(.+)'/is", $msg, $matches)) {
+ $msg = "导入失败,包含【{$matches[1]}】的记录已存在";
+ };
+ return $this->msg(504,$msg);
+ } catch (\Exception $e) {
+ return $this->msg(504,$e->getMessage());
+ }
+
+ return $this->msg(200,'导入成功!!');
+ }
+
+// /**
+// * 发送邮件
+// */
+// public function sendEmail()
+// {
+// $translate = [
+// 'language_id' => '所属站点',
+// 'country_id' => '国家/地区',
+// 'name' => '客户名称',
+// 'email' => '客户邮箱',
+// 'order_sn' => '订单号',
+// 'product_model' => '产品型号',
+// 'os' => '操作系统',
+// 'desc' => '问题详情',
+// 'question_attachment' => '反馈附件',
+// 'create_time' => '反馈时间'
+// ];
+//
+// $data = $this->request->param();
+// $data['create_time'] = date('Y-m-d H:i:s',time());
+// $mail = new PHPMailer();
+// $mail->CharSet = "UTF8";
+// $mail->SMTPDebug = 0; //Enable verbose debug output
+// $mail->isSMTP(); //Send using SMTP
+// $mail->Host = Env::get('EMAIL.MAIL_HOST'); //Set the SMTP server to send through
+// $mail->SMTPAuth = true; //Enable SMTP authentication
+// $mail->Username = Env::get('EMAIL.MAIL_USERNAME'); //SMTP username
+// $mail->Password = Env::get('EMAIL.MAIL_PASSWORD'); //SMTP password
+// $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS; //Enable TLS encryption; `PHPMailer::ENCRYPTION_SMTPS` encouraged
+// $mail->Port = Env::get('EMAIL.MAIL_PORT'); //TCP port to connect to, use 465 for `PHPMailer::ENCRYPTION_SMTPS` above
+//
+// //Recipients
+// $mail->setFrom(Env::get('EMAIL.MAIL_FROM_ADDRESS'), Env::get('EMAIL.MAIL_FROM_ADDRESS'));
+// $mail->addAddress('yulinzhihou@163.com', 'yulinzhihou'); //Add a recipient
+//
+// //Content
+// $mail->isHTML(true); //Set email format to HTML
+// $mail->Subject = '尤达官网用户问题反馈'.$data['name'].date('Y-m-d H:i:s');
+// $body = '';
+// $body .= <<
+// table,tr,td,th {
+// border: 1px solid #ccc;
+// border-collapse: collapse;
+// text-align: justify;
+// }
+// .item1 {
+// width: 20%;
+// }
+//
+//
+//EOF;
+// foreach ($data as $key => $value) {
+// if (is_array($value)) {
+// foreach ($value as $item) {
+// $body .= ''.$translate[$key].' '.'点击查看附件 ';
+// }
+// } else {
+// $body .= ''.$translate[$key].' '.''.$value.' ';
+// }
+// }
+// $body .= '
';
+// $mail->Body = $body;
+// $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
+// $result = $mail->send();
+// dd($result);
+//
+// }
+//
+//
+// public function validateEmail()
+// {
+// $inputData = $this->request->param();
+// $validator = new EmailValidator();
+// $multipleValidations = new MultipleValidationWithAnd([
+// new RFCValidation(),
+// new DNSCheckValidation()
+// ]);
+// //ietf.org has MX records signaling a server with email capabilites
+// $result = $validator->isValid($inputData['email'], $multipleValidations); //true
+// if ($result) {
+// return $this->msg(200,'邮箱有效');
+// } else {
+// return $this->msg(504,'邮箱无效');
+// }
+// }
+}
diff --git a/app/api/controller/v1/Resource.php b/app/api/controller/v1/Resource.php
new file mode 100644
index 0000000..12f764a
--- /dev/null
+++ b/app/api/controller/v1/Resource.php
@@ -0,0 +1,135 @@
+validate = new ResourceValidate();
+ $this->model = new ResourceModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (isset($inputData['resource_type_id']) && $inputData['resource_type_id'] != '' && $inputData['resource_type_id'] != 0) {
+ $this->focus['resource_type_id'] = $inputData['resource_type_id'];
+ }
+
+ if (isset($inputData['title']) && $inputData['title'] != '') {
+ $this->simple['title'] = $inputData['title'];
+ }
+
+ $this->order['create_time'] = 'desc';
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 新增
+ */
+ public function create():\think\Response\Json
+ {
+ $detail = $this->request->param('detail','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['detail'] = $detail;
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['create_time']) && !$inputData['create_time']) {
+ $inputData['create_time'] = intval($inputData['create_time']) / 1000;
+ } else {
+ unset($inputData['create_time']);
+ }
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->addData($inputData);
+
+ if ($result) {
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\Response\Json
+ {
+ $detail = $this->request->param('detail','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['detail'] = $detail;
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['create_time'])) {
+ $inputData['create_time'] = intval($inputData['create_time']) / 1000;
+ } else {
+ unset($inputData['create_time']);
+ }
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->editData($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * 启用禁用
+ */
+ public function changeStatus():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->changeStatus($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+}
diff --git a/app/api/controller/v1/ResourceType.php b/app/api/controller/v1/ResourceType.php
new file mode 100644
index 0000000..b1a261c
--- /dev/null
+++ b/app/api/controller/v1/ResourceType.php
@@ -0,0 +1,131 @@
+validate = new ResourceTypeValidate();
+ $this->model = new ResourceTypeModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ //兼容新方式
+ if (isset($inputData['sort']) && $inputData['sort'] != '') {
+ $this->orderby['sort'] = $inputData['sort'];
+ } else {
+ $this->orderby['sort'] = 'asc';
+ }
+
+ $this->field = ['id','platform_id','site_id','icon','name','sort'];
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->orderby,$this->field);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 更新
+ */
+ public function update():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $updateData = $insertData = [];
+ if (count($inputData['data']) > 0) {
+ foreach ($inputData['data'] as &$item) {
+ if (isset($item['id']) && $item['id'] != '') {
+ if (!$this->commonValidate(__FUNCTION__,$item)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $updateData[] =[
+ 'id' => $item['id'],
+ 'site_id' => $item['language_id'],
+ 'name' => $item['name'],
+ 'icon' => $item['icon']??'',
+ 'sort' => $item['sort'],
+ 'platform_id'=>$this->platformId
+ ];
+ } else {
+ if (!$this->commonValidate('create',$item)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $insertData[] = [
+ 'id' => null,
+ 'name' => $item['name'],
+ 'icon' => $item['icon']??'',
+ 'site_id' => $item['language_id'],
+ 'sort' => $item['sort'],
+ 'platform_id'=>$this->platformId
+ ];
+ }
+ }
+ }
+
+ if (!empty($updateData)) {
+ $result = $this->model->batchEditData($updateData);
+ } else {
+ $result = true;
+ }
+ if (!empty($insertData)) {
+ $result1 = $this->model->saveAll($insertData);
+ } else {
+ $result1 = true;
+ }
+
+ if ($result && $result1) {
+ return $this->msg(200,'更新成功');
+ } else {
+ return $this->msg(504,'更新失败');
+ }
+ }
+
+
+ /**
+ * 删除
+ */
+ public function del():\think\Response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //查找是否有子类。
+ $hasData = $this->model->getArticleData($inputData);
+ if (empty($hasData)) {
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ } else {
+ return $this->msg(504,"该类型下有内容,不能删除");
+ }
+ }
+}
diff --git a/app/api/controller/v1/Role.php b/app/api/controller/v1/Role.php
new file mode 100644
index 0000000..b47f59a
--- /dev/null
+++ b/app/api/controller/v1/Role.php
@@ -0,0 +1,21 @@
+model = new RoleModel();
+ $this->validate = new RoleValidate();
+ }
+}
diff --git a/app/api/controller/v1/Site.php b/app/api/controller/v1/Site.php
new file mode 100644
index 0000000..cbd6c02
--- /dev/null
+++ b/app/api/controller/v1/Site.php
@@ -0,0 +1,175 @@
+validate = new SiteValidate();
+ $this->model = new SiteModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+
+ /**
+ * 列表接口
+ */
+ public function siteIndex():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $this->focus['status'] = 0;
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ $data = [];
+ foreach ($result as $item) {
+ $data[] = [
+ 'id' => $item['id'],
+ 'name' => $item['language_name'],
+ 'currency_name' => $this->model->getCoinName($item['currency_id'])
+ ];
+ }
+ return $this->msg(200,'获取列表成功',$data);
+ }
+
+ /**
+ * 详情
+ */
+ public function read():\think\response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->getInfo($inputData);
+
+ if ($result) {
+ return $this->msg(200,'获取列表成功',$result);
+ } else {
+ return $this->msg(504,'获取列表失败');
+ }
+ }
+
+ /**
+ * 新增
+ */
+ public function create():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ //语言包
+ if (isset($inputData['language_id']) || !empty($inputData['language_id']) || $inputData['language_id'] != 0) {
+ $this->focus['language_id'] = $inputData['language_id'];
+ } else {
+ return $this->msg(504,'语言包ID不正确,请检查!');
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //验证站点是否已经添加过
+ $isExits = $this->model->getSiteData($inputData);
+ if (count($isExits) >= 1) {
+ return $this->msg(504,'一个品牌只能添加一个相同语言的站点。');
+ }
+ //增加站点加密算法 语言ID+站点域名,
+ $inputData['app_id'] = md5($inputData['language_id'].$inputData['domain']);
+ $inputData['app_key'] = md5($inputData['app_id']);
+
+ $result = $this->model->addData($inputData);
+
+ if ($result) {
+ Cache::set($inputData['app_id'],$inputData['app_key']);
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\response\Json
+ {
+ $inputData = $this->request->param();
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //验证站点是否已经添加过
+ $isExits = $this->model->getSiteData($inputData);
+
+ if (count($isExits) >= 1 && !in_array($inputData['id'],$isExits)) {
+ return $this->msg(504,'一个品牌只能添加一个相同语言的站点。');
+ }
+ //增加站点加密算法 语言ID+站点域名,
+ $inputData['app_id'] = md5($inputData['language_id'].$inputData['domain']);
+ $inputData['app_key'] = md5($inputData['app_id']);
+ $result = $this->model->editData($inputData);
+ if ($result) {
+ Cache::set($inputData['app_id'],$inputData['app_key']);
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * 获取导航数据
+ */
+ public function getNavigatorList():\think\response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ $this->commonValidate(__FUNCTION__,$inputData);
+ $result = $this->model->getNav($inputData);
+
+ if ($result) {
+ return $this->msg(200,'获取列表成功',$result);
+ } else {
+ return $this->msg(504,'获取列表失败');
+ }
+ }
+
+ /**
+ * 删除
+ */
+ public function del():\think\response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ }
+
+}
diff --git a/app/api/controller/v1/SoftManual.php b/app/api/controller/v1/SoftManual.php
new file mode 100644
index 0000000..98a3428
--- /dev/null
+++ b/app/api/controller/v1/SoftManual.php
@@ -0,0 +1,236 @@
+validate = new SoftManualValidate();
+ $this->model = new SoftManualModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (isset($inputData['file_type_id']) && $inputData['file_type_id'] != '' && $inputData['file_type_id'] != 0) {
+ $this->focus['file_type_id'] = $inputData['file_type_id'];
+ }
+
+ if (isset($inputData['name']) && $inputData['name'] != '') {
+ $this->simple['name'] = $inputData['name'];
+ }
+
+ $this->order['create_time'] = 'desc';
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->getAllList($inputData,$this->simple,$this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 新增
+ */
+ public function create():\think\Response\Json
+ {
+ $introduce = $this->request->param('introduce','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['introduce'] = $introduce;
+ $inputData['platform_id'] = $this->platformId;
+ unset($inputData['create_time']);
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ //验证是否提交按钮参数与链接
+ if (isset($inputData['softBtn']) && empty($inputData['softBtn'])) {
+ $this->msg(504,'还没有填写按钮信息,请检查!');
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ $result = $this->model->addData($inputData);
+
+ if ($result) {
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\Response\Json
+ {
+ $introduce = $this->request->param('introduce','','htmlspecialchars');
+ $inputData = $this->request->param();
+ $inputData['introduce'] = $introduce;
+ $inputData['platform_id'] = $this->platformId;
+ unset($inputData['create_time']);
+ unset($inputData['update_time']);
+
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //验证是否提交按钮参数与链接
+ if (empty($inputData['softBtn'])) {
+ return $this->msg(504,'还没有填写按钮信息,请检查!');
+ }
+
+ $result = $this->model->editData($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+ /**
+ * 更改排序
+ */
+ public function changeSort():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->changeSort($inputData);
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+
+ /**
+ * 图片,ICON上传
+ */
+ public function upload():\think\Response\Json
+ {
+ $files = $this->request->file();
+ if (!$files) {
+ return $this->msg(-1, "请选择上传的文件");
+ }
+ $field = array_keys($files)[0];
+ $data = [];
+ //兼容多图上传
+ if (is_array($files) && count($files) > 1 ) {
+ //不同字段文件名上传 image img ico
+ //上传到七牛
+ foreach ($files as $key => $fileSimple) {
+// if (!$this->commonValidate(__FUNCTION__, [$key => $fileSimple])) {
+// return $this->msg(200, $this->validate->getError());
+// }
+ $result[$key] = $this->qn->uploadFile($key);
+ }
+
+ foreach ($result as $key => $item) {
+ $data[] = [
+ 'cdn' => Env::get('QINIU.cdn'),
+ 'origin_name' => $files[$key]->getOriginalName(),
+ 'filename' => explode('/', $item['filename'])[count(explode('/', $item['filename'])) - 1],
+ 'md5' => md5_file($files[$key]->getPathname()),
+ 'url' => $item['remote_url'],
+ 'relative_path' => $item['filename']
+ ];
+ }
+ } elseif (is_array($files[$field]) && count($files[$field]) > 1) {
+ //同一名称的数组文件上传.image[0] image[1]
+// foreach ($files as $key => $fileSimple) {
+// if (!$this->commonValidate(__FUNCTION__, [$key => $fileSimple])) {
+// return $this->msg(200, $this->validate->getError());
+// }
+// }
+ //上传到七牛
+ $result = $this->qn->uploadFile($field, true, count($files[$field]));
+
+ foreach ($result as $key => $item) {
+ $data[] = [
+ 'cdn' => Env::get('QINIU.cdn'),
+ 'origin_name' => $files[$field][$key]->getOriginalName(),
+ 'filename' => explode('/', $item['filename'])[count(explode('/', $item['filename'])) - 1],
+ 'md5' => md5_file($files[$field][$key]->getPathname()),
+ 'url' => $item['remote_url'],
+ 'relative_path' => $item['filename']
+ ];
+ }
+ } else {
+// if (!$this->commonValidate(__FUNCTION__,[$field=>$files])) {
+// return $this->msg(200,$this->validate->getError());
+// }
+ //上传到七牛
+ $result = $this->qn->uploadFile($field);
+ $data = [
+ 'cdn' => Env::get('QINIU.cdn'),
+ 'origin_name' => $files[$field]->getOriginalName(),
+ 'filename' => explode('/',$result['filename'])[count(explode('/',$result['filename']))-1],
+ 'md5' => md5_file($files[$field]->getPathname()),
+ 'url' => $result['remote_url'],
+ 'relative_path' => $result['filename']
+ ];
+ }
+
+ return $this->msg(200, '上传成功', $data);
+ }
+
+ /**
+ * 删除
+ */
+ public function del():\think\Response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ //查询是否有被使用
+ $hasUsed = $this->model->getSoftManualUsed($inputData);
+ if ($hasUsed) {
+ return $this->msg(504,'已被使用,不能删除!');
+ }
+ $result = $this->model->delData($inputData);
+ if ($result) {
+ return $this->msg(200,"删除成功");
+ } else {
+ return $this->msg(504,"删除失败");
+ }
+ }
+
+
+
+}
diff --git a/app/api/controller/v1/SystemConfig.php b/app/api/controller/v1/SystemConfig.php
new file mode 100644
index 0000000..5908f62
--- /dev/null
+++ b/app/api/controller/v1/SystemConfig.php
@@ -0,0 +1,145 @@
+model = new SystemConfigModel();
+ $this->validate = new SystemConfigValidate();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->getIndexList($this->page,$this->size,$this->field, $this->simple, $this->focus,$this->order);
+ if (isset($result['data']) && !empty($result['data'])) {
+ foreach ($result['data'] as $key => $item) {
+ if (!empty($item['image'])) {
+ $result['data'][$key]['image'] = json_decode($item['image'],true);
+ }
+ }
+ }
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+ /**
+ * 详情
+ */
+ public function read():\think\Response\Json
+ {
+ $inputData = $this->request->param(['id']);
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->getInfo($inputData);
+ if ($result['type'] == 2 || $result['type'] == 4) {
+ // 处理图片
+ if (isset($result['image']) && !empty($result['image'])) {
+ $result['image'] = json_decode($result['image'],true);
+ } else {
+ $result['image'] = [];
+ }
+ }
+
+ if ($result) {
+ $result['language_id'] = $result['site_id'];
+ return $this->msg(200,'获取列表成功',$result);
+ } else {
+ return $this->msg(200,'获取列表成功',[]);
+ }
+ }
+
+ /**
+ * 新增
+ */
+ public function create():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ //语言包
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ if (isset($inputData['site_id']) || !empty($inputData['site_id']) || $inputData['site_id'] != 0) {
+ $this->focus['site_id'] = $inputData['site_id'];
+ } else {
+ return $this->msg(504,'语言包/所属站点参数,不正确,请检查!');
+ }
+
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ // 处理图片
+ if (isset($inputData['image']) && !empty($inputData['image'])) {
+ $inputData['image'] = json_encode($inputData['image']);
+ }
+
+ $result = $this->model->addData($inputData);
+
+ if ($result) {
+ return $this->msg(200,'新增成功');
+ } else {
+ return $this->msg(504,'新增失败');
+ }
+ }
+
+ /**
+ * 修改
+ */
+ public function update():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+
+ $inputData['platform_id'] = $this->platformId;
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+
+ // 处理图片
+ if (isset($inputData['image']) && !empty($inputData['image'])) {
+ $inputData['image'] = json_encode($inputData['image']);
+ }
+
+ $result = $this->model->editData($inputData);
+
+ if ($result) {
+ return $this->msg(200,'更改成功');
+ } else {
+ return $this->msg(504,'更改失败');
+ }
+ }
+
+
+
+}
diff --git a/app/api/controller/v1/Video.php b/app/api/controller/v1/Video.php
new file mode 100644
index 0000000..c9e6283
--- /dev/null
+++ b/app/api/controller/v1/Video.php
@@ -0,0 +1,66 @@
+validate = new VideoValidate();
+ $this->model = new VideoModel();
+ }
+
+ /**
+ * 列表
+ */
+ public function index():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ $inputData['platform_id'] = $this->platformId;
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $this->simple['name'] = $inputData['name'] ?? '';
+ $result = $this->model->getIndexList($this->page,$this->size,$this->field, $this->simple, $this->focus,$this->order);
+ return $this->msg(200,'获取列表成功',$result);
+ }
+
+
+ /**
+ * 启用禁用
+ */
+ public function changeStatus():\think\Response\Json
+ {
+ $inputData = $this->request->param();
+ if (isset($inputData['language_id']) && $inputData['language_id'] != 0 && $inputData['language_id'] != '') {
+ $this->focus['site_id'] = $inputData['site_id'] = $inputData['language_id'];
+ unset($inputData['language_id']);
+ }
+ if (!$this->commonValidate(__FUNCTION__,$inputData)) {
+ return $this->msg(-1,$this->validate->getError());
+ }
+ $result = $this->model->changeStatus($inputData);
+ if ($result) {
+ return $this->msg(200,"操作成功");
+ } else {
+ return $this->msg(504,"操作失败");
+ }
+ }
+}
diff --git a/app/api/middleware/Auth.php b/app/api/middleware/Auth.php
new file mode 100644
index 0000000..924a9ae
--- /dev/null
+++ b/app/api/middleware/Auth.php
@@ -0,0 +1,79 @@
+ Env::get('jwt_config.iss'),
+ 'exp' => Env::get('jwt_config.exp')
+ ];
+ $jwt = new Jwt($config);
+ $route = strtolower($request->pathinfo());
+ $domain = strtolower($request->host());
+
+ if (in_array($route,Config::get('whitelist.route')) or in_array($domain,Config::get('whitelist.domain'))) {
+ //表示此系列请求不需要鉴权,直接通行
+ return $next($request);
+ } else {
+ //此系列请求需要鉴权。
+ $loginToken = $request->header('x-token');
+ $result = $jwt->checkToken($loginToken);
+ if ($result < 0) {
+ switch ($result) {
+ case -1:
+ show(-1,"token异常");
+ break;
+ case -2:
+ show(-2,"token被篡改");
+ break;
+ case -3:
+ show(-3,"token验签异常");
+ break;
+ case -4:
+ show(-4,"token已过期");
+ break;
+ }
+ } elseif ($result === 200 || $result === 201) {
+ // token通过
+ $adminInfo = $jwt->getUserInfo($loginToken);
+ if (!isset($adminInfo['id'])) {
+ show(-1001, '登录异常');
+ }
+
+ if (empty($adminInfo) || $adminInfo['status'] == 1) {
+ show(-1002, '登录异常');
+ }
+
+ if ($result === 201) {
+ $new_login_token = $jwt->getToken($adminInfo);
+ $data = [
+ 'login_token' => $new_login_token,
+ 'exp' => Env::get('jwt_config.exp')
+ ];
+
+ header("Access-Control-Expose-Headers: X-Token-info");
+ header("X-Token-info: " . base64_encode(json_encode($data)));
+ }
+ $adminInfo['auth_id_list'] = [];//权限菜单下发
+ $request->admin_user_info = $adminInfo;
+ return $next($request);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/api/middleware/LogVisit.php b/app/api/middleware/LogVisit.php
new file mode 100644
index 0000000..1812965
--- /dev/null
+++ b/app/api/middleware/LogVisit.php
@@ -0,0 +1,32 @@
+domain() . $request->url();
+ $params = json_encode($request->param(), JSON_UNESCAPED_UNICODE);
+ $route = strtolower($request->pathinfo());
+ $pathInfo = explode('/',$route);
+ $action = array_pop($pathInfo);
+ $controller = array_pop($pathInfo);
+ $admin_id = 0;
+ $admin_name = '';
+ $platformId = 0;
+ if (isset($request->admin_user_info)) {
+ $admin_id = $request->admin_user_info['id'];
+ $admin_name = $request->admin_user_info['nickname'];
+ $platformId = $request->admin_user_info['platform_id'];
+ }
+ $log = new LogVisitModel();
+ $log->log($url, $params, $controller, $action,$admin_id, $admin_name,$platformId);
+ return $next($request);
+ }
+
+}
diff --git a/app/api/model/Admin.php b/app/api/model/Admin.php
new file mode 100644
index 0000000..9ef0358
--- /dev/null
+++ b/app/api/model/Admin.php
@@ -0,0 +1,92 @@
+ 'int',
+ 'code' => 'string',
+ 'username' => 'string',
+ 'nickname' => 'string',
+ 'password' => 'string',
+ 'avatar' => 'string',
+ 'role_id' => 'int',
+ 'org_id' => 'int',
+ 'dept_group_id' => 'int',
+ 'dept_id' => 'int',
+ 'mobile' => 'string',
+ 'create_time' => 'int',
+ 'create_ip' => 'string',
+ 'last_time' => 'int',
+ 'last_ip' => 'string',
+ 'status' => 'int',
+ 'update_time' => 'int',
+ ];
+
+ /**
+ * 获取管理员列表
+ * @param array $where
+ * @param int $page
+ * @param int $size
+ * @param string $order
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getList($where, $page=1, $size=12, $order='id asc')
+ {
+ $w = [];
+ if (isset($where['username']) && $where['username'] != '') {
+ $w[] = ['username', 'like', $where['username'] . '%'];
+ }
+
+ if (isset($where['role_id']) && $where['role_id'] != 0) {
+ $w[] = ['role_id', '=', $where['role_id']];
+ }
+
+ if ($page < 0) $page = 1;
+ if ($size > 100) $size = 100;
+
+ $result = $this->where($w)->limit(($page-1)*$size, intval($size))->order($order)->withoutField(['password'])->select()->toArray();
+ return $result;
+ }
+
+ /**
+ * 通过用户名获取信息
+ * @param string $username
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfoByUserName($username)
+ {
+ $result = $this->where(['username' => $username])->find();
+ return $result ? $result->toArray() : [];
+ }
+
+ /**
+ * 获取用户信息
+ * @param int $id 管理员表主键
+ * @param bool $type
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getUserInfo(int $id,bool $type=false):array
+ {
+ if ($type) {
+ $result = $this->find($id);
+ } else {
+ $result = $this->withoutField('password')->find($id);
+ }
+ return $result ? $result->toArray() : [];
+ }
+}
diff --git a/app/api/model/AdvertisePage.php b/app/api/model/AdvertisePage.php
new file mode 100644
index 0000000..af2eab6
--- /dev/null
+++ b/app/api/model/AdvertisePage.php
@@ -0,0 +1,100 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 广告页关系广告位模型
+ */
+ public function PageSpace()
+ {
+ return $this->hasMany(AdvertiseSpace::class);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+ }
+ }
+
+
+ /**
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdSpace($data)
+ {
+ $result = $this->where('id',$data['id'])->with('PageSpace')->find()->toArray();
+ return $result['PageSpace'];
+ }
+
+}
diff --git a/app/api/model/AdvertiseSpace.php b/app/api/model/AdvertiseSpace.php
new file mode 100644
index 0000000..83a72a4
--- /dev/null
+++ b/app/api/model/AdvertiseSpace.php
@@ -0,0 +1,140 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'advertise_page_id'=>'int',
+ 'max_num' =>'int',
+ 'width' =>'int',
+ 'height' =>'int',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 一个广告位对应一个多多个广告
+ */
+ public function pageAd():\think\model\relation\HasMany
+ {
+ return $this->hasMany(Advertisement::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ $page[$key]['advertise_page_name'] = $this->getAdvertisePageName($item['advertise_page_id']);
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ $page[$key]['advertise_page_name'] = $this->getAdvertisePageName($item['advertise_page_id']);
+ }
+ }
+ return $page;
+ }
+ }
+
+ /**
+ * 广告位-广告的关联模型
+ */
+ public function spaceToAD():\think\model\relation\HasMany
+ {
+ return $this->hasMany(Advertisement::class);
+ }
+
+ /**
+ * 获取列表
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getList($data):array
+ {
+ $result = $this->where('site_id',$data['site_id'])->select();
+ if ($result) {
+ foreach ($result as &$item) {
+ $item['use_num'] = $item->spaceToAD()->count();
+ }
+ }
+ return $result->toArray();
+ }
+
+
+ /**
+ * 获取此广告位已经使用了的数量
+ * @param $data
+ * @return int
+ */
+ public function getUseSpaceNum($data):int
+ {
+ return Advertisement::where('advertise_space_id',$data['id'])->where('site_id',$data['site_id'])->count();
+ }
+
+
+ /**
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAd($data):array
+ {
+ return $this->where('id',$data['id'])->with('pageAd')->find()->toArray()['pageAd'];
+ }
+}
diff --git a/app/api/model/Advertisement.php b/app/api/model/Advertisement.php
new file mode 100644
index 0000000..a9d3e48
--- /dev/null
+++ b/app/api/model/Advertisement.php
@@ -0,0 +1,154 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'advertise_space_id' =>'int',
+ 'command' =>'string',
+ 'name' =>'string',
+ 'image' =>'string',
+ 'url' =>'string',
+ 'start_time' =>'int',
+ 'stop_time' =>'int',
+ 'play_order' =>'int',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ $page[$key]['advertise_space_name'] = $this->getAdertiseSpaceName($item['advertise_space_id']);
+ $page[$key]['spec'] = $this->getAdvertiseSpaceSpec($item['advertise_space_id']);
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ $page[$key]['advertise_space_name'] = $this->getAdertiseSpaceName($item['advertise_space_id']);
+ $page[$key]['spec'] = $this->getAdvertiseSpaceSpec($item['advertise_space_id']);
+ }
+ return $page;
+ }
+ }
+
+ /**
+ * 广告对应广告位,一对一
+ * @return \think\model\relation\BelongsTo
+ */
+ public function getAdToSpace()
+ {
+ return $this->belongsTo(AdvertiseSpace::class);
+ }
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ $advertisement = $this->find($data['id']);
+ if ($advertisement) {
+ $advertisement['ad_space_max_num'] = $advertisement->getAdToSpace()->value('max_num');
+ $advertisement['size'] = $advertisement->getAdToSpace()->value('width')."x".$advertisement->getAdToSpace()->value('height');
+ }
+ return $advertisement->toArray() ? : [];
+ }
+
+ /**
+ * 通过id获取当前广告位最大的广告数量
+ * @param $data
+ * @return int|mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdvertiseSpaceMaxNum($data):int
+ {
+ $result = AdvertiseSpace::find($data);
+ return $result ? $result['max_num'] : 1;
+ }
+
+ /**
+ * 通过id获取当前广告位已经有多少条广告
+ * @param $data
+ * @return int
+ */
+ public function getAdvertiseUseSpaceNum($data):int
+ {
+ return $this->where('advertise_space_id',$data['advertise_space_id'])->where('site_id',$data['site_id'])->count();
+ }
+
+
+ /**
+ * 查询当前数据是否是修改自己,还是别的项目修改成其他的
+ * @param $data
+ * @return bool
+ */
+ public function getBeforeUpdate($data):bool
+ {
+ $result = $this->findOrEmpty($data['id']);
+ if (!empty($result)) {
+ if ($result['advertise_space_id'] == $data['advertise_space_id']) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/app/api/model/Area.php b/app/api/model/Area.php
new file mode 100644
index 0000000..c7016ba
--- /dev/null
+++ b/app/api/model/Area.php
@@ -0,0 +1,16 @@
+ 'int',
+ 'pid' => 'int',
+ 'name' => 'string',
+ 'level' => 'int',
+ ];
+}
diff --git a/app/api/model/Article.php b/app/api/model/Article.php
new file mode 100644
index 0000000..968d7ec
--- /dev/null
+++ b/app/api/model/Article.php
@@ -0,0 +1,96 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'article_type_id' => 'int',
+ 'title' => 'string',
+ 'brief' => 'string',
+ 'desc' => 'string',
+ 'thumb' => 'string',
+ 'url' => 'string',
+ 'meta_title' => 'string',
+ 'keywords' => 'string',
+ 'detail' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_outer_chain' => 'int',
+ 'click_num' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ *
+ */
+ public function articleType():\think\model\relation\HasOne
+ {
+ return $this->hasOne(ArticleType::class,'id','article_type_id')->bind(['article_type_name'=>'name']);
+ }
+
+ /**
+ */
+ public function languageName():\think\model\relation\HasOne
+ {
+ return $this->hasOne(Language::class,'id','site_id')->bind(['language_name'=>'name']);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int) $data['size'])->page((int)$data['page'])->order($sort)->with(['articleType','languageName'])->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->with(['articleType','languageName'])->select()->toArray();
+ }
+ }
+}
diff --git a/app/api/model/ArticleType.php b/app/api/model/ArticleType.php
new file mode 100644
index 0000000..513bd6f
--- /dev/null
+++ b/app/api/model/ArticleType.php
@@ -0,0 +1,105 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * article分类与article表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getArticle()
+ {
+ return $this->hasMany(Article::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getArticleData($data):array
+ {
+ $article = $this->find($data['id']);
+ if (!empty($article)) {
+ return $article->getArticle()->select()->toArray();
+ }
+ return [];
+ }
+}
diff --git a/app/api/model/Attachment.php b/app/api/model/Attachment.php
new file mode 100644
index 0000000..8ec1bd5
--- /dev/null
+++ b/app/api/model/Attachment.php
@@ -0,0 +1,24 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'site_id' => 'int',
+ 'name' => 'string',
+ 'type' => 'string',
+ 'local' => 'string',
+ 'path' => 'string',
+ 'hash' => 'string',
+ 'md5' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+}
diff --git a/app/api/model/Attribute.php b/app/api/model/Attribute.php
new file mode 100644
index 0000000..1891e78
--- /dev/null
+++ b/app/api/model/Attribute.php
@@ -0,0 +1,34 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'name' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+
+ /**
+ * 通过属性ID,查找是否有商品引用属性
+ * @param $data
+ * @return array|\think\Model|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGoodsAttrById($data)
+ {
+ return GoodsAttribute::where('attribute_id',$data['id'])->find();
+ }
+}
diff --git a/app/api/model/BaseModel.php b/app/api/model/BaseModel.php
new file mode 100644
index 0000000..78d9e7e
--- /dev/null
+++ b/app/api/model/BaseModel.php
@@ -0,0 +1,417 @@
+'desc','sort'=>'desc']
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getIndexList(int $page,int $pageSize,array $field = [], array $vague = [],array $focus = [],array $order = []):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($fields,$focus) {
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ })->where(function($query) use ($fields,$vague) {
+ //模糊查询
+ if (!empty($vague)) {
+ foreach ($vague as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->whereOr($key,'like',"%".$item."%");
+ }
+ }
+ }
+ })->order($order);
+ //判断是否需要分页
+ if (0 == $page || 0 == $pageSize) {
+ //不需要分页
+ return $collection->select()->toArray();
+ } else {
+ //需要分布
+ $totalNum = $collection->count();
+ $data = $collection->page($page)->limit($pageSize)->select()->toArray();;
+ return ['count'=>$totalNum,'data'=>$data];
+ }
+ }
+
+ /**
+ * 新增数据
+ * @param array $data
+ * @return bool
+ */
+ public function addData(array $data) : bool
+ {
+ $result = $this->create($data);
+ return (bool)$result;
+ }
+
+ /**
+ * 编辑数据
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function editData(array $data) : bool
+ {
+ if (isset($data['id']) && $data['id'] > 0) {
+ $result = $this->find($data['id']);
+ return $result && $result->save($data);
+ }
+ return false;
+ }
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data) : array
+ {
+ if (isset($data['id'])) {
+ $result = $this->find($data['id']);
+ return $result ? $result->toArray() : [];
+ }
+ return [];
+ }
+
+ /**
+ * 删除
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData(array $data) : bool
+ {
+ if (isset($data['id'])) {
+ $result = $this->find($data['id']);
+ return $result && $result->delete();
+ }
+ return false;
+ }
+
+ /**
+ * 通过ID获取数据
+ * @param $ids
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getExportData($ids): array
+ {
+ $result = $this->whereIn($this->pk,$ids['ids'])->order('create_time','desc')->select();
+ return $result ? $result->toArray() : [];
+ }
+
+
+ /**
+ * 批量修改
+ * @param $data
+ * @return bool
+ * @throws \Exception
+ */
+ public function batchEditData($data):bool
+ {
+ $result = $this->saveAll($data);
+ return (bool)$result;
+ }
+
+
+ /**
+ * 批量删除
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function batchDelData(array $data) : bool
+ {
+ $res = true;
+ foreach ($data as $item) {
+ if (isset($item['id']) && $item['id'] > 0) {
+ $result = $this->find($item['id']);
+ $result = $result->delete();
+ $res = $res && $result;
+ }
+ }
+ return $res;
+ }
+
+ /**
+ * 获取地区名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAreaNameById($id):string
+ {
+ $data = Area::find($id);
+ return $data ? $data['name'] : '';
+ }
+
+ /**
+ * 获取币种名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getCoinName($id):string
+ {
+ $result = Currency::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 获取站点语言名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSiteLanguageName($id):string
+ {
+ $lang = Site::find($id);
+ $result = Language::find($lang['language_id']);
+ return $result ? $result['name'] : '';
+ }
+
+
+ /**
+ * 获取语言名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLanguageName($id):string
+ {
+ $result = Language::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+
+ /**
+ * 获取语言名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getCountryName($id):string
+ {
+ $result = Country::find($id);
+ return $result ? $result['zh'] : '其他';
+ }
+
+ /**
+ * 获取币种名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getPlatformName($id):string
+ {
+ $result = Platform::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过id获取名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFileTypeName($id):string
+ {
+ $result = FileType::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过id获取名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFaqTypeName($id):string
+ {
+ $result = FaqType::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过id获取名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdvertisePageName($id):string
+ {
+ $result = AdvertisePage::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过id获取名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdertiseSpaceName($id):string
+ {
+ $result = AdvertiseSpace::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过id获取尺寸
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdvertiseSpaceSpec($id):string
+ {
+ $result = AdvertiseSpace::find($id);
+ if ($result) {
+ $width = $result['width'];
+ $height = $result['height'];
+ return $width. 'x' . $height;
+
+ }
+ return '';
+ }
+
+ /**
+ * 通过id获取名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGoodsName($id):string
+ {
+ $result = Goods::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 启用禁用
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function changeStatus($data):bool
+ {
+ $result = $this->find($data['id']);
+ return $result && $result->save($data);
+ }
+
+ /**
+ * 排序
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function changeSort($data):bool
+ {
+ $result = $this->find($data['id']);
+ return $result && $result->save($data);
+ }
+
+ /**
+ * 获取子类ID
+ * @param $id
+ * @return array
+ */
+ public function getChildCategory($id):array
+ {
+ $res = $this->where('pid',$id)->column('id');
+ array_push($res,intval($id));
+ return $res ?: [];
+ }
+
+ /**
+ * 获取父类ID
+ * @param $id
+ * @return array
+ */
+ public function getPCategory($id):array
+ {
+ $res = $this->where('id',$id)->column('id');
+ array_push($res,intval($id));
+ return $res ?: [];
+ }
+
+ /**
+ * 动态数据检测,检测提交过来的数据中ID是否合法
+ * @param $model
+ * @param $condition
+ * @return bool
+ */
+ public function dynamicCheck($model,$condition):bool
+ {
+ return (bool) $model::where($condition)->find();
+ }
+
+
+}
diff --git a/app/api/model/Brand.php b/app/api/model/Brand.php
new file mode 100644
index 0000000..a830ce6
--- /dev/null
+++ b/app/api/model/Brand.php
@@ -0,0 +1,106 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'brand_type_id' => 'int',
+ 'title' => 'string',
+ 'brief' => 'string',
+ 'desc' => 'string',
+ 'thumb' => 'string',
+ 'url' => 'string',
+ 'meta_title' => 'string',
+ 'keywords' => 'string',
+ 'detail' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_outer_chain' => 'int',
+ 'is_on_index' => 'int',
+ 'click_num' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ 'website' => 'string',
+ 'cname' => 'string',
+// 'en_name' => 'string',
+ 'belong' => 'string',
+// 'turnover' => 'string',
+ 'brand_cate' => 'string',
+ 'work_address' => 'string',
+ 'founded' => 'string',
+ 'founder' => 'string'
+ ];
+
+ /**
+ *
+ */
+ public function BrandType():\think\model\relation\HasOne
+ {
+ return $this->hasOne(BrandType::class,'id','brand_type_id')->bind(['brand_type_name'=>'name']);
+ }
+
+ /**
+ */
+ public function languageName():\think\model\relation\HasOne
+ {
+ return $this->hasOne(Language::class,'id','site_id')->bind(['language_name'=>'name']);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int) $data['size'])->page((int)$data['page'])->order($sort)->with(['BrandType','languageName'])->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->with(['BrandType','languageName'])->select()->toArray();
+ }
+ }
+}
diff --git a/app/api/model/BrandType.php b/app/api/model/BrandType.php
new file mode 100644
index 0000000..74e5871
--- /dev/null
+++ b/app/api/model/BrandType.php
@@ -0,0 +1,122 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * Brand分类与Brand表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getBrand()
+ {
+ return $this->hasMany(Brand::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getBrandData($data):array
+ {
+ $Brand = $this->find($data['id']);
+ if (!empty($Brand)) {
+ return $Brand->getBrand()->select()->toArray();
+ }
+ return [];
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getArticleData($data):array
+ {
+ $article = $this->find($data['id']);
+ if (!empty($article)) {
+ return $article->getBrand()->select()->toArray();
+ }
+ return [];
+ }
+}
diff --git a/app/api/model/BulkBuy.php b/app/api/model/BulkBuy.php
new file mode 100644
index 0000000..b215ebc
--- /dev/null
+++ b/app/api/model/BulkBuy.php
@@ -0,0 +1,25 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'area_id' =>'int',
+ 'name' =>'string',
+ 'phone' =>'string',
+ 'mode_number' =>'string',
+ 'email' =>'string',
+ 'arrival_country'=>'string',
+ 'delivery_time' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/api/model/Comment.php b/app/api/model/Comment.php
new file mode 100644
index 0000000..fbfb637
--- /dev/null
+++ b/app/api/model/Comment.php
@@ -0,0 +1,222 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'avatar' =>'string',
+ 'name' =>'string',
+ 'nickname' =>'string',
+ 'comment' =>'string',
+ 'url' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ protected $disuse = ['name'];
+ /**
+ * 反馈附件关联
+ * @return \think\model\relation\HasMany
+ */
+ public function CommentImage()
+ {
+ return $this->hasMany(CommentImage::class);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+ $newCommentImage = [];
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->with('CommentImage')->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $value) {
+ $resData[$key]['language_id'] = $value['site_id'];
+ if (isset($value['CommentImage']) && !empty($value['CommentImage'])) {
+ foreach ($value['CommentImage'] as $key1 => $value1) {
+ $newCommentImage[$key1]['name'] = basename($value1['image']);
+// $newCommentImage[$key1]['url'] = Env::get('QINIU.cdn') . $value1['image'];
+ $newCommentImage[$key1]['url'] = $value1['image'];
+ }
+ $page[$key]['CommentImage'] = $newCommentImage;
+ }
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->with('CommentImage')->select()->toArray();
+
+ if (!empty($resData)) {
+ if ($resData['CommentImage']) {
+ foreach ($resData as $key => $value) {
+ $resData[$key]['language_id'] = $value['site_id'];
+ foreach ($value['CommentImage'] as $key1 => $value1) {
+ $newCommentImage[$key1]['name'] = basename($value1['image']);
+// $newCommentImage[$key1]['url'] = Env::get('QINIU.cdn') . $value1['image'];
+ $newCommentImage[$key1]['url'] = $value1['image'];
+ }
+ $resData[$key]['CommentImage'] = $newCommentImage;
+ }
+ }
+ }
+ return $resData;
+ }
+ }
+
+ /**
+ * 新增数据
+ * @param $data
+ * @return bool
+ */
+ public function addData($data):bool
+ {
+ $this->startTrans();
+ try {
+ $data['avatar'] = doImageURLtoRelativePath($data['avatar']);
+ $comment = $this->create($data);
+ //处理数据结构
+ if (!empty($data['CommentImage'])) {
+ foreach ($data['CommentImage'] as &$value) {
+ $value['comment_id'] = $comment->id;
+ $value['image'] = doImageURLtoRelativePath($value['url']);
+ }
+ //模型关联新增
+ $comment->CommentImage()->saveAll($data['CommentImage']);
+ }
+ $this->commit();
+ return true;
+ } catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+ }
+
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ $comment = $this->find($data['id']);
+ $comment['CommentImage'] = $this->CommentImage()->where('comment_id',$data['id'])->select();
+ if ($comment['CommentImage']) {
+ $newImage = [];
+ foreach ($comment['CommentImage'] as $key1 => $value1) {
+ $newImage[$key1]['name'] = basename($value1['image']);
+ $newImage[$key1]['url'] = $value1['image'];
+ }
+ $comment['CommentImage'] = $newImage;
+ }
+ return $comment->toArray();
+ }
+
+ /**
+ * 编辑数据
+ * @param array $data
+ * @return bool
+ */
+ public function editData(array $data):bool
+ {
+ $this->startTrans();
+ try {
+ $data['comment_image'] = $data['CommentImage'];
+ unset($data['CommentImage']);
+ $comment = $this->find($data['id']);
+ $data['avatar'] = doImageURLtoRelativePath($data['avatar']);
+ $result1 = $comment->save($data);
+ //先将原先的全部删除
+ if (!empty($data['comment_image'])) {
+ $result2 = $comment->CommentImage->delete();
+ if ($result1 && $result2) {
+ //处理数据结构
+ $newCommentImage = [];
+ foreach ($data['comment_image'] as $key => $value) {
+ $newCommentImage[] = [
+ 'comment_id' => $data['id'],
+ 'image' => doImageURLtoRelativePath($value['url']),
+ ];
+ }
+ $data['comment_image'] = $newCommentImage;
+ //新增
+ $comment->CommentImage()->saveAll($data['comment_image']);
+ }
+ }
+ $this->commit();
+ return true;
+ } catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+ }
+
+
+ /**
+ * 删除数据
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData(array $data):bool
+ {
+ $comment = $this->find($data['id']);
+ $result1 = $comment->delete();
+ //先将原先的全部删除
+ $result2 = $comment->CommentImage->delete();;
+ return $result1 && $result2;
+ }
+
+}
diff --git a/app/api/model/CommentImage.php b/app/api/model/CommentImage.php
new file mode 100644
index 0000000..d5660de
--- /dev/null
+++ b/app/api/model/CommentImage.php
@@ -0,0 +1,16 @@
+'int',
+ 'comment_id' =>'int',
+ 'image' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/api/model/Country.php b/app/api/model/Country.php
new file mode 100644
index 0000000..f07d24f
--- /dev/null
+++ b/app/api/model/Country.php
@@ -0,0 +1,23 @@
+ 'int',
+ 'en' => 'string',
+ 'code' => 'string',
+ 'tw' => 'string',
+ 'zh' => 'string',
+ 'icon' => 'string',
+ 'locale' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+
+}
diff --git a/app/api/model/CouponSubscribe.php b/app/api/model/CouponSubscribe.php
new file mode 100644
index 0000000..31c9767
--- /dev/null
+++ b/app/api/model/CouponSubscribe.php
@@ -0,0 +1,78 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'goods_coupon_id' =>'int',
+ 'email' =>'string',
+ 'phone' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList($data,$simple = null,$focus = null,$sort = null,$field = null)
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ }
+ }
+ return $page;
+ }
+ }
+
+}
diff --git a/app/api/model/Currency.php b/app/api/model/Currency.php
new file mode 100644
index 0000000..eab2b32
--- /dev/null
+++ b/app/api/model/Currency.php
@@ -0,0 +1,84 @@
+'int',
+ 'name' =>'string',
+ 'code' =>'string',
+ 'signal' =>'string',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * 通过币种ID获取平台是否已经使用
+ * @param $data
+ * @return array|\think\Model|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getPlatformCoin($data)
+ {
+ return Platform::where('currency_id',$data)->find();
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->order($sort)->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->select()->toArray();
+ }
+ }
+
+}
diff --git a/app/api/model/Faq.php b/app/api/model/Faq.php
new file mode 100644
index 0000000..cfea278
--- /dev/null
+++ b/app/api/model/Faq.php
@@ -0,0 +1,94 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'faq_type_id' =>'int',
+ 'question' =>'string',
+ 'answer' =>'string',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+// if (!empty($simple)) {
+// foreach ($simple as $key => $item) {
+// if (in_array($key,$fields)) {
+// $query->where($key,'like',"%".$item."%");
+// }
+// }
+// }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ })->where(function ($query) use ($data,$fields,$simple) {
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->whereOr($key,'like',"%".$item."%");
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ //获取列表名称
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['faq_type_name'] = $this->getFaqTypeName($item['faq_type_id']);
+ $page[$key]['language_id'] = $this->getFaqTypeName($item['site_id']);
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ //获取列表名称
+ foreach ($page as $key => $item) {
+ $page[$key]['faq_type_name'] = $this->getFaqTypeName($item['faq_type_id']);
+ $page[$key]['language_id'] = $this->getFaqTypeName($item['site_id']);
+ }
+ }
+ return $page;
+ }
+ }
+}
diff --git a/app/api/model/FaqType.php b/app/api/model/FaqType.php
new file mode 100644
index 0000000..c3f415d
--- /dev/null
+++ b/app/api/model/FaqType.php
@@ -0,0 +1,106 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * faq分类关联faq表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getFaqContents()
+ {
+ return $this->hasMany(Faq::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的faq内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFaqData($data)
+ {
+ $faqType = $this->find($data['id']);
+ if (!empty($faqType)) {
+ return $faqType->getFaqContents()->select()->toArray();
+ }
+ return false;
+ }
+}
diff --git a/app/api/model/FileType.php b/app/api/model/FileType.php
new file mode 100644
index 0000000..520c4de
--- /dev/null
+++ b/app/api/model/FileType.php
@@ -0,0 +1,130 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ public function fileTypeSoftManual()
+ {
+ return $this->hasMany(SoftManual::class);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->with('fileTypeSoftManual')->select()->toArray();
+ if (!empty($resData)) {
+ foreach ($resData as $key => $item)
+ $resData[$key]['language_id'] = $item['site_id'];{
+ if (count($item['fileTypeSoftManual']) > 0) {
+ $resData[$key]['is_gray'] = 1;
+ } else {
+ $resData[$key]['is_gray'] = 0;
+ }
+ }
+ }
+ return $resData;
+ }
+ }
+
+
+ /**
+ * 获取当前类型下驱动下载文件内容
+ * @param $data
+ * @return false
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSoftManualData($data)
+ {
+ $softManual = $this->find($data['id']);
+ if (!empty($softManual)) {
+ return $softManual->fileTypeSoftManual()->select()->toArray();
+ }
+ return false;
+ }
+
+
+ /**
+ * 批量编辑数据
+ * @param $data
+ * @return \think\Collection
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function batchEditData($data):bool
+ {
+ return (bool)$this->saveAll($data);
+// $result = $result1 = true;
+// foreach ($data as $item) {
+// $models = $this->find($item['id']);
+// if ($models) {
+// $result1 = $models->save($item);
+// }
+// $result = $result && $result1;
+// }
+// return $result;
+ }
+
+}
diff --git a/app/api/model/Goods.php b/app/api/model/Goods.php
new file mode 100644
index 0000000..feeb4a6
--- /dev/null
+++ b/app/api/model/Goods.php
@@ -0,0 +1,609 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'main_img' =>'string',
+ 'model_number' =>'string',
+ 'goods_category_id' =>'int',
+ 'price' =>'int',
+ 'is_new' =>'int',
+ 'is_discount' =>'int',
+ 'is_hot' =>'int',
+ 'is_recommend' =>'int',
+ 'details' =>'string',
+ 'title' =>'string',
+ 'keywords' =>'string',
+ 'description' =>'string',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 商品链接关联模型
+ */
+ public function GoodsBuyNow()
+ {
+ return $this->hasMany(GoodsBuyNow::class);
+ }
+
+ /**
+ * 商品关联商品
+ */
+ public function GoodsConnect()
+ {
+ return $this->hasMany(GoodsConnect::class);
+ }
+
+ /**
+ * 商品手册关联模型
+ * @return \think\model\relation\HasMany
+ */
+ public function GoodsSoftManual()
+ {
+ return $this->hasMany(GoodsSoftManual::class);
+ }
+
+ /**
+ * 商品主图关联模型
+ * @return \think\model\relation\HasMany
+ */
+ public function GoodsImages()
+ {
+ return $this->hasMany(GoodsImages::class);
+ }
+
+ /**
+ * 商品属性关联
+ * @return \think\model\relation\HasMany
+ */
+ public function goodsAttr()
+ {
+ return $this->hasMany(GoodsAttribute::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ //分类查询
+ if (!empty($data['goods_category_id']) && is_array($data['goods_category_id'])) {
+ $query->whereIn('goods_category_id',implode(',',$data['goods_category_id']));
+ }
+ });
+ //先筛选再分
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->order($sort)->select()->count();
+ $page = $collection->order($sort)->limit((int)$data['size'])->page((int)$data['page'])->select()->toArray();
+ return ['page'=>array_values($page),'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->select()->toArray();
+ return array_values($resData);
+ }
+ }
+
+ /**
+ * 新增数据
+ * @param array $data
+ * @return bool
+ */
+ public function addData(array $data):bool
+ {
+ //开启事务
+ $this->startTrans();
+ //增加主图
+ if (isset($data['goods_images'][0]['url'])) {
+ $data['main_img'] = doImageURLtoRelativePath($data['goods_images'][0]['url']);
+ } else {
+ //TODO::没有上传数据则使用空,后面可以替换为默认图片
+ $data['main_img'] = '';
+ }
+ $goods = $this->create($data);
+ //处理数据结构
+ $newBuyNow = [];
+ foreach ($data['buy_now'] as $key => $value) {
+ if ($value['name'] != '' && $value['url'] != '') {
+ $newBuyNow[$key]['goods_id'] = $goods->id;
+ $newBuyNow[$key]['name'] = $value['name'];
+ $newBuyNow[$key]['url'] = $value['url'];
+ }
+ }
+ $data['buy_now'] = $newBuyNow;
+ if (!empty($data['buy_now'])) {
+ $result1 = $goods->GoodsBuyNow()->saveAll($data['buy_now']);
+ } else {
+ unset($data['buy_now']);
+ $result1 = true;
+ }
+
+ $newGoodsImages = [];
+ foreach ($data['goods_images'] as $key => $value) {
+ if ($key < 8) {
+ $newGoodsImages[$key]['goods_id'] = $goods->id;
+ $newGoodsImages[$key]['image'] = doImageURLtoRelativePath($value['url']);
+ }
+ }
+ $data['goods_images'] = $newGoodsImages;
+ if (!empty($data['goods_images'])) {
+ $result2 = $goods->GoodsImages()->saveAll($data['goods_images']);
+ } else {
+ unset($data['goods_images']);
+ $result2 = true;
+ }
+
+ $newConnectGoods = [];
+ foreach ($data['connect_goods'] as $key => $value) {
+ if ($value['connect_good_id'] != '' && $value['goods_category_id'] != '') {
+ $newConnectGoods[$key]['goods_id'] = $goods->id;
+ $newConnectGoods[$key]['connect_good_id'] = $value['connect_good_id'];
+ $newConnectGoods[$key]['goods_category_id'] = $value['goods_category_id'];
+ }
+ }
+ $data['connect_goods'] = $newConnectGoods;
+ if (!empty($data['connect_goods'])) {
+ $result3 = $goods->GoodsConnect()->saveAll($data['connect_goods']);
+ } else {
+ unset($data['connect_goods']);
+ $result3 = true;
+ }
+ //处理驱动文档数据
+ $newSoft = [];
+ foreach ($data['soft_manual'] as $key => $value) {
+ if ($value['file_type_id'] != '' && $value['soft_manual_id'] != '') {
+ $newSoft[$key]['goods_id'] = $goods->id;
+ $newSoft[$key]['file_type_id'] = $value['file_type_id'];
+ $newSoft[$key]['soft_manual_id'] = $value['soft_manual_id'];
+ }
+ }
+ $data['soft_manual'] = $newSoft;
+ if (!empty($data['soft_manual'])) {
+ $result4 = $goods->GoodsSoftManual()->saveAll($data['soft_manual']);
+ } else {
+ unset($data['soft_manual']);
+ $result4 = true;
+ }
+
+ //处理属性attr
+ $newAttr = [];
+ foreach ($data['attr'] as $key => $item) {
+ if ($item['attribute_id'] != '' && $item['value'] != '') {
+ $newAttr[$key]['goods_id'] = $goods->id;
+ $newAttr[$key]['attribute_id'] = $item['attribute_id'];
+ $newAttr[$key]['value'] = $item['value'];
+ }
+ }
+ $data['attr'] = $newAttr;
+ if (!empty($data['attr'])) {
+ $result5 = $goods->goodsAttr()->saveAll($data['attr']);
+ } else {
+ unset($data['attr']);
+ $result5 = true;
+ }
+ //模型关联新增
+ if($result1 && $result2 && $result3 && $result4 && $result5) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ //初始化默认结构
+ $defaultBuyNow = [['name' => '','url' => '']];
+ $defaultSoftManual = [['file_type_id'=>'','soft_manual_id'=>'']];
+ $defaultAttr = [['id'=>'','value'=>'']];
+ $defaultGoodsImages = [['name'=>'','url'=>'']];
+ $defaultConnectGoods = [
+ ['connect_good_id'=>'','goods_category_id'=>''],
+ ['connect_good_id'=>'','goods_category_id'=>''],
+ ['connect_good_id'=>'','goods_category_id'=>''],
+ ['connect_good_id'=>'','goods_category_id'=>''],
+ ];
+
+ $goods = $this->find($data['id']);
+ $goods['buy_now'] = $this->GoodsBuyNow()->where('goods_id',$data['id'])->select()->toArray();
+ $goods['goods_images'] = $this->GoodsImages()->where('goods_id',$data['id'])->select()->toArray();
+ $goods['connect_goods'] = $this->GoodsConnect()->where('goods_id',$data['id'])->select()->toArray();
+ $goods['soft_manual'] = $this->GoodsSoftManual()->where('goods_id',$data['id'])->select()->toArray();
+ $goods['attr'] = $this->goodsAttr()->where('goods_id',$data['id'])->select()->toArray();
+
+ //处理buynow
+ if (!empty($goods['buy_now'])) {
+ $newBuyNow = [];
+ foreach ($goods['buy_now'] as $key => $item) {
+ $newBuyNow[$key]['name'] = $item['name'];
+ $newBuyNow[$key]['url'] = $item['url'];
+ }
+ $goods['buy_now'] = $newBuyNow;
+ } else {
+ $goods['buy_now'] = $defaultBuyNow;
+ }
+ //处理属性attr
+ if (!empty($goods['attr'])) {
+ $newAttr = [];
+ foreach ($goods['attr'] as $key => $item) {
+ $newAttr[$key]['attribute_id'] = $item['attribute_id'];
+ $newAttr[$key]['value'] = $item['value'];
+ }
+ $goods['attr'] = $newAttr;
+ } else {
+ $goods['attr'] = $defaultAttr;
+ }
+ //处理图片
+ if (!empty($goods['goods_images'])) {
+ $newGoodsImages = [];
+ foreach ($goods['goods_images'] as $key => $item) {
+ if ($key < 8) {
+ $newGoodsImages[$key]['id'] = $item['id'];
+ $newGoodsImages[$key]['name'] = basename($item['image']);
+ $newGoodsImages[$key]['url'] = $item['image'];
+ }
+ }
+ $goods['goods_images'] = $newGoodsImages;
+ } else {
+ $goods['goods_images'] = $defaultGoodsImages;
+ }
+
+ //处理关联产品数据
+ if (!empty($goods['connect_goods'])) {
+ $newConnectGoods = [];
+ foreach ($goods['connect_goods'] as $key => $item) {
+ $newConnectGoods[$key]['id'] = $item['id'];
+ $newConnectGoods[$key]['connect_good_id'] = $item['connect_good_id'];
+ $newConnectGoods[$key]['type'] = $key;
+ $newConnectGoods[$key]['goods_category_id'] = $item['goods_category_id'];
+ }
+ if (count($newConnectGoods) < 4 ) {
+ $arr = [['connect_good_id'=>'','goods_category_id'=>'']];
+ switch (count($newConnectGoods)) {
+ case 1:
+ $newConnectGoods = array_merge(array_merge(array_merge($newConnectGoods,$arr),$arr),$arr);
+ break;
+ case 2:
+ $newConnectGoods = array_merge(array_merge($newConnectGoods,$arr),$arr);
+ break;
+ case 3:
+ $newConnectGoods = array_merge($newConnectGoods,$arr);
+ break;
+ }
+ }
+ $goods['connect_goods'] = $newConnectGoods;
+ } else {
+ $goods['connect_goods'] = $defaultConnectGoods;
+ }
+
+ //处理下载驱动手册
+ if (!empty($goods['soft_manual'])) {
+ $newSoft = [];
+ foreach ($goods['soft_manual'] as $key => $good) {
+ $newSoft[$key]['file_type_id'] = $good['file_type_id'];
+ $newSoft[$key]['soft_manual_id'] = $good['soft_manual_id'];
+ $newSoft[$key]['list'] = SoftManual::where('file_type_id',$good['file_type_id'])->select()->toArray();
+ }
+ $goods['soft_manual'] = $newSoft;
+ } else {
+ $goods['soft_manual'] = $defaultSoftManual;
+ }
+
+ return $goods->toArray();
+ }
+
+ /**
+ * 编辑数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function editData(array $data):bool
+ {
+ $this->startTrans();
+ $goods = $this->find($data['id']);
+ //如何编辑商品修改了分类数据,那么需要把相关产品对应的分类一同删除
+ if ($goods['goods_category_id'] != $data['goods_category_id']) {
+ $connect = GoodsConnect::where(['goods_id'=>$data['id'],'goods_category_id'=>$goods['goods_category_id']])->column(['id']);
+ if (!empty($connect)) {
+ GoodsConnect::destroy($connect);
+ }
+
+ }
+// dd($goods['goods_category_id'] , $data['goods_category_id']);
+ //增加主图
+ $data['main_img'] = doImageURLtoRelativePath($data['goods_images'][0]['url']);
+ $result1 = $goods->save($data);
+ //先将原先的全部删除
+ $result2 = $goods->GoodsBuyNow->delete();
+ $result3 = $goods->GoodsImages->delete();
+ $result4 = $goods->GoodsConnect->delete();
+ $result5 = $goods->GoodsSoftManual->delete();
+ $result6 = $goods->goodsAttr->delete();
+
+ $result = false;
+
+ if ($result1 && $result2 && $result3 && $result4 && $result5 && $result6) {
+ //处理数据结构
+ $newBuyNow = [];
+ foreach ($data['buy_now'] as $key => $value) {
+ if ($value['name'] != '' && $value != '') {
+ $newBuyNow[$key]['goods_id'] = $data['id'];
+ $newBuyNow[$key]['name'] = $value['name'];
+ $newBuyNow[$key]['url'] = $value['url'];
+ }
+ }
+ $data['buy_now'] = $newBuyNow;
+ if (!empty($data['buy_now'])) {
+ $result11 = $goods->GoodsBuyNow()->saveAll($data['buy_now']);
+ } else {
+ $result11 = true;
+ }
+
+ $newGoodsImages = [];
+ foreach ($data['goods_images'] as $key => $value) {
+ if ($key < 8) {
+ $newGoodsImages[$key]['goods_id'] = $data['id'];
+ $newGoodsImages[$key]['image'] = doImageURLtoRelativePath($value['url']);
+ }
+ }
+ $data['goods_images'] = $newGoodsImages;
+ if (!empty($data['goods_images'])) {
+ $result22 = $goods->GoodsImages()->saveAll($data['goods_images']);
+ } else {
+ $result22 = true;
+ }
+
+ $newConnectGoods = [];
+ foreach ($data['connect_goods'] as $key => $value) {
+ if ($value['goods_category_id'] != '' && $value['connect_good_id'] != '') {
+ $newConnectGoods[$key]['goods_id'] = $data['id'];
+ $newConnectGoods[$key]['connect_good_id'] = $value['connect_good_id'];
+ $newConnectGoods[$key]['goods_category_id'] = $value['goods_category_id'];
+ }
+ }
+ $data['connect_goods'] = $newConnectGoods;
+ if (!empty($data['connect_goods'])) {
+ $result33 = $goods->GoodsConnect()->saveAll($data['connect_goods']);
+ } else {
+ $result33 = true;
+ }
+
+
+ //处理驱动文档数据
+ $newSoft = [];
+ foreach ($data['soft_manual'] as $key => $value) {
+ if ($value['file_type_id'] != '' && $value['soft_manual_id'] != '') {
+ $newSoft[$key]['goods_id'] = $data['id'];
+ $newSoft[$key]['file_type_id'] = $value['file_type_id'];
+ $newSoft[$key]['soft_manual_id'] = $value['soft_manual_id'];
+ }
+ }
+ $data['soft_manual'] = $newSoft;
+ if (!empty($data['soft_manual'])) {
+ $result44 = $goods->GoodsSoftManual()->saveAll($data['soft_manual']);
+ } else {
+ $result44 = true;
+ }
+ //处理属性attr
+ $newAttr = [];
+ foreach ($data['attr'] as $key => $item) {
+ if ($item['attribute_id'] != '' && $item['value'] != '') {
+ $newAttr[$key]['goods_id'] = $goods->id;
+ $newAttr[$key]['attribute_id'] = $item['attribute_id'];
+ $newAttr[$key]['value'] = $item['value'];
+ }
+ }
+ $data['attr'] = $newAttr;
+ if (!empty($data['attr'])) {
+ $result55 = $goods->goodsAttr()->saveAll($data['attr']);
+ } else {
+ $result55 = true;
+ }
+
+ $result = $result11 && $result22 && $result33 && $result44 && $result55;
+ }
+
+ if ($result) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 删除数据
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData(array $data):bool
+ {
+ $goods = $this->find($data['id']);
+ $result1 = $goods->delete();
+ //先将原先的全部删除
+ $result2 = $goods->GoodsBuyNow->delete();
+ $result3 = $goods->GoodsImages->delete();
+ $result4 = $goods->GoodsConnect->delete();
+ $result5 = $goods->GoodsSoftManual->delete();
+ $result6 = $goods->goodsAttr->delete();
+
+ return $result1 && $result2 && $result3 && $result4 && $result5 && $result6;
+ }
+
+ /**
+ * 获取平台语言包列表
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getPlatformLanguage($data)
+ {
+ $result = (new Platform())->getPlatformLanguage($data);
+ if ($result) {
+ foreach ($result as $key => $item) {
+ $result[$key]['language_name'] = $this->getLanguageName($item['site_id']);
+ $result[$key]['coin_name'] = $this->getCoinName($item['currency_id']);
+ foreach ($item['PlatformLanguage'] as $key1 => $item1) {
+ $result[$key]['PlatformLanguage'][$key1]['language_name'] = $this->getLanguageName($item1['site_id']);
+ }
+ foreach ($item['PlatformCoin'] as $key1 => $item1) {
+ $result[$key]['PlatformCoin'][$key1]['coin_name'] = $this->getCoinName($item1['currency_id']);
+ }
+ }
+ return $result->toArray();
+ }
+ return [];
+ }
+
+ /**
+ * 通过分类ID获取商品列表
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGoodsInfoByGoodsCategoryId($data)
+ {
+ return $this->where(['goods_category_id'=>$data['goods_category_id'],'status'=>0])->select()->toArray();
+ }
+
+ /**
+ * 批量删除数据
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function batchDelData(array $data):bool
+ {
+ $newResult = true;
+ foreach ($data as $item) {
+ $result = $this->delData($item);
+ $newResult = $newResult && $result;
+ }
+ return $newResult;
+ }
+
+ /**
+ * 批量移除商品分类
+ * @param $data
+ * @return bool
+ */
+ public function batchRemoveOldCate($data)
+ {
+ return GoodsCate::whereIn('goods_id',implode(',',$data))->delete();
+ }
+
+ /**
+ * @param $data
+ * @return bool|\think\Collection
+ * @throws \Exception
+ */
+ public function goodsBatchEditCategory($data)
+ {
+ $this->startTrans();
+ try {
+ //修改分类时,先查询当前分类下的分类数据
+ foreach ($data as $datum) {
+ $goods = $this->find($datum['id']);
+ if ($goods['goods_category_id'] != $datum['goods_category_id']) {
+ $connect = GoodsConnect::where(['goods_id'=>$datum['id'],'goods_category_id'=>$goods['goods_category_id']])->column('id');
+ if (!empty($connect)) {
+ GoodsConnect::destroy($connect);
+ }
+ }
+ }
+ $result = $this->saveAll($data);
+ if ($result) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+
+ }catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+
+ }
+
+ /**
+ * 获取分类及其子分类
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllSonCategory($data)
+ {
+ $newData = (new GoodsCategory())->getAllSonCategory($data);
+ array_push($newData,$data['id']);
+ return $newData;
+ }
+}
diff --git a/app/api/model/GoodsAttribute.php b/app/api/model/GoodsAttribute.php
new file mode 100644
index 0000000..e5eb4ec
--- /dev/null
+++ b/app/api/model/GoodsAttribute.php
@@ -0,0 +1,18 @@
+'int',
+ 'goods_id' =>'int',
+ 'attribute_id' =>'int',
+ 'value' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ 'sort' =>'int',
+ ];
+}
diff --git a/app/api/model/GoodsBuyNow.php b/app/api/model/GoodsBuyNow.php
new file mode 100644
index 0000000..9c623ce
--- /dev/null
+++ b/app/api/model/GoodsBuyNow.php
@@ -0,0 +1,21 @@
+'int',
+ 'goods_id' =>'int',
+ 'url' =>'string',
+ 'name' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/api/model/GoodsCate.php b/app/api/model/GoodsCate.php
new file mode 100644
index 0000000..2e5dcdb
--- /dev/null
+++ b/app/api/model/GoodsCate.php
@@ -0,0 +1,17 @@
+'int',
+ 'goods_id' =>'int',
+ 'goods_category_id' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/api/model/GoodsCategory.php b/app/api/model/GoodsCategory.php
new file mode 100644
index 0000000..f2e0d03
--- /dev/null
+++ b/app/api/model/GoodsCategory.php
@@ -0,0 +1,133 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'int',
+ 'desc' =>'int',
+ 'pid' =>'int',
+ 'icon' =>'int',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 分类 商品数据
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGategoryListData($data)
+ {
+ return (new Goods())->where(['goods_category_id'=>$data['goods_category_id'],'status'=>0])->select()->toArray();
+ }
+
+
+ /**
+ * 分类 商品明细数据
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGategoryListDataInfo($data)
+ {
+ if (isset($data['id']) && $data['id'] != 0) {
+ $result = GoodsConnect::where('goods_id',$data['id'])->find();
+ return $result ? $result->toArray() : [] ;
+ }
+ return [];
+ }
+
+ /**
+ * 启用禁用
+ * @param $data
+ * @param bool $type
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function changeStatus($data,bool $type = false):bool
+ {
+ if (!$type) {
+ $result = $this->find($data['id']);
+ //正常更新
+ if ($result) {
+ return $result->save($data);
+ }
+ } else {
+ $ret = $this->saveAll($data);
+ return (bool) $ret;
+ }
+ return false;
+ }
+
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ $allCategory = $this->select()->toArray();
+ $result = $this->find($data['id']);
+ $newPid = [];
+ if (!empty($allCategory)) {
+ if ($result['pid'] != 0) {
+ $newPid = category_to_all_pid($allCategory,$result['pid']);
+ } else {
+ $newPid = [0];
+ }
+ }
+ $result['pid'] = $newPid;
+ return $result->toArray();
+ }
+
+ /**
+ * 查找所有子项
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllSonCategory($data):array
+ {
+ $newData = $this->select()->toArray();
+ if (!empty($newData)) {
+ return category_to_all_children_id($newData,$data['id']);
+ }
+ return [];
+ }
+
+ /**
+ * 查询当前分类下是否在商品
+ * @param $data
+ * @return array|\think\Model|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function hasGoodsOnCategory($data)
+ {
+ return Goods::where('goods_category_id',$data['id'])->find();
+ }
+}
diff --git a/app/api/model/GoodsConnect.php b/app/api/model/GoodsConnect.php
new file mode 100644
index 0000000..a5a91bc
--- /dev/null
+++ b/app/api/model/GoodsConnect.php
@@ -0,0 +1,19 @@
+'int',
+ 'goods_id' =>'int',
+ 'goods_category_id' =>'int',
+ 'connect_good_id' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/api/model/GoodsCoupon.php b/app/api/model/GoodsCoupon.php
new file mode 100644
index 0000000..2f8f46e
--- /dev/null
+++ b/app/api/model/GoodsCoupon.php
@@ -0,0 +1,35 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'old_code' =>'string',
+ 'new_code' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ *
+ * @param $data
+ * @return array|Model|void|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLatest($data)
+ {
+ return $this->order($this->pk,'desc')->where($data)->find();
+ }
+}
diff --git a/app/api/model/GoodsImages.php b/app/api/model/GoodsImages.php
new file mode 100644
index 0000000..e1e9e5f
--- /dev/null
+++ b/app/api/model/GoodsImages.php
@@ -0,0 +1,19 @@
+'int',
+ 'goods_id' =>'int',
+ 'image' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+
+ ];
+}
diff --git a/app/api/model/GoodsSoftManual.php b/app/api/model/GoodsSoftManual.php
new file mode 100644
index 0000000..8a9e03c
--- /dev/null
+++ b/app/api/model/GoodsSoftManual.php
@@ -0,0 +1,19 @@
+'int',
+ 'goods_id' =>'int',
+ 'file_type_id' =>'int',
+ 'soft_manual_id'=>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/api/model/ImagesFile.php b/app/api/model/ImagesFile.php
new file mode 100644
index 0000000..d422096
--- /dev/null
+++ b/app/api/model/ImagesFile.php
@@ -0,0 +1,44 @@
+hasOne(User::class, 'id', 'up_id')->bind(['uploader_name'=>'nickname']);
+ }
+
+ // 根据ID查询
+ public function scopeId($query, $id)
+ {
+ if (is_array($id)) {
+ $query->where('id', 'in', $id);
+ } else {
+ $query->where('id', '=', $id);
+ }
+ }
+
+ // 根据上传人查询
+ public function scopeUpId($query, $up_id)
+ {
+ $query->where('up_id', '=', $up_id);
+ }
+
+ // 根据文件MD5值查询
+ public function scopeFileMd5($query, $md5)
+ {
+ $query->where('file_md5', '=', $md5);
+ }
+
+ // 根据文件hash值查询
+ public function scopeFileHash($query, $hash)
+ {
+ $query->where('file_hash', '=', $hash);
+ }
+}
diff --git a/app/api/model/Investment.php b/app/api/model/Investment.php
new file mode 100644
index 0000000..a2c02cb
--- /dev/null
+++ b/app/api/model/Investment.php
@@ -0,0 +1,107 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'country_id' => 'int',
+ 'province_id' => 'int',
+ 'city_id' => 'int',
+ 'from' => 'string',
+ 'area' => 'string',
+ 'phone' => 'string',
+ 'name' => 'string',
+ 'email' => 'string',
+ 'wechat' => 'string',
+ 'qq' => 'string',
+ 'desc' => 'string',
+ 'sort' => 'int',
+ 'is_open' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ * 查看列表数据
+ * @param int $page 分页页码
+ * @param int $pageSize 分页类目数量
+ * @param array $field 需要输入的字段,默认为全部输出,筛选表字段
+ * @param array $vague 需要进行模糊查询的字段,如: a like %a%
+ * @param array $focus 精确搜索条件,如a=1,b=2这种精确等于某个值的
+ * @param array $order 排序字段,如:['id'=>'desc','sort'=>'desc']
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getIndexList(int $page,int $pageSize,array $field = [], array $vague = [],array $focus = [],array $order = []):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($fields,$focus) {
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ })->where(function($query) use ($fields,$vague) {
+ //模糊查询
+ if (!empty($vague)) {
+ $query->whereOr('phone','like',"%".$vague['keyword']."%");
+ $query->whereOr('name','like',"%".$vague['keyword']."%");
+ $query->whereOr('wechat','like',"%".$vague['keyword']."%");
+ $query->whereOr('qq','like',"%".$vague['keyword']."%");
+ $query->whereOr('email','like',"%".$vague['keyword']."%");
+ }
+ })->order($order);
+ //判断是否需要分页
+ if (0 == $page || 0 == $pageSize) {
+ //不需要分页
+ return $collection->select()->toArray();
+ } else {
+ //需要分布
+ $totalNum = $collection->count();
+ $data = $collection->page($page)->limit($pageSize)->select()->toArray();;
+ return ['count'=>$totalNum,'data'=>$data];
+ }
+ }
+
+
+ /**
+ * 通过ID获取数据
+ * @param $ids
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getExportData($ids): array
+ {
+ $result = $this->whereIn($this->pk,$ids['ids'])->order('create_time','desc')->select()->toArray();
+ foreach ($result as &$item){
+ $item['platform_id'] = $this->getPlatformName($item['platform_id']);
+ $item['language_id'] = $item['site_id'] = $this->getLanguageName($item['site_id']);
+ $item['country_id'] = '中国';
+ $item['province_id'] = $this->getAreaNameById($item['province_id']);
+ $item['city_id'] = $this->getAreaNameById($item['city_id']);
+ $item['is_open'] = $item['is_open'] == 0 ? '同意同类厂家查看,以便获得更多产品代理机会' : '同意意向厂家查看';
+ unset($item['area']);
+ unset($item['qq']);
+ unset($item['sort']);
+ unset($item['update_time']);
+ unset($item['email']);
+ }
+ return $result;
+ }
+}
diff --git a/app/api/model/Join.php b/app/api/model/Join.php
new file mode 100644
index 0000000..fbddbe4
--- /dev/null
+++ b/app/api/model/Join.php
@@ -0,0 +1,97 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'join_type_id' => 'int',
+ 'title' => 'string',
+ 'brief' => 'string',
+ 'desc' => 'string',
+ 'thumb' => 'string',
+ 'url' => 'string',
+ 'meta_title' => 'string',
+ 'keywords' => 'string',
+ 'detail' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_outer_chain' => 'int',
+ 'is_on_index' => 'int',
+ 'click_num' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ *
+ */
+ public function JoinType():\think\model\relation\HasOne
+ {
+ return $this->hasOne(JoinType::class,'id','join_type_id')->bind(['join_type_name'=>'name']);
+ }
+
+ /**
+ */
+ public function languageName():\think\model\relation\HasOne
+ {
+ return $this->hasOne(Language::class,'id','site_id')->bind(['language_name'=>'name']);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int) $data['size'])->page((int)$data['page'])->order($sort)->with(['JoinType','languageName'])->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->with(['JoinType','languageName'])->select()->toArray();
+ }
+ }
+}
diff --git a/app/api/model/JoinType.php b/app/api/model/JoinType.php
new file mode 100644
index 0000000..328d8d8
--- /dev/null
+++ b/app/api/model/JoinType.php
@@ -0,0 +1,105 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * article分类与article表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getArticle()
+ {
+ return $this->hasMany(Join::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getArticleData($data):array
+ {
+ $article = $this->find($data['id']);
+ if (!empty($article)) {
+ return $article->getArticle()->select()->toArray();
+ }
+ return [];
+ }
+}
diff --git a/app/api/model/Language.php b/app/api/model/Language.php
new file mode 100644
index 0000000..cdac461
--- /dev/null
+++ b/app/api/model/Language.php
@@ -0,0 +1,37 @@
+ 'int',
+ 'name' => 'string',
+ 'code' => 'string',
+ 'icon' => 'string',
+ 'locale' => 'string',
+ 'coin' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ * 查找语言包是否被使用
+ * @param $id
+ * @return array|\think\Model|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLanguageUse($id)
+ {
+ return Platform::where('language_id',$id)->find();
+ }
+}
diff --git a/app/api/model/LogVisit.php b/app/api/model/LogVisit.php
new file mode 100644
index 0000000..e742ed0
--- /dev/null
+++ b/app/api/model/LogVisit.php
@@ -0,0 +1,51 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'admin_id' => 'int',
+ 'admin_name' => 'string',
+ 'url' => 'string',
+ 'params' => 'string',
+ 'controller' => 'string',
+ 'action' => 'string',
+ 'ip' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+
+ /**
+ * 写入日志
+ * @param $url
+ * @param $params
+ * @param $controller
+ * @param $action
+ * @param $admin_id
+ * @param $admin_name
+ * @param $platformId
+ * @return bool
+ */
+ public function log($url, $params, $controller, $action,$admin_id, $admin_name,$platformId)
+ {
+ $insert_data = [
+ 'url' => $url,
+ 'params' => $params,
+ 'controller' => $controller,
+ 'action' => $action,
+ 'admin_id' => $admin_id?:0,
+ 'admin_name' => $admin_name?:'',
+ 'ip' => get_client_ip(),
+ 'platform_id' => $platformId?:0,
+ 'create_time' => time()
+ ];
+ return $this->save($insert_data);
+ }
+}
diff --git a/app/api/model/Navigator.php b/app/api/model/Navigator.php
new file mode 100644
index 0000000..94fa24a
--- /dev/null
+++ b/app/api/model/Navigator.php
@@ -0,0 +1,119 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'pid' => 'int',
+ 'name' => 'string',
+ 'desc' => 'string',
+ 'icon' => 'string',
+ 'url' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_top' => 'int',
+ 'is_foot' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+
+ /**
+ * 查询子项
+ * @param $id
+ * @return int
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ private function getPidData($id):int
+ {
+ $result = $this->where('pid',$id)->find();
+ if ($result) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->select()->toArray();
+ foreach ($resData as $key => $item) {
+ if (1 === $this->getPidData($item['id'])) {
+ $resData[$key]['is_gray'] = 1;
+ } else {
+ $resData[$key]['is_gray'] = 0;
+ }
+ }
+ return $resData;
+ }
+ }
+
+ /**
+ * 判断导航栏是否有子类
+ * @param $id
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getNavigatorIsInUse($id):bool
+ {
+ $result = $this->where('pid',$id['id'])->find();
+ return (bool) $result;
+ }
+
+
+
+}
diff --git a/app/api/model/News.php b/app/api/model/News.php
new file mode 100644
index 0000000..671e4e6
--- /dev/null
+++ b/app/api/model/News.php
@@ -0,0 +1,97 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'news_type_id' => 'int',
+ 'title' => 'string',
+ 'brief' => 'string',
+ 'desc' => 'string',
+ 'thumb' => 'string',
+ 'url' => 'string',
+ 'meta_title' => 'string',
+ 'keywords' => 'string',
+ 'detail' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_outer_chain' => 'int',
+ 'is_on_index' => 'int',
+ 'click_num' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ *
+ */
+ public function NewsType():\think\model\relation\HasOne
+ {
+ return $this->hasOne(NewsType::class,'id','news_type_id')->bind(['news_type_name'=>'name']);
+ }
+
+ /**
+ */
+ public function languageName():\think\model\relation\HasOne
+ {
+ return $this->hasOne(Language::class,'id','site_id')->bind(['language_name'=>'name']);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int) $data['size'])->page((int)$data['page'])->order($sort)->with(['NewsType','languageName'])->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->with(['NewsType','languageName'])->select()->toArray();
+ }
+ }
+}
diff --git a/app/api/model/NewsType.php b/app/api/model/NewsType.php
new file mode 100644
index 0000000..6511070
--- /dev/null
+++ b/app/api/model/NewsType.php
@@ -0,0 +1,105 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * article分类与article表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getArticle()
+ {
+ return $this->hasMany(News::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getArticleData($data):array
+ {
+ $article = $this->find($data['id']);
+ if (!empty($article)) {
+ return $article->getArticle()->select()->toArray();
+ }
+ return [];
+ }
+}
diff --git a/app/api/model/Platform.php b/app/api/model/Platform.php
new file mode 100644
index 0000000..f366b06
--- /dev/null
+++ b/app/api/model/Platform.php
@@ -0,0 +1,279 @@
+ 'int',
+ 'vi_color1' => 'string',
+ 'vi_color2' => 'string',
+ 'vi_color3' => 'string',
+ 'language_id' => 'int',
+ 'currency_id' => 'int',
+ 'name' => 'string',
+ 'desc' => 'string',
+ 'icon' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+ /**
+ * 平台语言包关联模型
+ */
+ public function PlatformLanguage():\think\model\relation\HasMany
+ {
+ return $this->hasMany(PlatformLanguage::class);
+ }
+
+ /**
+ * 平台币种关联模型
+ */
+ public function PlatformCoin():\think\model\relation\HasMany
+ {
+ return $this->hasMany(PlatformCoin::class);
+ }
+
+ /**
+ * 通过平台ID查询平台有没有被使用
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function hasUserPlatform($data):array
+ {
+ return Site::where('platform_id',$data['id'])->select()->toArray();
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->whereLike($key,'%'.$item.'%');
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->with(['PlatformLanguage'=>function($query) {
+ $query->with(['getLanguage'=>function ($query) {
+ $query->field(['id','name']);
+ }]);
+ },'PlatformCoin'=>function($query) {
+ $query->with(['getCoin'=>function ($query) {
+ $query->field(['id','name']);
+ }]);
+ }])->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_name'] = $this->getLanguageName($item['language_id']);
+ $page[$key]['currency_name'] = $this->getLanguageName($item['currency_id']);
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $this->where(function ($query) use ($data,$fields) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ } else {
+ $query->where(1);
+ }
+ })->with(['PlatformLanguage'=>function($query) {
+ $query->with(['getLanguage'=>function ($query) {
+ $query->field(['id','name']);
+ }]);
+ },'PlatformCoin'=>function($query) {
+ $query->with(['getCoin'=>function ($query) {
+ $query->field(['id','name']);
+ }]);
+ }])->select()->toArray();
+
+ foreach ($resData as $key => $item) {
+ $resData[$key]['language_name'] = $this->getLanguageName($item['language_id']);
+ $resData[$key]['currency_name'] = $this->getCoinName($item['currency_id']);
+ }
+
+ return $resData;
+ }
+
+
+ }
+
+ /**
+ * 新增数据
+ * @param array $data
+ * @return bool
+ */
+ public function addData(array $data):bool
+ {
+ unset($data['id']);
+ $platform = $this->create($data);
+ if ($platform) {
+ //处理数据结构
+ foreach ($data['platform_language'] as $k => $value) {
+ $data['platform_language'][$k]['platform_id'] = $platform->id;
+ }
+
+ foreach ($data['platform_coin'] as $k => $value) {
+ $data['platform_coin'][$k]['platform_id'] = $platform->id;
+ }
+ //模型关联新增
+ $result = $platform->PlatformLanguage()->saveAll($data['platform_language']);
+ $result1 = $platform->PlatformCoin()->saveAll($data['platform_coin']);
+
+ return $result && $result1;
+ }
+ return false;
+
+ }
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ $platform = $this->find($data['id'])->toArray();
+ if ($platform) {
+ $platform['platform_language'] = $this->PlatformLanguage()->where('platform_id',$data['id'])->select()->toArray();
+ $platform['platform_coin'] = $this->PlatformCoin()->where('platform_id',$data['id'])->select()->toArray();
+ return $platform;
+ }
+ return [];
+
+ }
+
+ /**
+ * 编辑数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function editData(array $data):bool
+ {
+ $this->startTrans();
+ try {
+ $platform = $this->find($data['id']);
+ if ($platform) {
+ $result1 = $platform->save($data);
+ //先将原先的全部删除
+ $result2 = $platform->PlatformLanguage->delete();
+ $result3 = $platform->PlatformCoin->delete();
+ $result = false;
+ if ($result1 && $result2 && $result3) {
+ //处理数据结构
+ foreach ($data['platform_language'] as $k => $value) {
+ $data[$k]['platform_language'] = $data['id'];
+ }
+
+ //处理数据结构
+ foreach ($data['platform_coin'] as $k => $value) {
+ $data[$k]['platform_coin'] = $data['id'];
+ }
+ //新增
+ $result4 = $platform->PlatformLanguage()->saveAll($data['platform_language']);
+ $result5 = $platform->PlatformCoin()->saveAll($data['platform_coin']);
+ $result = $result4 && $result5;
+ }
+// return $result;
+ }
+ $this->commit();
+ return true;
+ } catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 删除数据
+ * @param array $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData(array $data):bool
+ {
+ $platform = $this->find($data['id']);
+ if ($platform) {
+ $result1 = $platform->delete();
+
+ //先将原先的全部删除
+ $result2 = $platform->PlatformLanguage->delete();;
+ $result3 = $platform->PlatformCoin->delete();;
+ return $result1 && $result2 && $result3;
+ }
+ return false;
+ }
+
+ /**
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getPlatformLanguage($data):array
+ {
+ return $this->where('id',$data)->with(['PlatformLanguage','PlatformCoin'])->select()->toArray();
+ }
+
+
+ /**
+ * @param $field
+ * @param $status
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLanguageList($field,$status):array
+ {
+ return Language::field($field)->where($status)->select()->toArray();
+ }
+}
\ No newline at end of file
diff --git a/app/api/model/PlatformCoin.php b/app/api/model/PlatformCoin.php
new file mode 100644
index 0000000..237150f
--- /dev/null
+++ b/app/api/model/PlatformCoin.php
@@ -0,0 +1,25 @@
+'int',
+ 'currency_id' =>'int',
+ 'platform_id' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 平台-币种关联模型
+ * @return \think\model\relation\BelongsTo
+ */
+ public function getCoin()
+ {
+ return $this->belongsTo(Currency::class,'currency_id','id');
+ }
+}
diff --git a/app/api/model/PlatformLanguage.php b/app/api/model/PlatformLanguage.php
new file mode 100644
index 0000000..4c58713
--- /dev/null
+++ b/app/api/model/PlatformLanguage.php
@@ -0,0 +1,27 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 平台-语言包关联模型
+ * @return \think\model\relation\BelongsTo
+ */
+ public function getLanguage()
+ {
+ return $this->belongsTo(Language::class);
+ }
+}
diff --git a/app/api/model/Question.php b/app/api/model/Question.php
new file mode 100644
index 0000000..40c08ff
--- /dev/null
+++ b/app/api/model/Question.php
@@ -0,0 +1,222 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'area_id' => 'int',
+ 'country_id' => 'int',
+ 'name' => 'string',
+ 'email' => 'string',
+ 'phone' => 'string',
+ 'order_sn' => 'string',
+ 'product_model' => 'string',
+ 'os' => 'string',
+ 'desc' => 'string',
+ 'is_done' => 'int',
+ 'is_send_email' => 'int',
+ 'is_send_status' => 'int',
+ 'send_time' => 'int',
+ 'send_details' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ * 反馈附件关联
+ * @return \think\model\relation\HasMany
+ */
+ public function QuestionAttachment()
+ {
+ return $this->hasMany(QuestionAttachment::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList($data,$simple = null,$focus = null,$sort = null,$field = null)
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $lang = Language::find($data['site_id']);
+ if (!empty($lang)) {
+ if (strtolower($lang['code']) == 'zh-cn' || strtolower($lang['code']) == 'zh_cn') {
+ $page[$key]['country_name'] = '中国';
+ } else {
+ $page[$key]['country_name'] = $this->getCountryName($item['country_id']);
+ }
+ }
+
+ $page[$key]['is_done_name'] = $item['is_done'] == 0 ? '未解决': '已解决';
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['country_name'] = $this->getCountryName($item['country_id']);
+ $page[$key]['is_done_name'] = $item['is_done'] == 0 ? '未解决': '已解决';
+ }
+ }
+ return $page;
+ }
+ }
+
+ /**
+ * 新增数据
+ * @param $data
+ * @return bool|void
+ */
+ public function addData($data)
+ {
+ $this->startTrans();
+ $question = $this->create($data);
+ //处理数据结构
+ foreach ($data['question_attachment'] as $k => $value) {
+ $value['question_id'] = $question->id;
+ }
+ //模型关联新增
+ $result = $question->QuestionAttachment()->saveAll($data['question_attachment']);
+ if ($result && $question) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 获取详情
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo($data)
+ {
+ $question = $this->find($data['id']);
+ $question['question_attachment'] = $this->QuestionAttachment()->where('question_id',$data['id'])->select()->toArray();
+ if (!empty($question['question_attachment'])) {
+ $newAttach = [];
+ foreach ($question['question_attachment'] as $key1 => $value1) {
+ $newAttach[$key1]['name'] = basename($value1['attach']);
+// $newAttach[$key1]['url'] = Env::get('QINIU.cdn').$value1['image'];
+ $newAttach[$key1]['url'] = $value1['attach'];
+ }
+ $question['question_attachment'] = $newAttach;
+ }
+ return $question;
+ }
+
+// /**
+// * 编辑数据
+// * @param $data
+// * @return bool
+// * @throws \think\db\exception\DataNotFoundException
+// * @throws \think\db\exception\DbException
+// * @throws \think\db\exception\ModelNotFoundException
+// */
+// public function editData($data)
+// {
+// $question = $this->find($data['id']);
+// $result1 = $question->save($data);
+// //先将原先的全部删除
+// $result2 = $question->QuestionAttachment->delete();
+// $result = false;
+// if ($result1 && $result2) {
+// //处理数据结构
+// $newData = [];
+// foreach ($data['question_attachment'] as $key => $value) {
+// $newData[$key]['question_id'] = $data['id'];
+// $newData[$key]['attach'] = $value['url'];
+// }
+// $data['question_attachment'] = $newData;
+// //新增
+// $result = $question->QuestionAttachment()->saveAll($data['question_attachment']);
+// }
+// return $result;
+// }
+
+ /**
+ * 删除数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData($data)
+ {
+ $this->startTrans();
+ $question = $this->find($data['id']);
+ $result1 = $question->delete();
+ //先将原先的全部删除
+ $result2 = $question->QuestionAttachment->delete();;
+ if ($result1 && $result2) {
+ $this->commit();
+ return true;
+ } else {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 解决-未解决
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function isDone($data)
+ {
+ $question = $this->find($data['id']);
+ return $question->save($data);
+ }
+}
diff --git a/app/api/model/QuestionAttachment.php b/app/api/model/QuestionAttachment.php
new file mode 100644
index 0000000..fd02bf0
--- /dev/null
+++ b/app/api/model/QuestionAttachment.php
@@ -0,0 +1,27 @@
+'int',
+ 'question_id' =>'int',
+ 'attach' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * 附件-问题关联表
+ * @return \think\model\relation\BelongsTo
+ */
+ public function getQuestion()
+ {
+ return $this->belongsTo(Question::class);
+ }
+}
diff --git a/app/api/model/Resource.php b/app/api/model/Resource.php
new file mode 100644
index 0000000..9736af3
--- /dev/null
+++ b/app/api/model/Resource.php
@@ -0,0 +1,98 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'resource_type_id' => 'int',
+ 'title' => 'string',
+ 's_title' => 'string',
+ 'brief' => 'string',
+ 'desc' => 'string',
+ 'thumb' => 'string',
+ 'url' => 'string',
+ 'meta_title' => 'string',
+ 'keywords' => 'string',
+ 'detail' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_outer_chain' => 'int',
+ 'is_on_index' => 'int',
+ 'click_num' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ *
+ */
+ public function ResourceType():\think\model\relation\HasOne
+ {
+ return $this->hasOne(ResourceType::class,'id','resource_type_id')->bind(['resource_type_name'=>'name']);
+ }
+
+ /**
+ */
+ public function languageName():\think\model\relation\HasOne
+ {
+ return $this->hasOne(Language::class,'id','site_id')->bind(['language_name'=>'name']);
+ }
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int) $data['size'])->page((int)$data['page'])->order($sort)->with(['ResourceType','languageName'])->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->with(['ResourceType','languageName'])->select()->toArray();
+ }
+ }
+}
diff --git a/app/api/model/ResourceType.php b/app/api/model/ResourceType.php
new file mode 100644
index 0000000..8951030
--- /dev/null
+++ b/app/api/model/ResourceType.php
@@ -0,0 +1,105 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+ /**
+ * article分类与article表模型
+ * @return \think\model\relation\HasMany
+ */
+ public function getArticle()
+ {
+ return $this->hasMany(Resource::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field=null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $page = $collection->order($sort)->select()->toArray();
+ foreach ($page as $key => $item) {
+ $page[$key]['language_id'] = $item['site_id'];
+ }
+ return $page;
+
+ }
+ }
+
+ /**
+ * 获取对应分类下的文章内容
+ * @param $data
+ * @return mixed
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getArticleData($data):array
+ {
+ $article = $this->find($data['id']);
+ if (!empty($article)) {
+ return $article->getArticle()->select()->toArray();
+ }
+ return [];
+ }
+}
diff --git a/app/api/model/Role.php b/app/api/model/Role.php
new file mode 100644
index 0000000..76da1c6
--- /dev/null
+++ b/app/api/model/Role.php
@@ -0,0 +1,49 @@
+ 'int',
+ 'name' => 'string',
+ 'desc' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+
+ protected $disuse = [
+ 'desc'
+ ];
+
+
+ /**
+ * 角色菜单关联
+ * @return \think\model\relation\HasMany
+ */
+ public function RoleToMenu()
+ {
+ return $this->hasMany(RoleToMenu::class);
+ }
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo(array $data):array
+ {
+ $result = $this->find($data['role_id']);
+ return $result ? $result->toArray() : [];
+ }
+
+}
diff --git a/app/api/model/Site.php b/app/api/model/Site.php
new file mode 100644
index 0000000..c448768
--- /dev/null
+++ b/app/api/model/Site.php
@@ -0,0 +1,141 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'currency_id' =>'int',
+ 'domain' =>'string',
+ 'app_id' =>'string',
+ 'app_key' =>'string',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (isset($data['platform_id'])) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->whereLike($key,'%'.$item.'%');
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $lang = Language::find($item['language_id']);
+ $page[$key]['language_name'] = $lang ? $lang->toArray()['name']: "";
+ $page[$key]['currency_name'] = $this->getLanguageName($item['currency_id']);
+ $page[$key]['platform_name'] = $this->getPlatformName($item['platform_id']);
+ }
+ }
+
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->field(['id','platform_id','language_id','currency_id','domain','status'])->select()->toArray();
+ if (!empty($resData)) {
+ foreach ($resData as $key => $item) {
+ $lang = Language::find($item['language_id']);
+ $resData[$key]['language_name'] = $lang ? $lang->toArray()['name']: "";
+ $resData[$key]['currency_name'] = $this->getCoinName($item['currency_id']);
+ $resData[$key]['platform_name'] = $this->getPlatformName($item['platform_id']);
+ }
+ }
+
+ return $resData;
+ }
+ }
+
+ /**
+ * 通过品牌ID与语言包ID获取是否存在相同的数据。
+ * @param $data
+ * @return array
+ * @throws DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSiteData($data):array
+ {
+ return $this->where(['platform_id'=>$data['platform_id'],'language_id'=>$data['language_id']])->column('id');
+ }
+
+
+ /**
+ * 通过品牌ID判断站点是否存在
+ * @param $platformId
+ * @return bool
+ * @throws DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSiteInfoByPlatformId($platformId):bool
+ {
+ $result = $this->where(['platform_id'=>$platformId])->select()->toArray();
+ if (!empty($result)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 删除数据
+ * @param array $data
+ * @return bool
+ * @throws DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData(array $data):bool
+ {
+ $result = $this->find($data['id']);
+ if ($result) {
+ Cache::set($result['app_id'],null);
+ return $result->delete();
+ }
+ return false;
+ }
+}
diff --git a/app/api/model/SoftManual.php b/app/api/model/SoftManual.php
new file mode 100644
index 0000000..5eefd7b
--- /dev/null
+++ b/app/api/model/SoftManual.php
@@ -0,0 +1,230 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'language_id' => 'int',
+ 'site_id' => 'int',
+ 'file_type_id' => 'int',
+ 'name' => 'string',
+ 'image' => 'string',
+ 'introduce' => 'string',
+ 'file_name' => 'string',
+ 'btn_tips' => 'string',
+ 'url' => 'string',
+ 'support' => 'string',
+ 'os' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'download_count'=> 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+ /**
+ * 驱动手册分表
+ * @return \think\model\relation\HasMany
+ */
+ public function softBtn()
+ {
+ return $this->hasMany(SoftManualBtn::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @param null $sort
+ * @param null $field
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList(array $data,$simple = null,$focus = null,$sort = null,$field = null):array
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->field($field)->where(function ($query) use ($data,$fields,$simple,$focus) {
+ if (in_array('platform_id',$fields)) {
+ $query->where('platform_id',$data['platform_id']);
+ }
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit((int)$data['size'])->page((int)$data['page'])->with('softBtn')->order($sort)->select()->toArray();
+ if (!empty($page)) {
+ foreach ($page as $key => $item) {
+ $page[$key]['file_type_name'] = $this->getFileTypeName($item['file_type_id']);
+ }
+ }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->with('softBtn')->select()->toArray();
+ if (!empty($resData)) {
+ foreach ($resData as $key => $item) {
+ $resData[$key]['file_type_name'] = $this->getFileTypeName($item['file_type_id']);
+ }
+ }
+ return $resData;
+ }
+ }
+
+ /**
+ * 新增数据
+ * @param $data
+ */
+ public function addData($data):bool
+ {
+ $this->startTrans();
+ try {
+ $soft = $this->create($data);
+ //处理数据结构
+ foreach ($data['softBtn'] as $key => $value) {
+ $data['softBtn'][$key]['soft_manual_id'] = $soft->id;
+ $data['softBtn'][$key]['btn_tips'] = $value['btn_tips'];
+ $data['softBtn'][$key]['url'] = $value['url'];
+ $data['softBtn'][$key]['file_name'] = $value['file_name'];
+ $data['softBtn'][$key]['md5'] = $value['md5'];
+ }
+ //模型关联新增
+ $soft->softBtn()->saveAll($data['softBtn']);
+ $this->commit();
+ return true;
+ } catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+
+ }
+
+ /**
+ * 获取详情
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo($data):array
+ {
+ $soft = $this->find($data['id']);
+ $soft['softBtn'] = $soft->softBtn()->select()->toArray();
+ if (empty($soft['softBtn'])) {
+ $soft['softBtn'] = [['name'=>'','url'=>'','md5'=>'']];
+ }
+ return $soft->toArray();
+ }
+
+ /**
+ * 编辑数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function editData($data):bool
+ {
+ $this->startTrans();
+ try {
+ $soft = $this->find($data['id']);
+ if ($soft) {
+ $result2 = $soft->softBtn->delete();
+ $result1 = $soft->save($data);
+ //先将原先的全部删除
+// $result = false;
+ if ($result1 && $result2) {
+ //处理数据结构
+ foreach ($data['softBtn'] as $key => $value) {
+ $data['softBtn'][$key]['soft_manual_id'] = $data['id'];
+ $data['softBtn'][$key]['btn_tips'] = $value['btn_tips'];
+ $data['softBtn'][$key]['url'] = $value['url'];
+ $data['softBtn'][$key]['file_name'] = $value['file_name'];
+ $data['softBtn'][$key]['md5'] = $value['md5'];
+ }
+ //新增
+ $result = $soft->softBtn()->saveAll($data['softBtn']);
+ }
+// return $result;
+ }
+ $this->commit();
+ return true;
+ } catch (\Exception $e) {
+ $this->rollback();
+ return false;
+ }
+ }
+
+ /**
+ * 删除数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData($data):bool
+ {
+ $soft = $this->find($data['id']);
+ $result1 = $soft->delete();
+ //先将原先的全部删除
+ $result2 = $soft->softBtn->delete();;
+ return $result1 && $result2;
+ }
+
+ /**
+ * 编辑排序
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function changeSort($data):bool
+ {
+ $result = $this->find($data['id']);
+ return $result && $result->save($data);
+ }
+
+ /**
+ * 查询文档驱动是否被引用
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSoftManualUsed($data)
+ {
+ $result = GoodsSoftManual::where('soft_manual_id',$data['id'])->find();
+ return (bool) $result;
+ }
+}
diff --git a/app/api/model/SoftManualBtn.php b/app/api/model/SoftManualBtn.php
new file mode 100644
index 0000000..4ce4f12
--- /dev/null
+++ b/app/api/model/SoftManualBtn.php
@@ -0,0 +1,20 @@
+ 'int',
+ 'soft_manual_id'=> 'int',
+ 'btn_tips' => 'string',
+ 'url' => 'string',
+ 'file_name' => 'string',
+ 'md5' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+}
diff --git a/app/api/model/SystemConfig.php b/app/api/model/SystemConfig.php
new file mode 100644
index 0000000..6532517
--- /dev/null
+++ b/app/api/model/SystemConfig.php
@@ -0,0 +1,26 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'type' =>'int',
+ 'page' =>'string',
+ 'pos' =>'string',
+ 'name' =>'string',
+ 'value' =>'string',
+ 'image' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int'
+ ];
+}
diff --git a/app/api/model/User.php b/app/api/model/User.php
new file mode 100644
index 0000000..fc2c51e
--- /dev/null
+++ b/app/api/model/User.php
@@ -0,0 +1,97 @@
+ 'int',
+ 'uc_id' => 'int',
+ 'admin_id' => 'int',
+ 'role_id' => 'int',
+ 'org_id' => 'int',
+ 'dept_id' => 'int',
+ 'staff_code' => 'string',
+ 'nickname' => 'string',
+ 'mobile' => 'string',
+ 'email' => 'string',
+ 'avatar' => 'string',
+ 'gender' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ 'signin_time' => 'int',
+ 'signin_ip' => 'string',
+ 'status' => 'int',
+ ];
+
+ /**
+ * 获取详情
+ * @param array $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo($data) : array
+ {
+ if (isset($data['admin_id'])) {
+ $result = $this->where('uc_id',$data['admin_id'])->find();
+ return $result ? $result->toArray() : [];
+ }
+ if (isset($data['uc_id'])) {
+ $result = $this->where('uc_id',$data['uc_id'])->find();
+ return $result ? $result->toArray() : [];
+ }
+ return [];
+ }
+
+
+ /**
+ * 通过角色ID,摘取对应菜单ID
+ * @param array $data
+ * @return array
+ */
+ public function getMenuList(array $data):array
+ {
+ return $this->getMenuListUserCode($data['staff_code']);
+ }
+
+ /**
+ * 获取角色名称
+ * @param $roleId
+ * @return array|\think\Model|null
+ */
+ public function getRolesName($roleId):string
+ {
+ $result = $this->getRoleDetailId($roleId);
+ return $result['role_name'] ?? '';
+ }
+
+
+ /**
+ * 查找菜单列表
+ * @param $arr
+ * @return array
+ */
+ public function getMenuSiderList($arr):array
+ {
+ $result = $this->getMenuListApp();
+ if(!empty($result)) {
+ $newData = [];
+ foreach ($result as $datum) {
+ if (in_array($datum['id'],$arr)) {
+ array_push($newData,$datum);
+ }
+ }
+ return $newData;
+ } else {
+ return [];
+ }
+ }
+
+}
diff --git a/app/api/model/Video.php b/app/api/model/Video.php
new file mode 100644
index 0000000..d9c6c6c
--- /dev/null
+++ b/app/api/model/Video.php
@@ -0,0 +1,24 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'site_id' => 'int',
+ 'name' => 'string',
+ 'image' => 'string',
+ 'url' => 'string',
+ 'is_top' => 'int',
+ 'sort' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+}
diff --git a/app/api/route/v1.php b/app/api/route/v1.php
new file mode 100644
index 0000000..058c19f
--- /dev/null
+++ b/app/api/route/v1.php
@@ -0,0 +1,431 @@
+
+ // +----------------------------------------------------------------------
+ //全局CDN链接,减少改变静态地址而打包前端代码
+ Route::group('v1',function () {
+ Route::group('cdn',function(){
+ Route::any('get_cdn_url','Base@getCDNUrl');
+ });
+
+ //后台登录模块路由
+ Route::group('auth',function() {
+ Route::post('login','Auth@login'); //登录路由
+ Route::post('info','Auth@info'); //已登录管理员信息
+ Route::post('all_info','Auth@allInfo'); //获取所有信息
+ Route::post('get_auth','Auth@getAuth'); //获取用户所有权限
+ Route::post('update_pwd','Auth@updatePwd'); //个人中心修改密码
+ Route::post('update_head_img','Auth@updateHeadImg'); //个人中心修改头像
+ Route::post('update_info','Auth@updateInfo'); //个人中心修改基本信息
+ });
+
+ //后台管理员模块路由组
+ Route::group('admin',function (){
+ Route::post('list','Admin@list');//管理员列表
+ Route::post('add','Admin@add');//新增管理员
+ Route::post('info','Admin@read');//获取管理员信息
+ Route::post('update','Admin@update');//修改管理信息
+ Route::post('forbidden','Admin@forbidden');//禁用
+ });
+
+ //后台菜单模块路由组
+ Route::group('menu', function () {
+ Route::post('list','Menu@tree');/*菜单列表结构*/
+ Route::post('get_menu_select_list','Menu@selectList');/*菜单仅查询列表结构*/
+ Route::post('get_menu_change_list','Menu@changeList');/*菜单可编辑列表结构*/
+ Route::post('info','Menu@read');/*菜单详情*/
+ Route::post('create','Menu@create');/*菜单新增*/
+ Route::post('update','Menu@update');/*菜单编辑*/
+ Route::post('upload','Menu@upload');/*菜单图标上传*/
+ Route::post('change_status','Menu@updateStatus');/*修改状态*/
+ Route::post('del','Menu@del');/*菜单删除*/
+ Route::post('sort','Menu@sort');/*菜单排序*/
+ });
+
+ //后台角色模块路由组
+ Route::group('role', function () {
+ Route::post('list','Role@index');/*列表*/
+ Route::post('info','Role@read');/*详情*/
+ Route::post('add','Role@create');/*新增*/
+ Route::post('update','Role@update');/*编辑*/
+ Route::post('del','Role@del');/*删除*/
+
+ Route::post('dis_auth_select','Role@distributeAuthForSelect');/*分配权限 */
+ Route::post('dis_auth_change','Role@distributeAuthForChange');/*分配权限 */
+ });
+
+ //后台站点模块路由组
+ Route::group('site', function () {
+ Route::post('list','Site@index');/*列表*/
+ Route::post('site_list','Site@siteIndex');/*列表*/
+ Route::post('create','Site@create');/*新增*/
+ Route::post('info','Site@read');/*更新*/
+ Route::post('update','Site@update');/*更新*/
+ Route::post('del','Site@del');/*删除*/
+ Route::post('change_status','Site@changeStatus');/*删除*/
+ Route::post('get_nav','Site@getNavigatorList');/*获取导航栏*/
+ });
+
+ //后台语言包模块路由组
+ Route::group('lang', function () {
+ Route::post('list','Language@index');/*列表*/
+ Route::post('create','Language@create');/*新增*/
+ Route::post('info','Language@read');/*更新*/
+ Route::post('update','Language@update');/*更新*/
+ Route::post('upload','Language@upload');/*上传图标*/
+ Route::post('del','Language@del');/*删除*/
+ Route::post('change_status','Language@changeStatus');/*启用禁用*/
+ });
+
+ //后台平台模块路由组
+ Route::group('plat', function () {
+ Route::post('list','Platform@index');/*列表*/
+ Route::post('lang_list','Platform@languageList');/*列表*/
+ Route::post('info','Platform@read');/*详情*/
+ Route::post('create','Platform@create');/*新增*/
+ Route::post('update','Platform@update');/*更新*/
+ Route::post('upload','Platform@upload');/*上传图标*/
+ Route::post('del','Platform@del');/*删除*/
+ });
+
+ //后台导航栏模块路由组
+ Route::group('nav', function () {
+ Route::post('list','Navigator@tree');/*列表*/
+ Route::post('top_list','Navigator@topTree');/*列表*/
+ Route::post('info','Navigator@read');/*列表*/
+ Route::post('create','Navigator@create');/*新增*/
+ Route::post('update','Navigator@update');/*更新*/
+ Route::post('upload','Navigator@upload');/*上传图标*/
+ Route::post('del','Navigator@del');/*删除*/
+ Route::post('change_status','Navigator@changeStatus');/*启用禁用*/
+ });
+
+ //后台国家模块路由组
+ Route::group('country', function () {
+ Route::post('list','Country@index');/*列表*/
+ Route::post('info','Country@read');/*详情*/
+ Route::post('create','Country@create');/*新增*/
+ Route::post('update','Country@update');/*更新*/
+ Route::post('upload','Country@upload');/*上传图标*/
+ Route::post('del','Country@del');/*删除*/
+ });
+
+ //后台用户反馈模块路由组
+ Route::group('question', function () {
+ Route::post('list','Question@index');/*列表*/
+ Route::post('info','Question@read');/*列表*/
+ Route::post('is_done','Question@isDone');/*列表*/
+ Route::post('create','Question@create');/*新增*/
+ Route::post('send_email','Question@sendEmail');/*新增*/
+ Route::post('check_email','Question@validateEmail');/*新增*/
+ // Route::post('update','Question@update');/*更新*/
+ // Route::post('upload','Question@upload');/*上传图标*/
+ Route::post('del','Question@del');/*删除*/
+ });
+
+ //后台手册文档模块路由组
+ Route::group('soft_manual', function () {
+ Route::post('list','SoftManual@index');/*列表*/
+ Route::post('info','SoftManual@read');/*列表*/
+ Route::post('create','SoftManual@create');/*新增*/
+ Route::post('update','SoftManual@update');/*更新*/
+ Route::post('upload','SoftManual@upload');/*上传图标*/
+ Route::post('upload_file','ImagesFile@uploadFile');/*上传图标*/
+ Route::post('check_file','ImagesFile@checkFile');/*上传图标*/
+ Route::post('change_sort','SoftManual@changeSort');/*修改排序*/
+ Route::post('del','SoftManual@del');/*删除*/
+ Route::post('change_status','SoftManual@changeStatus');/*启用禁用*/
+ });
+
+ //后台评测文章模块路由组
+ Route::group('article', function () {
+ Route::post('list','Article@index');/*列表*/
+ Route::post('info','Article@read');/*列表*/
+ Route::post('create','Article@create');/*新增*/
+ Route::post('update','Article@update');/*更新*/
+ Route::post('upload','Article@upload');/*上传图标*/
+ Route::post('change_status','Article@changeStatus');/*上传图标*/
+ Route::post('del','Article@del');/*删除*/
+ });
+
+
+ //后台组织模块路由组
+ Route::group('org',function () {
+ Route::post('list','app\api\controller\Organization@list');
+ Route::post('info','app\api\controller\Organization@info');
+ Route::post('add','app\api\controller\Organization@add');
+ Route::post('edit','app\api\controller\Organization@edit');
+ Route::post('delete','app\api\controller\Organization@delete');
+ });
+
+ //后台商品分类模块路由组
+ Route::group('category', function () {
+ Route::post('list','GoodsCategory@tree');/*列表*/
+ Route::post('category_goods_list','GoodsCategory@categoryGoodsList');/*列表*/
+ Route::post('category_goods_info','GoodsCategory@categoryGoodsInfo');/*列表*/
+ Route::post('info','GoodsCategory@read');/*详情*/
+ Route::post('create','GoodsCategory@create');/*新增*/
+ Route::post('update','GoodsCategory@update');/*更新*/
+ Route::post('upload','GoodsCategory@upload');/*上传图标*/
+ Route::post('del','GoodsCategory@del');/*删除*/
+ Route::post('change_status','GoodsCategory@changeStatus');/*启用禁用*/
+ });
+
+ //后台商品分类模块路由组
+ Route::group('attr', function () {
+ Route::post('list','Attribute@index');/*列表*/
+ Route::post('info','Attribute@read');/*详情*/
+ Route::post('create','Attribute@create');/*新增*/
+ Route::post('update','Attribute@update');/*更新*/
+ Route::post('del','Attribute@del');/*删除*/
+ });
+
+ //后台商品模块路由组
+ Route::group('goods', function () {
+ Route::post('list','Goods@index');/*列表*/
+ Route::post('language_list','Goods@languageList');/*列表*/
+ Route::post('info','Goods@read');/*列表*/
+ Route::post('create','Goods@create');/*新增*/
+ Route::post('update','Goods@update');/*更新*/
+ Route::post('upload','Goods@upload');/*上传图标*/
+ Route::post('del','Goods@del');/*删除*/
+ Route::any('ue_upload','Goods@ueditorUpload');/*百度富文本上传*/
+ Route::post('change_status','Goods@changeStatus');/*删除*/
+ Route::post('sort','Goods@changeSort');/*排序*/
+ Route::post('batch_del','Goods@batchGoodsDel');/*批量删除*/
+ Route::post('batch_enable','Goods@batchGoodsEnable');/*批量删除*/
+ Route::post('batch_disable','Goods@batchGoodsDisable');/*批量删除*/
+ Route::post('batch_category_change','Goods@batchCategoryModify');/*批量修改分类*/
+ });
+
+ //后台文件类型路由组
+ Route::group('file_type', function () {
+ Route::post('list','FileType@index');/*列表*/
+ Route::post('sort','FileType@sort');/*列表*/
+ Route::post('create','FileType@create');/*新增*/
+ Route::post('update','FileType@update');/*更新*/
+ Route::post('del','FileType@del');/*删除*/
+ });
+
+ //后台评论路由组
+ Route::group('comment', function () {
+ Route::post('list','Comment@index');/*列表*/
+ Route::post('info','Comment@read');/*列表*/
+ Route::post('create','Comment@create');/*新增*/
+ Route::post('update','Comment@update');/*更新*/
+ Route::post('upload','Comment@upload');/*上传图标*/
+ Route::post('del','Comment@del');/*删除*/
+ });
+
+ //后台大量采购路由组
+ Route::group('bulk_buy', function () {
+ Route::post('list','BulkBuy@index');/*列表*/
+ Route::post('info','BulkBuy@read');/*列表*/
+ Route::post('create','BulkBuy@create');/*新增*/
+ Route::post('update','BulkBuy@update');/*更新*/
+ Route::post('upload','BulkBuy@upload');/*上传图标*/
+ Route::post('del','BulkBuy@del');/*删除*/
+ });
+
+ //后台广告模块路由组
+ Route::group('ad', function () {
+ Route::post('list','Advertisement@index');/*列表*/
+ Route::post('info','Advertisement@read');/*列表*/
+ Route::post('create','Advertisement@create');/*新增*/
+ Route::post('update','Advertisement@update');/*更新*/
+ Route::post('upload','Advertisement@upload');/*上传图标*/
+ Route::post('del','Advertisement@del');/*删除*/
+ });
+
+ //后台广告位模块路由组
+ Route::group('ad_space', function () {
+ Route::post('list','AdvertiseSpace@index');/*列表*/
+ Route::post('invalid_list','AdvertiseSpace@invalidList');/*列表*/
+ Route::post('info','AdvertiseSpace@read');/*列表*/
+ Route::post('create','AdvertiseSpace@create');/*新增*/
+ Route::post('update','AdvertiseSpace@update');/*更新*/
+ Route::post('upload','AdvertiseSpace@upload');/*上传图标*/
+ Route::post('del','AdvertiseSpace@del');/*删除*/
+ });
+
+ //后台广告所属页模块路由组
+ Route::group('ad_page', function () {
+ Route::post('list','AdvertisePage@index');/*列表*/
+ Route::post('create','AdvertisePage@create');/*新增*/
+ Route::post('update','AdvertisePage@update');/*更新*/
+ Route::post('del','AdvertisePage@del');/*删除*/
+ });
+
+ //后台优惠券模块路由组
+ Route::group('coupon', function () {
+ Route::post('list','GoodsCoupon@index');/*列表*/
+ Route::post('create','GoodsCoupon@create');/*新增*/
+ });
+
+ //后台优惠券领取记录模块路由组
+ Route::group('coupon_subscribe', function () {
+ Route::post('list','CouponSubscribe@index');/*列表*/
+ Route::post('create','CouponSubscribe@create');/*新增*/
+ Route::post('del','CouponSubscribe@del');/*删除*/
+ });
+
+ //后台币种模块路由组
+ Route::group('currency', function () {
+ Route::post('list','Currency@index');/*列表*/
+ Route::post('info','Currency@read');/*列表*/
+ Route::post('create','Currency@create');/*新增*/
+ Route::post('update','Currency@update');/*更新*/
+ Route::post('del','Currency@del');/*删除*/
+ Route::post('change_status','Currency@changeStatus');/*删除*/
+ });
+
+ //后台faq模块路由组
+ Route::group('faq', function () {
+ Route::post('list','Faq@index');/*列表*/
+ Route::post('info','Faq@read');/*列表*/
+ Route::post('create','Faq@create');/*新增*/
+ Route::post('update','Faq@update');/*更新*/
+ Route::post('del','Faq@del');/*删除*/
+ });
+
+ //后台faq模块路由组
+ Route::group('faq_type', function () {
+ Route::post('list','FaqType@index');/*列表*/
+ Route::post('create','FaqType@create');/*新增*/
+ Route::post('update','FaqType@update');/*更新*/
+ Route::post('del','FaqType@del');/*删除*/
+ });
+
+ //后台广告所属页模块路由组
+ Route::group('log', function () {
+ Route::post('list','LogVisit@index');/*列表*/
+ Route::post('info','LogVisit@read');/*列表*/
+ Route::post('del','LogVisit@del');/*删除*/
+ });
+
+ //后台文章类型路由组
+ Route::group('article_type', function () {
+ Route::post('list','ArticleType@index');/*列表*/
+ Route::post('update','ArticleType@update');/*更新*/
+ Route::post('del','ArticleType@del');/*删除*/
+ });
+
+ //后台文章模块路由组
+ Route::group('article', function () {
+ Route::post('list','Article@index');/*列表*/
+ Route::post('info','Article@read');/*列表*/
+ Route::post('create','Article@create');/*新增*/
+ Route::post('update','Article@update');/*更新*/
+ Route::post('del','Article@del');/*删除*/
+ });
+
+ //后台品牌矩阵类型路由组
+ Route::group('brand_type', function () {
+ Route::post('list','BrandType@index');/*列表*/
+ Route::post('update','BrandType@update');/*更新*/
+ Route::post('del','BrandType@del');/*删除*/
+ });
+
+ //后台品牌矩阵模块路由组
+ Route::group('brand', function () {
+ Route::post('list','Brand@index');/*列表*/
+ Route::post('info','Brand@read');/*列表*/
+ Route::post('create','Brand@create');/*新增*/
+ Route::post('update','Brand@update');/*更新*/
+ Route::post('del','Brand@del');/*删除*/
+ Route::post('upload','Brand@upload');/*上传*/
+ Route::post('change_status','Brand@changeStatus');/*修改状态*/
+ });
+ //后台资源中心类型路由组
+ Route::group('resource_type', function () {
+ Route::post('list','ResourceType@index');/*列表*/
+ Route::post('update','ResourceType@update');/*更新*/
+ Route::post('del','ResourceType@del');/*删除*/
+ });
+
+ //后台资源中心模块路由组
+ Route::group('resource', function () {
+ Route::post('list','Resource@index');/*列表*/
+ Route::post('info','Resource@read');/*列表*/
+ Route::post('create','Resource@create');/*新增*/
+ Route::post('update','Resource@update');/*更新*/
+ Route::post('del','Resource@del');/*删除*/
+ Route::post('upload','Resource@upload');/*上传*/
+ Route::post('change_status','Resource@changeStatus');/*修改状态*/
+ });
+ //后台新闻动态类型路由组
+ Route::group('news_type', function () {
+ Route::post('list','NewsType@index');/*列表*/
+ Route::post('update','NewsType@update');/*更新*/
+ Route::post('del','NewsType@del');/*删除*/
+ });
+
+ //后台新闻动态模块路由组
+ Route::group('news', function () {
+ Route::post('list','News@index');/*列表*/
+ Route::post('info','News@read');/*列表*/
+ Route::post('create','News@create');/*新增*/
+ Route::post('update','News@update');/*更新*/
+ Route::post('del','News@del');/*删除*/
+ Route::post('upload','News@upload');/*上传*/
+ Route::post('change_status','News@changeStatus');/*修改状态*/
+ });
+ //后台加入我们类型路由组
+ Route::group('join_type', function () {
+ Route::post('list','JoinType@index');/*列表*/
+ Route::post('update','JoinType@update');/*更新*/
+ Route::post('del','JoinType@del');/*删除*/
+ });
+ //后台新闻动态模块路由组
+ Route::group('video', function () {
+ Route::post('list','Video@index');/*列表*/
+ Route::post('info','Video@read');/*列表*/
+ Route::post('create','Video@create');/*新增*/
+ Route::post('update','Video@update');/*更新*/
+ Route::post('del','Video@del');/*删除*/
+ Route::post('upload','Video@upload');/*上传*/
+ Route::post('change_status','Video@changeStatus');/*修改状态*/
+ });
+ //后台加入我们模块路由组
+ Route::group('join', function () {
+ Route::post('list','Join@index');/*列表*/
+ Route::post('info','Join@read');/*列表*/
+ Route::post('create','Join@create');/*新增*/
+ Route::post('update','Join@update');/*更新*/
+ Route::post('del','Join@del');/*删除*/
+ Route::post('upload','Join@upload');/*上传*/
+ Route::post('change_status','Join@changeStatus');/*修改状态*/
+ });
+ //
+ Route::group('config', function () {
+ Route::post('list','SystemConfig@index');/*列表*/
+ Route::post('info','SystemConfig@read');/*详情*/
+ Route::post('create','SystemConfig@create');/*新增*/
+ Route::post('update','SystemConfig@update');/*更新*/
+ Route::post('upload','SystemConfig@upload');/*上传*/
+ Route::post('del','SystemConfig@del');/*删除*/
+ });
+
+
+ })->prefix('app\\api\\controller\\v1\\')->middleware([
+ app\api\middleware\Auth::class,
+ app\api\middleware\LogVisit::class
+ ]),
+
+ // +----------------------------------------------------------------------
+ // | 后台管理系统路由 - 结束
+ // +----------------------------------------------------------------------
+ // | Author: yulinzhihou
+ // +----------------------------------------------------------------------
+
+ //全局错误路由
+ Route::miss(function() {
+ return json(["status"=>500,'message'=>'请使用正确的接口地址和参数','route'=>request()->url(),'create_time'=>time(),'date_time'=>date("Y-m-d H:i:s",time())]);
+ })
+];
diff --git a/app/api/validate/Admin.php b/app/api/validate/Admin.php
new file mode 100644
index 0000000..da80543
--- /dev/null
+++ b/app/api/validate/Admin.php
@@ -0,0 +1,43 @@
+ ['require', 'length:2,20'],
+ 'password' => ['require', 'length:0,32'],
+ 'mobile' => ['require', 'mobile'],
+ 'id' => ['require','integer','gt:0']
+ ];
+
+
+ /**
+ * 验证器错误提示信息汇总
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * 验证器验证场景
+ * @var array
+ */
+ protected $scene = [
+ 'login' => ['username','password'],
+ 'add' => ['username','password', 'mobile'],
+ 'update' => ['id'],
+ 'forbidden' => ['id']
+ ];
+
+
+}
diff --git a/app/api/validate/AdvertisePage.php b/app/api/validate/AdvertisePage.php
new file mode 100644
index 0000000..db1e23c
--- /dev/null
+++ b/app/api/validate/AdvertisePage.php
@@ -0,0 +1,48 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'name|广告页名称' => ['length:1,30','require','unique:advertise_page,name^site_id^platform_id'],
+ 'sort|排序' => ['between:1,255'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * @var
+ */
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['site_id','name'],
+ 'update' => ['id','name'],
+ 'batchCreate' => ['site_id','name'],
+ 'batchUpdate' => ['id','name'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/AdvertiseSpace.php b/app/api/validate/AdvertiseSpace.php
new file mode 100644
index 0000000..6c7cceb
--- /dev/null
+++ b/app/api/validate/AdvertiseSpace.php
@@ -0,0 +1,52 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言版本' => ['integer','gt:0'],
+ 'name|广告位名称' => ['length:1,50','require','unique:advertise_space,name^site_id^platform_id'],
+ 'sort|排序' => ['between:1,255'],
+ 'advertise_page_id|所属页面'=>['integer','gt:0'],
+ 'max_num|数量上限' => ['integer','between:1,15'],
+ 'width|尺寸要求-宽度' => ['integer','gt:0','elt:1920'],
+ 'height|尺寸要求-高度' => ['integer','gt:0','elt:1920'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','advertise_page_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','advertise_page_id','name','max_num','width','height','sort'],
+ 'update' => ['id','advertise_page_id','name','max_num','width','height','sort'],
+ 'del' => ['id'],
+ 'invalidList' => ['']
+ ];
+}
diff --git a/app/api/validate/Advertisement.php b/app/api/validate/Advertisement.php
new file mode 100644
index 0000000..f186df1
--- /dev/null
+++ b/app/api/validate/Advertisement.php
@@ -0,0 +1,61 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言版本' => ['integer','gt:0'],
+ 'name|广告名称' => ['length:1,50','require'],
+ 'sort|排序' => ['between:1,255'],
+ 'advertise_space_id|广告位' => ['integer','gt:0','require'],
+ 'image|图片上传' => ['length:1,128','require'],
+ 'url|关联链接' => ['length:1,128'],
+ 'command|悬浮提示' => ['length:1,128'],
+ 'start_time|开始时间' => ['integer','gt:0'],
+ 'stop_time|结束时间' => ['integer','gt:0'],
+ 'play_order|轮播顺序' => ['integer','gt:0'],
+ 'status|状态' => ['in:0,1','integer'],
+ 'avatar|广告图' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,bmp,gif,jpeg',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ]
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['site_id','advertise_space_id','name','image','url','play_order','command'],
+ 'update' => ['id','advertise_space_id','name','image','url','play_order','command','status'],
+ 'del' => ['id'],
+ 'upload' => ['']
+ ];
+}
diff --git a/app/api/validate/Article.php b/app/api/validate/Article.php
new file mode 100644
index 0000000..e0aff0c
--- /dev/null
+++ b/app/api/validate/Article.php
@@ -0,0 +1,64 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'language_id|语言包' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'article_type_id|所属分类' => ['integer','gt:0'],
+ 'is_outer_chain|外链文章' => ['require','integer','egt:0','in:0,1'],
+ 'status|状态' => ['integer','egt:0','in:0,1'],
+ 'title|文章标题' => ['require','length:1,128'],
+ 'brief|文章摘要' => ['length:1,255'],
+ 'thumb|封面图片' => ['length:1,255'],
+ 'url|链接' => ['length:1,255'],
+ 'keywords|Keywords' => ['length:1,255'],
+ 'desc|Description' => ['length:1,255'],
+ 'meta_title|页面Meta-title' => ['length:1,255'],
+ 'detail|图文详情' => ['length:1,65530'],
+ 'click_num|点击次数' => ['integer','egt:0'],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg,gif,webp,tiff,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,image/webp,image/tiff,image/bmp'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','article_type_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','title','desc','thumb','url','detail','is_outer_chain','brief','article_type_id','keywords','meta_title'],
+ 'update' => ['id','site_id','title','desc','thumb','url','detail','is_outer_chain','brief','article_type_id','keywords','meta_title'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['image'],
+ ];
+}
diff --git a/app/api/validate/ArticleType.php b/app/api/validate/ArticleType.php
new file mode 100644
index 0000000..42d7cac
--- /dev/null
+++ b/app/api/validate/ArticleType.php
@@ -0,0 +1,38 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:article_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/Attribute.php b/app/api/validate/Attribute.php
new file mode 100644
index 0000000..e10ee6a
--- /dev/null
+++ b/app/api/validate/Attribute.php
@@ -0,0 +1,37 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|所属站点' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'name|属性名称' => ['length:1,50','require','unique:attribute,name^site_id^platform_id'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id'],
+ 'read' => ['id'],
+ 'update' => ['id','name'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/Base.php b/app/api/validate/Base.php
new file mode 100644
index 0000000..011e070
--- /dev/null
+++ b/app/api/validate/Base.php
@@ -0,0 +1,52 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'icon|图标' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,bmp,gif,jpeg',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ],
+ 'file|文件' => [
+ 'fileSize' => 1024 * 1024 * 10,
+ 'fileExt' => 'xls,xlsx,jpg,png,docx,doc',
+ 'fileMime' => 'application/vnd.ms-excel,image/jpeg,image/png,image/gif,application/x-rar-compressed,application/zip,application/pdf,audio/ogg,text/plain,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
+ ],
+ 'driver|驱动' => [
+ 'fileSize' => 1024 * 1024 * 10,
+ 'fileExt' => 'xls,xlsx,jpg,png,docx,doc,rar,zip',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,application/x-rar-compressed,application/zip,application/pdf,audio/ogg,text/plain,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'file' => ['file'],
+ 'image' => ['image'],
+ 'icon' => ['icon'],
+ 'driver' => ['driver'],
+ ];
+
+}
diff --git a/app/api/validate/Brand.php b/app/api/validate/Brand.php
new file mode 100644
index 0000000..c1475c9
--- /dev/null
+++ b/app/api/validate/Brand.php
@@ -0,0 +1,73 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'language_id|语言包' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'brand_type_id|所属分类' => ['integer','gt:0'],
+ 'is_outer_chain|外链文章' => ['require','integer','egt:0','in:0,1'],
+ 'status|状态' => ['integer','egt:0','in:0,1'],
+ 'title|文章标题' => ['require','length:1,128'],
+ 'brief|文章摘要' => ['length:1,255'],
+ 'thumb|封面图片' => ['length:1,255'],
+ 'url|链接' => ['length:1,255'],
+ 'keywords|Keywords' => ['length:1,255'],
+ 'desc|Description' => ['length:1,255'],
+ 'meta_title|页面Meta-title' => ['length:1,255'],
+ 'detail|图文详情' => ['length:1,65530'],
+ 'click_num|点击次数' => ['integer','egt:0'],
+ 'website' => ['length:1,255'],
+ 'cname' => ['length:1,255'],
+ 'en_name' => ['length:1,255'],
+ 'belong' => ['length:1,255'],
+ 'turnover' => ['length:1,255'],
+ 'brand_cate' => ['length:1,255'],
+ 'work_address' => ['length:1,255'],
+ 'founded' => ['length:1,255'],
+ 'founder' => ['length:1,255'],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg,gif,webp,tiff,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,image/webp,image/tiff,image/bmp'
+ ]
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','Brand_type_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','title','desc','thumb','url','detail','is_outer_chain','brief','brand_type_id','keywords','meta_title'],
+ 'update' => ['id','site_id','title','desc','thumb','url','detail','is_outer_chain','brief','brand_type_id','keywords','meta_title'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['image'],
+ ];
+}
diff --git a/app/api/validate/BrandType.php b/app/api/validate/BrandType.php
new file mode 100644
index 0000000..71e2974
--- /dev/null
+++ b/app/api/validate/BrandType.php
@@ -0,0 +1,38 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:brand_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/BulkBuy.php b/app/api/validate/BulkBuy.php
new file mode 100644
index 0000000..93d86a8
--- /dev/null
+++ b/app/api/validate/BulkBuy.php
@@ -0,0 +1,52 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言包ID' => ['integer','gt:0'],
+ 'name|客户名称' => ['length:1,30','require'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'mode_number|产品型号' => ['length:1,128','require'],
+ 'needed_num|需要数量' => ['integer','gt:0'],
+ 'email|邮箱' => ['length:1,60','require'],
+ 'arrival_country|收货国家'=> ['length:1,128','require'],
+ 'delivery_time|发货时间' => ['integer','gt:0'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * 场景
+ * @var
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['site_id','name','mode_number','needed_num','email','arrival_country','sort','delivery_time'],
+ 'update' => ['id','name','mode_number','needed_num','email','arrival_country','sort','delivery_time'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/Comment.php b/app/api/validate/Comment.php
new file mode 100644
index 0000000..afd60be
--- /dev/null
+++ b/app/api/validate/Comment.php
@@ -0,0 +1,54 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言版本' => ['integer','gt:0'],
+ 'sort|排序' => ['require','integer','gt:0','lt:256'],
+ 'avatar|客户头像' => [
+ 'fileSize' => 1024 * 1024 * 1,
+ 'fileExt' => 'jpg,png,ico',
+ 'fileMime' => 'image/jpeg,image/png,image/gif',
+ ],
+ 'image|评价配图' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,bmp,gif,jpeg',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ],
+ 'nickname|客户昵称' => ['length:1,20'],
+ 'comment|评价内容' => ['length:1,1500'],
+ 'url|产品链接' => ['length:1,128'],
+ ];
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size','nickname'],
+ 'read' => ['id'],
+ 'create' => ['site_id','name','nickname','comment','url','sort'],
+ 'update' => ['id','name','nickname','comment','url','sort'],
+ 'del' => ['id'],
+ 'upload' => ['avatar','image']
+ ];
+}
diff --git a/app/api/validate/CouponSubscribe.php b/app/api/validate/CouponSubscribe.php
new file mode 100644
index 0000000..c47a1f1
--- /dev/null
+++ b/app/api/validate/CouponSubscribe.php
@@ -0,0 +1,29 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer'],
+ 'platform_id' => ['integer','gt:0'],
+ 'site_id' => ['integer','gt:0'],
+ 'goods_coupon_id' => ['integer','gt:0'],
+ 'email' => ['email'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/Currency.php b/app/api/validate/Currency.php
new file mode 100644
index 0000000..fad3698
--- /dev/null
+++ b/app/api/validate/Currency.php
@@ -0,0 +1,46 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'name|币种名称' => ['length:1,10','require','unique:currency,name'],
+ 'code|币种缩写' => ['length:1,10','require','unique:currency,code'],
+ 'signal|币种符号' => ['length:1,10','require'],
+ 'status|状态' => ['in:0,1','integer'],
+ ];
+
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['name','code','signal','status'],
+ 'update' => ['id','name','code','signal','status'],
+ 'del' => ['id'],
+ 'changeStatus'=> ['id','status'],
+ ];
+}
diff --git a/app/api/validate/Faq.php b/app/api/validate/Faq.php
new file mode 100644
index 0000000..6f8b0f5
--- /dev/null
+++ b/app/api/validate/Faq.php
@@ -0,0 +1,45 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言版本' => ['integer','gt:0'],
+ 'faq_type_id|问题分类' => ['integer','gt:0'],
+ 'question|回答问题' => ['length:1,150','require','unique:faq,question^site_id^platform_id'],
+ 'answer|回答内容' => ['length:1,3000'],
+ 'sort|排序' => ['between:1,255'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ protected $scene = [
+ 'index' => ['page','size','answer'],
+ 'read' => ['id'],
+ 'create' => ['site_id','faq_type_id','question','answer','sort'],
+ 'update' => ['id','faq_type_id','question','answer','sort'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/FaqType.php b/app/api/validate/FaqType.php
new file mode 100644
index 0000000..41db641
--- /dev/null
+++ b/app/api/validate/FaqType.php
@@ -0,0 +1,40 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id' => ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,60','require','unique:faq_type,name^site_id'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['site_id','name','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort'],
+ ];
+}
diff --git a/app/api/validate/FileType.php b/app/api/validate/FileType.php
new file mode 100644
index 0000000..9d41405
--- /dev/null
+++ b/app/api/validate/FileType.php
@@ -0,0 +1,37 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:file_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/Goods.php b/app/api/validate/Goods.php
new file mode 100644
index 0000000..a40f79f
--- /dev/null
+++ b/app/api/validate/Goods.php
@@ -0,0 +1,71 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|选择语言' => ['integer','gt:0'],
+ 'goods_category_id|所属分类' => ['require','integer','gt:0'],
+ 'name|商品标题' => ['length:1,220','unique:goods,name^site_id'],
+ 'model_number|商品型号' => ['length:1,128','unique:goods,model_number^site_id'],
+ 'price|价格' => ['float','gt:0'],
+ 'details|图文介绍' => ['length:1,65534'],
+ 'title|标题' => ['length:1,255','unique:goods,title^site_id'],
+ 'keywords|关键词' => ['length:1,255'],
+ 'description|描述' => ['length:1,255'],
+ 'status|上架状态' => ['in:0,1','integer'],
+ 'is_new|是否新品' => ['in:0,1','integer'],
+ 'is_discount|是否折扣' => ['in:0,1','integer'],
+ 'is_hot|是否热门' => ['in:0,1','integer'],
+ 'is_recommend|是否推荐' => ['in:0,1','integer'],
+ 'sort|排序' => ['between:1,255'],
+ 'image|产品主图' => [
+ 'fileSize' => 1024 * 1024 * 1,
+ 'fileExt' => 'jpg,png,gif,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ *
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['site_id','goods_category_id','name','model_number','price','details','title','keywords','description','status'],
+ 'update' => ['id','name','goods_category_id','model_number','price','details','title','keywords','description','status'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'batchGoodsDel' => ['id'],
+ 'batchGoodsEnable' => ['id','status'],
+ 'batchGoodsDisable' => ['id','status'],
+ 'batchCategoryModify' => ['id','goods_category_id'],
+ 'upload' => ['image'],
+ 'changeSort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/GoodsBuyNow.php b/app/api/validate/GoodsBuyNow.php
new file mode 100644
index 0000000..c1d68bd
--- /dev/null
+++ b/app/api/validate/GoodsBuyNow.php
@@ -0,0 +1,28 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer'],
+ 'goods_id|商品ID' => ['require','integer','gt:0'],
+ 'name|链接名称' => ['require','length:1,128'],
+ 'url|链接地址' => ['require','length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/GoodsCategory.php b/app/api/validate/GoodsCategory.php
new file mode 100644
index 0000000..bd63218
--- /dev/null
+++ b/app/api/validate/GoodsCategory.php
@@ -0,0 +1,47 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|所属站点' => ['require','integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,50','require','unique:goods_category,name^site_id'],
+ 'status|状态' => ['in:0,1','integer'],
+ 'pid|上级分类' => ['require','integer','egt:0'],
+ 'icon|图标' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['status'],
+ 'tree' => ['status'],
+ 'read' => ['id'],
+ 'create' => ['site_id','name','desc','pid','sort','status'],
+ 'update' => ['id','name','desc','pid','sort','status'],
+ 'del' => ['id'],
+ 'upload' => ['icon'],
+ 'sort' => ['id','sort'],
+ 'changeStatus' => ['id','status'],
+ 'categoryGoodsList' => [''],
+ 'categoryGoodsInfo' => [''],
+ ];
+}
diff --git a/app/api/validate/GoodsConnect.php b/app/api/validate/GoodsConnect.php
new file mode 100644
index 0000000..10ab314
--- /dev/null
+++ b/app/api/validate/GoodsConnect.php
@@ -0,0 +1,28 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'goods_id|商品ID' => ['integer','require','gt:0'],
+ 'goods_category_id|商品分类ID' => ['integer','require','gt:0'],
+ 'connect_good_id|关联商品ID' => ['integer','gt:0','require'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/GoodsCoupon.php b/app/api/validate/GoodsCoupon.php
new file mode 100644
index 0000000..6ee153a
--- /dev/null
+++ b/app/api/validate/GoodsCoupon.php
@@ -0,0 +1,47 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言包ID' => ['integer','gt:0'],
+// 'old_code|旧口令' => ['length:1,30'],
+ 'new_code|新口令' => ['require','length:1,30','unique:goods_coupon,new_code^old_code^id'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['site_id','old_code','new_code'],
+ 'update' => ['id','old_code','new_code'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/GoodsImages.php b/app/api/validate/GoodsImages.php
new file mode 100644
index 0000000..e0900f4
--- /dev/null
+++ b/app/api/validate/GoodsImages.php
@@ -0,0 +1,27 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer'],
+ 'goods_id|商品ID' => ['integer','require','gt:0'],
+ 'image|图片' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/GoodsSoftManual.php b/app/api/validate/GoodsSoftManual.php
new file mode 100644
index 0000000..d116423
--- /dev/null
+++ b/app/api/validate/GoodsSoftManual.php
@@ -0,0 +1,30 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer','require','gt:0'],
+ 'soft_manual_id' => ['integer','require','gt:0'],
+ 'btn_tips' => ['length:1,128'],
+ 'url' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [];
+}
diff --git a/app/api/validate/Investment.php b/app/api/validate/Investment.php
new file mode 100644
index 0000000..d3064e4
--- /dev/null
+++ b/app/api/validate/Investment.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/Join.php b/app/api/validate/Join.php
new file mode 100644
index 0000000..f5a1576
--- /dev/null
+++ b/app/api/validate/Join.php
@@ -0,0 +1,64 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'language_id|语言包' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'join_type_id|所属分类' => ['integer','gt:0'],
+ 'is_outer_chain|外链文章' => ['require','integer','egt:0','in:0,1'],
+ 'status|状态' => ['integer','egt:0','in:0,1'],
+ 'title|文章标题' => ['require','length:1,128'],
+ 'brief|文章摘要' => ['length:1,255'],
+ 'thumb|封面图片' => ['length:1,255'],
+ 'url|链接' => ['length:1,255'],
+ 'keywords|Keywords' => ['length:1,255'],
+ 'desc|Description' => ['length:1,255'],
+ 'meta_title|页面Meta-title' => ['length:1,255'],
+ 'detail|图文详情' => ['length:1,65530'],
+ 'click_num|点击次数' => ['integer','egt:0'],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg,gif,webp,tiff,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,image/webp,image/tiff,image/bmp'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','Join_type_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','title','desc','thumb','url','detail','is_outer_chain','brief','Join_type_id','keywords','meta_title'],
+ 'update' => ['id','site_id','title','desc','thumb','url','detail','is_outer_chain','brief','Join_type_id','keywords','meta_title'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['image'],
+ ];
+}
diff --git a/app/api/validate/JoinType.php b/app/api/validate/JoinType.php
new file mode 100644
index 0000000..e12e651
--- /dev/null
+++ b/app/api/validate/JoinType.php
@@ -0,0 +1,38 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:join_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/Language.php b/app/api/validate/Language.php
new file mode 100644
index 0000000..beaa45b
--- /dev/null
+++ b/app/api/validate/Language.php
@@ -0,0 +1,50 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'name|语言名称' => ['length:1,10','require','unique:language,name'],
+ 'code|语言代号' => ['length:1,10','require','unique:language,code'],
+ 'icon|预览图' => ['length:1,128','require'],
+ 'status|状态' => ['in:0,1','integer'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * 验证场景定义
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['name','code','icon','url','status'],
+ 'update' => ['id','name','code','icon','url','status'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['']
+ ];
+}
diff --git a/app/api/validate/Menu.php b/app/api/validate/Menu.php
new file mode 100644
index 0000000..3178396
--- /dev/null
+++ b/app/api/validate/Menu.php
@@ -0,0 +1,51 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'name|菜单名称' => ['length:1,12','require'],
+ 'icon|图标' => ['length:1,128','require'],
+ 'sort|排序' => ['between:1,255','require'],
+ 'path|菜单路径' => ['length:1,64','require'],
+ 'component|操作' => ['length:1,128','require'],
+ 'redirect|跳转' => ['length:1,128','require'],
+ 'is_menu|是否为菜单' => ['in:0,1','integer'],
+ 'pid|父ID' => ['integer','require','egt:0'],
+ 'status|状态' => ['in:0,1','integer'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size','name'],
+ 'tree' => [''],
+ 'read' => ['id'],
+ 'create' => ['name','icon','path','component','redirect','is_menu','pid','sort','status'],
+ 'update' => ['id','name','icon','path','component','redirect','is_menu','pid','sort','status'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort'],
+ ];
+}
diff --git a/app/api/validate/MenuPlatform.php b/app/api/validate/MenuPlatform.php
new file mode 100644
index 0000000..3d890d6
--- /dev/null
+++ b/app/api/validate/MenuPlatform.php
@@ -0,0 +1,28 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer','require','gt:0'],
+ 'menu_id|菜单ID' => ['integer','require','gt:0'],
+ 'platform_id|品牌ID' => ['integer','gt:0'],
+ 'status|状态' => ['integer','in:1,0'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/Navigator.php b/app/api/validate/Navigator.php
new file mode 100644
index 0000000..bbe6618
--- /dev/null
+++ b/app/api/validate/Navigator.php
@@ -0,0 +1,53 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|所属站点'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|栏目名称' => ['length:1,128','require','unique:navigator,name^site_id^platform_id'],
+ 'is_top|顶部导航' => ['in:0,1','integer'],
+ 'is_foot|底部导航' => ['in:0,1','integer'],
+ 'pid|上级栏目' => ['require','integer','egt:0'],
+ 'icon|图标' => ['length:1,128'],
+ 'desc|描述' => ['length:1,128'],
+ 'url|文件路径' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'tree' => [''],
+ 'read' => ['id'],
+ 'create' => ['site_id','name','desc','pid','icon','url','sort','is_top','is_foot'],
+ 'update' => ['id','name','desc','pid','icon','url','sort','is_top','is_foot'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort'],
+ 'changeStatus' => ['id','is_top','is_foot'],
+ 'topTree' => [''],
+ 'upload' => ['']
+ ];
+}
diff --git a/app/api/validate/News.php b/app/api/validate/News.php
new file mode 100644
index 0000000..a795fba
--- /dev/null
+++ b/app/api/validate/News.php
@@ -0,0 +1,64 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'language_id|语言包' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'news_type_id|所属分类' => ['integer','gt:0'],
+ 'is_outer_chain|外链文章' => ['require','integer','egt:0','in:0,1'],
+ 'status|状态' => ['integer','egt:0','in:0,1'],
+ 'title|文章标题' => ['require','length:1,128'],
+ 'brief|文章摘要' => ['length:1,255'],
+ 'thumb|封面图片' => ['length:1,255'],
+ 'url|链接' => ['length:1,255'],
+ 'keywords|Keywords' => ['length:1,255'],
+ 'desc|Description' => ['length:1,255'],
+ 'meta_title|页面Meta-title' => ['length:1,255'],
+ 'detail|图文详情' => ['length:1,65530'],
+ 'click_num|点击次数' => ['integer','egt:0'],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg,gif,webp,tiff,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,image/webp,image/tiff,image/bmp'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','News_type_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','title','desc','thumb','url','detail','is_outer_chain','brief','News_type_id','keywords','meta_title'],
+ 'update' => ['id','site_id','title','desc','thumb','url','detail','is_outer_chain','brief','News_type_id','keywords','meta_title'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['image'],
+ ];
+}
diff --git a/app/api/validate/NewsType.php b/app/api/validate/NewsType.php
new file mode 100644
index 0000000..d27871e
--- /dev/null
+++ b/app/api/validate/NewsType.php
@@ -0,0 +1,38 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:news_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/Platform.php b/app/api/validate/Platform.php
new file mode 100644
index 0000000..6c6ea27
--- /dev/null
+++ b/app/api/validate/Platform.php
@@ -0,0 +1,51 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|品牌名称' => ['length:1,50','require','unique:platform,name'],
+ 'status|状态' => ['in:0,1','integer'],
+ 'vi_color1|品牌VI色标准色' => ['length:1,10','require','different:vi_color2','different:vi_color3','regex:^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$'],
+ 'vi_color2|品牌VI色辅助色-深' => ['length:1,10','require','different:vi_color3','different:vi_color1','regex:^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$'],
+ 'vi_color3|品牌VI色辅助色-浅' => ['length:1,10','require','different:vi_color1','different:vi_color2','regex:^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$'],
+ 'currency_id|默认币种' => ['integer','gt:0'],
+ 'language_id|默认语言' => ['integer','gt:0'],
+ 'icon|品牌logo' => ['length:1,128'],
+
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * 验证场景定义
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['name','vi_color1','vi_color2','vi_color3','language_id','currency_id','desc','icon','status'],
+ 'update' => ['id','vi_color1','vi_color2','vi_color3','language_id','currency_id','desc','icon','status'],
+ 'del' => ['id'],
+ 'upload' => [''],
+ 'langeuageList' => ['']
+ ];
+}
diff --git a/app/api/validate/Question.php b/app/api/validate/Question.php
new file mode 100644
index 0000000..084fa3a
--- /dev/null
+++ b/app/api/validate/Question.php
@@ -0,0 +1,60 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'name|姓名' => ['length:1,40','require'],
+ 'country_id|国家' => ['length:1,30','require'],
+ 'email|邮箱' => ['length:1,60'],
+ 'phone|手机号码' => ['length:1,20','regex:/^1[23456789]{1}\d{9}$/'],
+ 'order_sn|SKU' => ['length:1,50'],
+ 'product_model|产品型号' => ['length:1,128'],
+ 'is_done|解决与否' => ['integer','in:0,1'],
+ 'os|操作系统' => ['length:1,50'],
+ 'image' => [
+ 'fileSize' => 1024 * 1024 * 10,
+ 'fileExt' => 'xls,xlsx,jpg,png,docx,doc,rar,zip',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,application/x-rar-compressed,application/zip,application/pdf,audio/ogg,text/plain,application/vnd.openxmlformats-officedocument.wordprocessingml.document'
+ ]
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','is_done','product_model'],
+ 'read' => ['id'],
+ 'create' => ['site_id','country_id','name','email','phone','order_sn','product_model','os','desc','sort'],
+ 'update' => ['id','country_id','name','email','phone','order_sn','product_model','os','desc','sort'],
+ 'del' => ['id'],
+ 'isDone' => ['id','is_done'],
+ 'upload' => ['image']
+ ];
+}
diff --git a/app/api/validate/QuestionAttachment.php b/app/api/validate/QuestionAttachment.php
new file mode 100644
index 0000000..0f16f8c
--- /dev/null
+++ b/app/api/validate/QuestionAttachment.php
@@ -0,0 +1,27 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer','require','gt:0'],
+ 'question_id|问题ID' => ['integer','require','gt:0'],
+ 'attach|附件' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/Resource.php b/app/api/validate/Resource.php
new file mode 100644
index 0000000..17b1901
--- /dev/null
+++ b/app/api/validate/Resource.php
@@ -0,0 +1,65 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'language_id|语言包' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'resource_type_id|所属分类' => ['integer','gt:0'],
+ 'is_outer_chain|外链文章' => ['require','integer','egt:0','in:0,1'],
+ 'status|状态' => ['integer','egt:0','in:0,1'],
+ 'title|文章标题' => ['require','length:1,128'],
+ 's_title|小标题' => ['require','length:1,255'],
+ 'brief|文章摘要' => ['length:1,255'],
+ 'thumb|封面图片' => ['length:1,255'],
+ 'url|链接' => ['length:1,255'],
+ 'keywords|Keywords' => ['length:1,255'],
+ 'desc|Description' => ['length:1,255'],
+ 'meta_title|页面Meta-title' => ['length:1,255'],
+ 'detail|图文详情' => ['length:1,65530'],
+ 'click_num|点击次数' => ['integer','egt:0'],
+ 'image|图片' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg,gif,webp,tiff,bmp',
+ 'fileMime' => 'image/jpeg,image/png,image/gif,image/webp,image/tiff,image/bmp'
+ ],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => ['page','size','Resource_type_id'],
+ 'read' => ['id'],
+ 'create' => ['site_id','title','desc','thumb','url','detail','is_outer_chain','brief','Resource_type_id','keywords','meta_title'],
+ 'update' => ['id','site_id','title','desc','thumb','url','detail','is_outer_chain','brief','Resource_type_id','keywords','meta_title'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'upload' => ['image'],
+ ];
+}
diff --git a/app/api/validate/ResourceType.php b/app/api/validate/ResourceType.php
new file mode 100644
index 0000000..46d88d1
--- /dev/null
+++ b/app/api/validate/ResourceType.php
@@ -0,0 +1,38 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'site_id|语言包ID'=> ['integer','gt:0'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'name|分类名称' => ['length:1,20','require','unique:resource_type,name^site_id']
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => [''],
+ 'create' => ['name','site_id','sort'],
+ 'update' => ['id','name','sort'],
+ 'del' => ['id'],
+ 'sort' => ['id','sort']
+ ];
+}
diff --git a/app/api/validate/Role.php b/app/api/validate/Role.php
new file mode 100644
index 0000000..e3c0b2f
--- /dev/null
+++ b/app/api/validate/Role.php
@@ -0,0 +1,41 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'name' => ['length:1,50','require'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size'],
+ 'read' => ['id'],
+ 'create' => ['name'],
+ 'update' => ['id','name'],
+ 'del' => ['id'],
+ ];
+}
diff --git a/app/api/validate/Site.php b/app/api/validate/Site.php
new file mode 100644
index 0000000..ed41177
--- /dev/null
+++ b/app/api/validate/Site.php
@@ -0,0 +1,48 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'status|状态' => ['in:0,1','integer'],
+ 'currency_id|默认币种' => ['integer','gt:0'],
+ 'language_id|站点语言'=> ['integer','gt:0'],
+ 'platform_id|所属品牌'=> ['integer','gt:0'],
+ 'domain|站点域名' => ['length:1,128','require'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size','platform_id'],
+ 'read' => ['id'],
+ 'create' => ['platform_id','language_id','currency_id','domain','status'],
+ 'update' => ['id','platform_id','currency_id','domain','status'],
+ 'del' => ['id'],
+ 'get_nav' => ['id'],
+ 'changeStatus' => ['id','status'],
+ 'siteIndex' => ['']
+ ];
+}
diff --git a/app/api/validate/SoftManual.php b/app/api/validate/SoftManual.php
new file mode 100644
index 0000000..1f25476
--- /dev/null
+++ b/app/api/validate/SoftManual.php
@@ -0,0 +1,63 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言版本' => ['require','integer','gt:0'],
+ 'file_type_id|文件分类' => ['integer','gt:0'],
+ 'name|下载名称' => ['length:1,50','unique:soft_manual,name^site_id^platform_id'],
+ 'introduce|下载介绍' => ['length:1,255'],
+ 'support|支持型号' => ['length:1,255'],
+ 'os|操作系统' => ['length:1,60'],
+ 'sort|排序' => ['require','between:1,255'],
+ 'download_count|下载次数' => ['integer','gt:0'],
+// 'image|预览图' => [
+// 'fileSize' => 1024 * 1024 * 10,
+// 'fileExt' => 'jpg,png,gif',
+// 'fileMime' => 'image/jpeg,image/png,image/gif'
+// ],
+// 'file|驱动文件' => [
+// 'fileSize' => 1024 * 1024 * 100,
+// 'fileExt' => 'xls,xlsx,jpg,png,docx,doc,rar,zip,pdf,chm',
+// 'fileMime' => 'image/jpeg,image/png,image/gif,application/x-rar-compressed,application/zip,application/pdf,audio/ogg,text/plain,application/vnd.openxmlformats-officedocument.wordprocessingml.document,application/vnd.ms-htmlhelp'
+// ],
+
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [
+ 'name.length' => '下载名称不能超过50个字符',
+ 'introduce.length' => '下载介绍不能超过255个字符',
+ 'support.length' => '支持型号不能超过255个字符',
+ 'os.length' => '操作系统不能超过60个字符',
+ ];
+
+ protected $scene = [
+ 'index' => [''],
+ 'read' => ['id'],
+ 'create' => ['site_id','file_type_id','name','introduce','support','os','sort'],
+ 'update' => ['id','file_type_id','name','introduce','support','os','sort'],
+ 'del' => ['id'],
+ 'changeStatus' => ['id','status'],
+// 'upload' => ['image','file']
+ ];
+}
diff --git a/app/api/validate/SoftManualBtn.php b/app/api/validate/SoftManualBtn.php
new file mode 100644
index 0000000..234e400
--- /dev/null
+++ b/app/api/validate/SoftManualBtn.php
@@ -0,0 +1,35 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['integer','gt:0','require'],
+ 'soft_manual_id|文档手册' => ['integer','gt:0'],
+ 'btn_tips|按钮名称' => ['length:1,20'],
+ 'url|下载链接' => ['length:1,128'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ /**
+ * @var array
+ */
+ protected $scene = [
+ 'index' => [],
+ ];
+}
diff --git a/app/api/validate/SystemConfig.php b/app/api/validate/SystemConfig.php
new file mode 100644
index 0000000..1bf1902
--- /dev/null
+++ b/app/api/validate/SystemConfig.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/api/validate/Video.php b/app/api/validate/Video.php
new file mode 100644
index 0000000..08728d4
--- /dev/null
+++ b/app/api/validate/Video.php
@@ -0,0 +1,54 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id|语言包' => ['integer','gt:0'],
+ 'name|视频名称' => ['length:1,40'],
+ 'is_top|是否置顶' => ['integer','in:0,1'],
+ 'sort|排序' => ['integer','between:1,200'],
+ 'image' => [
+ 'fileSize' => 1024 * 1024 * 5,
+ 'fileExt' => 'jpg,png,ico,jpeg',
+ 'fileMime' => 'image/jpeg,image/png,image/gif'
+ ],
+ 'url' => [
+ 'fileSize' => 1024 * 1024 * 50,
+ 'fileExt' => 'mp4',
+ 'fileMime' => 'video/mp4'
+ ]
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size','name'],
+ 'read' => ['id'],
+ 'create' => ['site_id','name','sort','is_top'],
+ 'update' => ['id','site_id','name','sort','is_top'],
+ 'del' => ['id'],
+ 'upload' => ['image','url'],
+ 'change_status' => ['id','is_top','sort'],
+ 'sort' => ['id','is_top','sort'],
+ ];
+}
diff --git a/app/common.php b/app/common.php
new file mode 100644
index 0000000..db97c85
--- /dev/null
+++ b/app/common.php
@@ -0,0 +1,498 @@
+insert($add_data,false,true);
+
+}
+
+
+/**
+ * 组装绝对url
+ * @param $url
+ * @return string
+ */
+function build_image_fullurl($url, $qiniu=true, $type='public')
+{
+ $rootPath = '';
+ if (empty($url) || stripos($url, 'http://') !== false || stripos($url, 'https://') !== false) {
+ return $url;
+ } else if (stripos($url, '.') == 0) {
+ $url = mb_substr($url, 1);
+ }
+
+ if (stripos($url, '/') == 0) {
+ if (false !== stripos($url, '/attachs')) {
+ $rootPath = 'https://www.f2b211.com';
+ }
+ if (false !== stripos($url, '/paycard')) {
+ $rootPath = 'https://api.f2b211.com';
+ }
+ if (false !== stripos($url, '/payimg')) {
+ $rootPath = 'https://api.f2b211.com';
+ }
+ if (false !== stripos($url, '/Public/goods')) {
+ $rootPath = 'https://www.f2b211.com';
+ }
+ } else {
+ // 七牛地址
+ if ($qiniu) {
+ $rootPath = \utils\QiniuUploader::$domain;
+ } else {
+ if ($type == 'public') {
+ $rootPath = request()->domain() . \think\facade\Filesystem::getConfig('disks.public.url');
+ } else {
+ $rootPath = request()->domain() . '/';
+ }
+ }
+ }
+
+ return $rootPath . $url;
+}
+/**
+ * 返回json格式的数组
+ * @param
+ * @param
+ * @param [array] $data [随带的数据]
+ * @return [string] [json字符串]
+ */
+function json_return($data)
+{
+ header("Content-Type: application/json; charset=UTF-8");
+
+ exit(json_encode($data));
+}
+
+
+/**
+ * 将数值金额转换为中文大写金额
+ * @param $amount float 金额(支持到分)
+ * @param $type int 补整类型,0:到角补整;1:到元补整
+ * @return mixed 中文大写金额
+ */
+function convertAmountToCn($amount, $type = 1) {
+ // 判断输出的金额是否为数字或数字字符串
+ if(!is_numeric($amount)){
+ return "要转换的金额只能为数字!";
+ }
+
+ // 金额为0,则直接输出"零元整"
+ if($amount == 0) {
+ return "人民币零元整";
+ }
+
+ // 金额不能为负数
+ if($amount < 0) {
+ return "要转换的金额不能为负数!";
+ }
+
+ // 金额不能超过万亿,即12位
+ if(strlen($amount) > 12) {
+ return "要转换的金额不能为万亿及更高金额!";
+ }
+
+ // 预定义中文转换的数组
+ $digital = array('零', '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖');
+ // 预定义单位转换的数组
+ $position = array('仟', '佰', '拾', '亿', '仟', '佰', '拾', '万', '仟', '佰', '拾', '元');
+
+ // 将金额的数值字符串拆分成数组
+ $amountArr = explode('.', $amount);
+
+ // 将整数位的数值字符串拆分成数组
+ $integerArr = str_split($amountArr[0], 1);
+
+ // 将整数部分替换成大写汉字
+ $result = '人民币';
+ $integerArrLength = count($integerArr); // 整数位数组的长度
+ $positionLength = count($position); // 单位数组的长度
+ $zeroCount = 0; // 连续为0数量
+ for($i = 0; $i < $integerArrLength; $i++) {
+ // 如果数值不为0,则正常转换
+ if($integerArr[$i] != 0){
+ // 如果前面数字为0需要增加一个零
+ if($zeroCount >= 1){
+ $result .= $digital[0];
+ }
+ $result .= $digital[$integerArr[$i]] . $position[$positionLength - $integerArrLength + $i];
+ $zeroCount = 0;
+ }else{
+ $zeroCount += 1;
+ // 如果数值为0, 且单位是亿,万,元这三个的时候,则直接显示单位
+ if(($positionLength - $integerArrLength + $i + 1)%4 == 0){
+ $result = $result . $position[$positionLength - $integerArrLength + $i];
+ }
+ }
+ }
+
+ // 如果小数位也要转换
+ if($type == 0) {
+ // 将小数位的数值字符串拆分成数组
+ $decimalArr = str_split($amountArr[1], 1);
+ // 将角替换成大写汉字. 如果为0,则不替换
+ if($decimalArr[0] != 0){
+ $result = $result . $digital[$decimalArr[0]] . '角';
+ }
+ // 将分替换成大写汉字. 如果为0,则不替换
+ if($decimalArr[1] != 0){
+ $result = $result . $digital[$decimalArr[1]] . '分';
+ }
+ }else{
+// $result = $result . '整';
+ $result = $result;
+ }
+ return $result;
+}
+
+
+
+/**
+ * 获取客户端ip
+ */
+function get_client_ip($type = 0) {
+ $type = $type ? 1 : 0;
+ static $ip = NULL;
+ if ($ip !== NULL) return $ip[$type];
+ if(isset($_SERVER['HTTP_X_REAL_IP'])){//nginx 代理模式下,获取客户端真实IP
+ $ip=$_SERVER['HTTP_X_REAL_IP'];
+ }elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {//客户端的ip
+ $ip = $_SERVER['HTTP_CLIENT_IP'];
+ }elseif (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {//浏览当前页面的用户计算机的网关
+ $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
+ $pos = array_search('unknown',$arr);
+ if(false !== $pos) unset($arr[$pos]);
+ $ip = trim($arr[0]);
+ }elseif (isset($_SERVER['REMOTE_ADDR'])) {
+ $ip = $_SERVER['REMOTE_ADDR'];//浏览当前页面的用户计算机的ip地址
+ }else{
+ $ip=$_SERVER['REMOTE_ADDR'];
+ }
+ // IP地址合法验证
+ $long = sprintf("%u",ip2long($ip));
+ $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
+ return $ip[$type];
+}
+
+
+/**
+ * 列表转换为树形结构
+ * @param array $list 需要处理的树形结构数据
+ * @param int $isOver 是否有限级别,比如2表示只输出2级分类结构,0表示有多少级全部输出
+ * @param string $pk 主键字段名
+ * @param string $pid_name 父类字段名
+ * @param string $child_name 子数据结构名
+ * @param string $level_name 层级结构名
+ * @param int $pid 父ID
+ * @param int $level 层级数量,1=一层分类,2=二层
+ * @return array
+ */
+function list_to_tree($list,$isOver = 0, $pk='id', $pid_name='pid', $child_name='children', $level_name='level', $pid=0, $level=1)
+{
+ $tree = [];
+ foreach ($list as $key => $value)
+ {
+ if ($value[$pid_name] == $pid)
+ {
+ $value[$level_name] = $level;
+ if ($isOver == $level) {
+ continue;
+ } else {
+ $child = list_to_tree($list,$isOver, $pk, $pid_name, $child_name, $level_name, $value[$pk], $level+1);
+ }
+ if (!empty($child)) $value[$child_name] = $child;
+ $tree[] = $value;
+ }
+ }
+
+ return $tree;
+}
+
+/**
+ * 列表转换为树形结构
+ */
+function list_to_top_tree($data,$cid)
+{
+ $arr = [];
+ foreach ($data as $item) {
+ if ($cid == $item['id']) {
+ $arr[] = $item;
+ $arr = array_merge(list_to_top_tree($data,$item['pid']),$arr);
+ }
+ }
+ return $arr;
+}
+
+/**
+ * 通过分类id查找所有父ID
+ */
+function category_to_all_pid($data,$cid)
+{
+ $arr = [];
+ foreach ($data as $item) {
+ if ($cid == $item['id']) {
+ $arr[] = $item['id'];
+ $arr = array_merge(category_to_all_pid($data,$item['pid']),$arr);
+ }
+ }
+ return $arr;
+}
+
+/**
+ * 当前分类ID,获取所有子分类ID
+ */
+function category_to_all_children_id($data,$cid)
+{
+ $arr = [];
+ foreach ($data as $item) {
+ if ($cid == $item['pid']) {
+ $arr[] = $item['id'];
+ $arr = array_merge(category_to_all_children_id($data,$item['id']),$arr);
+ }
+ $arr[] = $cid;
+ }
+ return $arr;
+}
+
+
+/**
+ * 获取唯一id
+ */
+function unique_id($length = 20, $prefix = '')
+{
+ $id = $prefix;
+ $addLength = $length - 13;
+ $id .= uniqid();
+ if (function_exists('random_bytes')) {
+ $id .= substr(bin2hex(random_bytes(ceil(($addLength) / 2))),0,$addLength);
+ } elseif (function_exists('openssl_random_pseudo_bytes')) {
+ $id .= substr(bin2hex(openssl_random_pseudo_bytes(ceil($addLength / 2))),0,$addLength);
+ } else {
+ $id .= mt_rand(1*pow(10,($addLength)),9*pow(10,($addLength)));
+ }
+ return $id;
+}
+
+///**
+// * 获取随机字符串
+// */
+//function rand_str($length)
+//{
+// $pattern = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLOMNOPQRSTUVWXYZ';
+// $result = '';
+// for($i=0;$i<$length;$i++)
+// {
+// $result .= $pattern{mt_rand(0,35)}; //生成php随机数
+// }
+// return $result;
+//}
+
+/**
+ * 格式化价格
+ * @param $price int 价格
+ * @param $divisor int 除数
+ * @param $bit int 保留位数
+ * @return string
+ */
+function format_price($price, $divisor=100, $bit=2)
+{
+ $format = "%." . $bit . "f";
+ return sprintf($format, $price / $divisor);
+}
+
+/**
+ * 数据是否合法
+ */
+function is_valid_data($data)
+{
+ return isset($data) && $data != '';
+}
+
+/**
+ * 隐藏电话号码
+ */
+function hide_mobile($mobile)
+{
+ $IsWhat = preg_match('/(0[0-9]{2,3}[\-]?[2-9][0-9]{6,7}[\-]?[0-9]?)/i',$mobile); //固定电话
+ if($IsWhat == 1){
+ return preg_replace('/(0[0-9]{2,3}[\-]?[2-9])[0-9]{3,4}([0-9]{3}[\-]?[0-9]?)/i','$1****$2',$mobile);
+ }else{
+ return preg_replace('/(1[358]{1}[0-9])[0-9]{4}([0-9]{4})/i','$1****$2',$mobile);
+ }
+}
+
+function curl_get($url){
+ $headerArray = array(
+ "Content-type: application/json"
+ );
+ $ch = curl_init();
+ curl_setopt($ch, CURLOPT_URL, $url);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
+ curl_setopt($ch,CURLOPT_HTTPHEADER,$headerArray);
+ $output = curl_exec($ch);
+ curl_close($ch);
+ $output = json_decode($output, true);
+ return $output;
+}
+
+function curl_post($url, $data){
+ $data = json_encode($data);
+ $headerArray = array(
+ "Content-type: application/json"
+ );
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ $output = curl_exec($curl);
+ curl_close($curl);
+ return json_decode($output, true);
+}
+
+
+/** 根据物料编码查69码
+ * @param $fnumber 编码
+ */
+function get_FBARCODE($fnumber){
+ $formid = 'BD_MATERIAL';
+ $TopRowCount = 0;
+ $Limit = 0;
+ $StartRow = 0;
+ $FilterString = "FUseOrgId.fnumber=101 and FForbidStatus='A' and FNumber='$fnumber'";//dump($FilterString);die;
+ $OrderString = 'FMATERIALID';
+ $FieldKeys = 'FBARCODE';
+ $erp = new ERP();
+ $geterp = $erp->getproduct($formid, $FieldKeys, $FilterString, $OrderString, $StartRow, $TopRowCount, $Limit);
+ $fnumber = json_decode($geterp[0],true);
+ $CheckBox = $fnumber[0][0];
+ return $CheckBox;
+}
+/** 根据69码查物料型号
+ * @param $code 69码
+ */
+function FBARCODE_Getmodel($code){
+ $formid = 'BD_MATERIAL';
+ $TopRowCount = 0;
+ $Limit = 0;
+ $StartRow = 0;
+ $FilterString = "FUseOrgId.fnumber=101 and FForbidStatus='A' and FBARCODE='$code'";//dump($FilterString);die;
+ $OrderString = 'FMATERIALID';
+ $FieldKeys = 'FSpecification';
+ $erp = new ERP();
+ $geterp = $erp->getproduct($formid, $FieldKeys, $FilterString, $OrderString, $StartRow, $TopRowCount, $Limit);
+ $fnumber = json_decode($geterp[0],true);
+ if($fnumber==null){
+ $CheckBox=null;
+ }else{
+ $CheckBox = $fnumber[0][0];
+ }
+
+ return $CheckBox;
+}
+
+
+/**
+ * 处理图片绝对路径转相对路径算法
+ * @param $url
+ * @return mixed|string
+ */
+function doImageURLtoRelativePath($url)
+{
+ $arr = explode(think\facade\Env::get('QINIU.cdn'),$url);
+ if (isset($arr[1])) {
+ return $arr[1];
+ } else {
+ //可以拆分域名朋问题
+ if (false === strrpos(think\facade\Env::get('QINIU.cdn'),$url)) {
+ return $url;
+ } else {
+ $domain = explode('/',$url)[2];
+ $arr = explode($domain[2],$url);
+ return ltrim('/',$arr[1]);
+ }
+
+ }
+}
+
+if (!function_exists('is_image')) {
+
+ function is_image($file) {
+ return file_exists($file) && @getimagesize($file) ? true : false;
+ }
+}
+
+
+/**
+ * 处理二维数组站点与语言ID互换的问题
+ */
+if (!function_exists('array_copy_column')) {
+ function array_copy_column($array) {
+ foreach ($array as $key => $item) {
+ if (isset($item['language_id'])) {
+ $array[$key]['site_id'] = $item['language_id'];
+ }
+ }
+ return $array;
+ }
+}
+
+if (function_exists('show')) {
+ /**
+ * 返回json格式的数组
+ * @param [int] $status [代表返回时的状态:0失败,1成功]
+ * @param [string] $message [提示信息]
+ * @param [array] $data [随带的数据]
+ * @return [string] [json字符串]
+ */
+ function show($status, $message, $data = [])
+ {
+ header("Content-Type: application/json; charset=UTF-8");
+
+ $result = [
+ 'status' => $status,
+ 'message' => $message,
+ 'data' => $data
+ ];
+
+ exit(json_encode($result));
+ }
+}
+
+/**
+ * 递归
+ * @param $data array 需要递归的数据
+ * @param $pid integer 上级ID
+ * @param $pf string 上级的字段名
+ * @param $unset bool 为true则去除pid字段
+ * @return array
+ */
+if (!function_exists('recursion_func')) {
+ function recursion_func($data, $pid = 0, $pf = 'pid', $unset = false) {
+ $result = [];
+ foreach ($data as $key => $val) {
+ if ($val[$pf] == $pid) {
+ if ($unset) unset($val[$pf]);
+ $result[$key] = $val;
+ if ($recur = recursion_func($data, $val['id'], $pf, $unset)) {
+ $result[$key]['children'] = array_values($recur);
+ }
+ }
+ }
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/app/event.php b/app/event.php
new file mode 100644
index 0000000..e9851bb
--- /dev/null
+++ b/app/event.php
@@ -0,0 +1,17 @@
+ [
+ ],
+
+ 'listen' => [
+ 'AppInit' => [],
+ 'HttpRun' => [],
+ 'HttpEnd' => [],
+ 'LogLevel' => [],
+ 'LogWrite' => [],
+ ],
+
+ 'subscribe' => [
+ ],
+];
diff --git a/app/index/common.php b/app/index/common.php
new file mode 100644
index 0000000..1243615
--- /dev/null
+++ b/app/index/common.php
@@ -0,0 +1,2 @@
+ env('lang.default_lang', 'zh-cn'),
+ // 允许的语言列表
+ 'allow_lang_list' => ['zh-cn', 'en-us'],
+ // 多语言自动侦测变量名
+ 'detect_var' => 'lang',
+ // 是否使用Cookie记录
+ 'use_cookie' => true,
+ // 多语言cookie变量
+ 'cookie_var' => 'think_lang',
+ // 扩展语言包
+ 'extend_list' => [],
+ // Accept-Language转义为对应语言包名称
+ 'accept_language' => [
+ 'zh-cn' => 'zh-cn',
+ 'en-us' => 'en-us'
+ ],
+ // 是否支持语言分组
+ 'allow_group' => true,
+];
\ No newline at end of file
diff --git a/app/index/config/view.php b/app/index/config/view.php
new file mode 100644
index 0000000..6a40943
--- /dev/null
+++ b/app/index/config/view.php
@@ -0,0 +1,34 @@
+ 'Think',
+ // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
+ 'auto_rule' => 1,
+ // 模板目录名
+ 'view_dir_name' => 'view',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DIRECTORY_SEPARATOR,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+
+ // 模板变量
+ 'tpl_replace_string' => [
+ '__STATIC__' => Env::get('cdn.url','/'),
+ '__LOCAL__' => Env::get('cdn.local','/'),
+ ],
+ 'tpl_cache' => false,
+];
diff --git a/app/index/controller/About.php b/app/index/controller/About.php
new file mode 100644
index 0000000..89b17b8
--- /dev/null
+++ b/app/index/controller/About.php
@@ -0,0 +1,41 @@
+model = new \app\index\model\About();
+ }
+
+ /**
+ * 显示资源列表
+ *
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $resource = [];
+// $resource['banner'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-banner');
+// $resource['banner_mobile'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-手机-banner');
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'about');
+ View::assign('meta',$metaTitle);
+ View::assign('resource',$resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'about/about_us');
+ }
+
+ public function mileage(){
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'about/mileage');
+ }
+
+}
diff --git a/app/index/controller/Base.php b/app/index/controller/Base.php
new file mode 100644
index 0000000..042468a
--- /dev/null
+++ b/app/index/controller/Base.php
@@ -0,0 +1,249 @@
+'test']
+ * @var array
+ */
+ protected $vague = [];
+
+ /**
+ * 精准查询,精确字段,格式['language_id'=> 1]
+ * @var array
+ */
+ protected $focus = [];
+
+ /**
+ * 排序字段。格式 ['sort'=>'desc']
+ * @var array
+ */
+ protected $sort = [];
+
+ /**
+ * 模型
+ * @var array
+ */
+ protected $model = null;
+
+ /**
+ * 语言ID
+ * @var int|mixed
+ */
+ protected $languageId = 1;
+
+ /**
+ * 导航栏模型
+ * @var null
+ */
+ protected $navModel = null;
+
+ /**
+ * 系统配置模型
+ * @var null
+ */
+ protected $systemConfigModel = null;
+
+ /**
+ * 接口监控数据
+ * @var string[]
+ */
+ protected $apiLog = [
+ 'items' => '', /*项目名称*/
+ 'forum' => '', /*模块*/
+ 'forum_code' => '', /*模块日志编码*/
+ 'url' => '', /*访问页*/
+ 'refer' => '', /*访问来源*/
+ 'click' => '', /*点击次数*/
+ 'content' => '', /*访问内容*/
+ 'ip' => '', /*访客IP*/
+ 'country' => '', /*国家*/
+ 'province' => '', /*省*/
+ 'city' => '', /*市*/
+ 'start_time' => '', /*点击时间*/
+ 'drive' => '', /*PC OR 移动端*/
+ 'system' => '', /*设备系统*/
+ 'brower' => '', /*浏览器*/
+ 'models' => '', /*设备型号*/
+ 'date_time' => '' /*生成时间*/
+ ];
+
+ /**
+ * 判断请求来源是否是手机设备
+ * @return bool
+ */
+ private function isMobile() : bool
+ {
+ //如果有HTTP_X_WAP_PROFILE则一定是移动设备
+ if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
+ return true;
+ }
+ //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
+ if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], 'wap')) {
+ return true;
+ }
+ //野蛮方法,判断手机发送的客户端标志,兼容性有待提高
+ if (isset($_SERVER['HTTP_USER_AGENT'])) {
+
+ $clientKeywords = ['nokia','sony','ericsson','mot','samsung','htc','sgh','lg','sharp','sie-','philips','panasonic','alcatel','lenovo','iphone','ipod','blackberry','meizu','android','netfront','symbian','ucweb','windowsce','palm','operamini','operamobi','openwave','nexusone','cldc','midp','wap','mobile'];
+
+ //从HTTP_USER_AGENT中查找手机浏览器的关键字
+ if (preg_match("/(".implode('|', $clientKeywords).")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
+ return true;
+ }
+ }
+ //协议法,因为有可能不准确,放到最后判断
+ if (isset($_SERVER['HTTP_ACCEPT'])) {
+ //如果只支持wml并且不支持html那一定是移动设备
+ //如果支持wml和html但是wml在html之前则是移动设备
+ if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * 初始化
+ * @return void
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function initialize()
+ {
+ $controller = $this->request->controller();
+
+ $this->languageId = $this->request->language_id??1;
+ //通过中间件过来的语言包,动态设置
+ Lang::setLangSet($this->request->language_code??'zh-cn');
+ //重新加载动态设置的语言包
+ $this->app->loadLangPack(Lang::getLangSet());
+ // 初始化公共模型
+ $this->navModel = new Navigator();
+
+ $this->systemConfigModel = new SystemConfig();
+
+ // 初始化公共页面,判断语言包
+ // 导航
+ $navInfo = $this->navModel->getNavInfo($this->languageId,$this->platformId,$controller);
+ $navInfo = recursion_func($navInfo);
+ $footerNavInfo = $this->navModel->getFootNavInfo($this->languageId,$this->platformId);
+ $footerNavInfo = recursion_func($footerNavInfo);
+ // 头部版本号
+ // 静态版本号
+ $version = Env::get('front.version');
+ // 尾部数据
+ $footerInfo = $this->systemConfigModel->getFooterInfo($this->languageId);
+ // 首页多网站切换
+ $multiLanguage = $this->systemConfigModel->getWebSiteInfo($this->languageId);
+ // 其他公共数据
+ // 增加标签显示
+ $metaTitle = $this->systemConfigModel->getMetaTitle($this->languageId,'common');
+ View::assign('meta',$metaTitle);
+ View::assign('nav_info',$navInfo);
+ View::assign('nav_footer_info',$footerNavInfo);
+ View::assign('footer_info',$footerInfo);
+ View::assign('multi_lang',$multiLanguage);
+ View::assign('ver',$version);
+ View::assign('is_dev',Env::get('APP_DEBUG'));
+ View::assign('is_mobile',$this->isMobile());
+ }
+
+ /**
+ * 访问日志监控,提交kafka生产者接口
+ * @return \think\response\Json
+ * @throws \GeoIp2\Exception\AddressNotFoundException
+ * @throws \MaxMind\Db\Reader\InvalidDatabaseException
+ */
+ public function submitActionLog()
+ {
+ $inputData = $this->request->param();
+ $model = explode('//',$inputData['url']);
+ $model = explode('/',$model[1]);
+ $this->apiLog['items'] = Env::get('platform_name','官网');
+ $this->apiLog['forum'] = count($model) > 1 && $model[1] != '' ? $model[1] : 'index';
+ $this->apiLog['forum_code'] = 200;
+ $this->apiLog['url'] = $inputData['url'];
+ $this->apiLog['refer'] = $inputData['url'];
+ $this->apiLog['content'] = $inputData['content'];
+ $this->apiLog['click'] = $inputData['click'];
+ $this->apiLog['start_time'] = date('Y-m-d H:i:s',(int)ceil(($inputData['date_time'] - (int)ceil((int)$inputData['start_time'])) / 1000) );
+ $this->apiLog['date_time'] = date('Y-m-d H:i:s',(int)ceil($inputData['date_time'] / 1000) );
+ //获取应用启动时间
+ //获取访问设备,系统版本,浏览器,设备型号
+ $userAgent = $inputData['drive'];
+ AbstractDeviceParser::setVersionTruncation(AbstractDeviceParser::VERSION_TRUNCATION_NONE);
+ $dd = new DeviceDetector($userAgent);
+ $dd->parse();
+
+ if ($dd->isBot()) {
+ $this->apiLog['brower'] = '未知';
+ $this->apiLog['system'] = '未知';
+ $this->apiLog['drive'] = '未知';
+ $this->apiLog['models'] = '爬虫';
+ } else {
+ $clientInfo = $dd->getClient();
+ $osInfo = $dd->getOs();
+ $device = $dd->getDeviceName();
+ $brand = $dd->getBrandName();
+ $model = $dd->getModel();
+ $this->apiLog['brower'] = !empty($clientInfo) ? $clientInfo['name'].' '.$clientInfo['version'] : '未知';
+ $this->apiLog['system'] = !empty($osInfo) ? $osInfo['name'].' '.$osInfo['version'] : '未知';
+ $this->apiLog['models'] = $device . " " . $brand . " ". $model;
+ $this->apiLog['drive'] = $device;
+ }
+ //解析IP地址,得到国家,城市,地址,
+ $this->apiLog['ip'] = $inputData['ip'];
+
+ if (!filter_var($inputData['ip'],FILTER_VALIDATE_IP,FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE | FILTER_NULL_ON_FAILURE)) {
+ $this->apiLog['country'] = '本地';
+ $this->apiLog['province'] = '本地';
+ $this->apiLog['city'] = '本地';
+ } else {
+ $readerCity = new Reader(public_path() . 'GeoLite2-City.mmdb');
+ $record = $readerCity->city($inputData['ip']);
+ $country = $record->country->names['zh-CN'];
+ $province = $record->subdivisions[0]->names['zh-CN']??'';
+ $city = $record->city->names['zh-CN']??$record->city->names['en'];
+ $china = ['香港','澳门','台湾'];
+ if (in_array($country,$china)) {
+ $province = $city = $country;
+ $country = '中国';
+ }
+
+ $this->apiLog['country'] = $country;
+ $this->apiLog['province'] = $province;
+ $this->apiLog['city'] = $city;
+ }
+// Cache::set('this-api-log',$this->apiLog);
+ // 返回信息前,写入kafka log日志
+ $result = $this->sendLogsToKafkaProduce($this->apiLog,'action_logs',Env::get('database.database'),'add');
+ return $result ? json('提交成功') : json('提交失败',504);
+ }
+}
\ No newline at end of file
diff --git a/app/index/controller/Contact.php b/app/index/controller/Contact.php
new file mode 100644
index 0000000..e31f91a
--- /dev/null
+++ b/app/index/controller/Contact.php
@@ -0,0 +1,37 @@
+model = new \app\index\model\About();
+ }
+
+ /**
+ * 显示资源列表
+ *
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $resource = [];
+// $resource['banner'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-banner');
+// $resource['banner_mobile'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-手机-banner');
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'contact');
+ View::assign('meta',$metaTitle);
+ View::assign('resource',$resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'contact/contact');
+ }
+
+}
diff --git a/app/index/controller/Download.php b/app/index/controller/Download.php
new file mode 100644
index 0000000..19515c8
--- /dev/null
+++ b/app/index/controller/Download.php
@@ -0,0 +1,61 @@
+model = new SoftManualModel();
+ }
+
+ public function index()
+ {
+ $resource = [];
+ $inputData = $this->request->param();
+ $resource['type'] = $this->model->getDownloadType();
+
+ if (isset($inputData['keyword']) && $inputData['keyword'] != '') {
+ $this->vague['name'] = ($inputData['keyword']);
+ }
+// $this->request->pathinfo()
+ if (isset($inputData['file_type_id']) && $inputData['file_type_id'] != '' && $inputData['file_type_id'] != 0) {
+ $this->focus['file_type_id'] = $inputData['file_type_id'];
+ }
+
+ $this->sort['sort'] = 'desc';
+ $this->focus['status'] = "0";
+ $result = $this->model->getAllList($inputData,$this->vague,$this->focus,$this->sort);
+// dump($result);
+ //构建数据
+ if ((isset($result['page']) && !empty($result['page'])) && !empty($result)) {
+ $resource['list'] = $result;
+ } else {
+ if (isset($inputData['keyword']) && $inputData['keyword'] != '') {
+ $this->vague['introduce'] = ($inputData['keyword']);
+ }
+ $result = $this->model->getAllList($inputData,$this->vague,$this->focus,$this->sort);
+ $resource['list'] = $result;
+ }
+
+// dump($this->model->getLastSql());
+// dump($resource);
+// $resource['page'] = $result->render();
+// $resource['list'] = $result->toArray();
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'download');
+ View::assign('meta',$metaTitle);
+ View::assign('resource',$resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'download/download');
+ }
+
+}
diff --git a/app/index/controller/Goods.php b/app/index/controller/Goods.php
new file mode 100644
index 0000000..14f64fe
--- /dev/null
+++ b/app/index/controller/Goods.php
@@ -0,0 +1,105 @@
+model = new \app\index\model\Goods();
+ }
+
+ /**
+ * 显示资源列表
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $resource = [];
+ $query = [];
+ if (isset($inputData['model_number']) && $inputData['model_number'] != '') {
+ $query['model_number'] = $inputData['model_number'];
+ }
+ //分类
+ $resource['category'] = $this->model->getFirstLeveCategory($inputData);
+ $resource['checked1'] = 0;
+ $resource['url'] = explode('.html', $this->request->query())[0];
+ if (isset($inputData['cate1']) && $inputData['cate1'] != '') {
+ $categoryTwo = $this->model->getSecondLevelCategory($inputData);
+ $resource['category_two'] = $categoryTwo;
+ $resource['checked2'] = $inputData['cate2']??0;
+ }
+ if (isset($inputData['cate2']) && $inputData['cate2'] != '') {
+ $categoryThree = $this->model->getThreeLevelCategory($inputData);
+ $resource['category_three'] = $categoryThree;
+ $resource['checked3'] = $inputData['cate3']??0;
+ }
+
+ $forth = [
+ 'is_all','is_recommend','is_hot','is_new'
+ ];
+
+ //
+ $url = 'index/goods/index?';
+ for ($i=1;$i<=3;$i++) {
+ $cate = 'cate'.$i;
+ if (isset($inputData[$cate]) && $inputData[$cate] != '') {
+ $url .= http_build_query([$cate =>$inputData[$cate]])."&";
+ $resource['checked'.$i] = $inputData[$cate];
+ $resource['url'.$i] = rtrim($url, '&');
+ $query['cate'.$i] = $inputData[$cate];
+ }
+ $resource['url'] = rtrim($url, '&');
+ }
+
+
+ $resource['checked4'] = '';
+ foreach ($forth as $fort) {
+ if (isset($inputData[$fort]) && $inputData[$fort] != '') {
+ if ($inputData[$fort] == 1) {
+ $resource['checked4'] = $fort;
+ $query[$fort] = $inputData[$fort];
+ }
+ }
+ }
+ // 查询对应的
+ $goodsPaginate = $this->model->getGoodsList($query, $resource['url']);
+ //dump($goodsPaginate);
+ $resource['page'] = $goodsPaginate->render();
+ $resource['list'] = $goodsPaginate->toArray();
+ // dump($this->model->getLastSql());
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'goods_list');
+ View::assign('meta',$metaTitle);
+ View::assign('resource', $resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'goods/list');
+ }
+
+ /**
+ * 显示资源列表
+ */
+ public function detail()
+ {
+ $inputData = $this->request->param();
+ $resource = [];
+ if (isset($inputData['id']) && $inputData['id'] > 0) {
+ $resource['bread'] = $this->model->getCategoryToParent($inputData['id']);
+// dump($resource);
+ $goodsInfo = $this->model->getInfo($inputData);
+ $goodsInfo['details'] = htmlspecialchars_decode($goodsInfo['details']);
+// dump($goodsInfo);
+ if (empty($goodsInfo) || $goodsInfo['status'] == 1) {
+ View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'goods/404');
+ }
+ }
+ $resource['goodsInfo'] = $goodsInfo;
+// dump($goodsInfo);
+ View::assign('resource', $resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'goods/detail');
+ }
+}
\ No newline at end of file
diff --git a/app/index/controller/Index.php b/app/index/controller/Index.php
new file mode 100644
index 0000000..ea2bcad
--- /dev/null
+++ b/app/index/controller/Index.php
@@ -0,0 +1,53 @@
+model = new IndexModel();
+ parent::initialize();
+ }
+
+ /**
+ * @return string
+ */
+ public function index():string
+ {
+ $inputData = $this->request->param();
+ // banner
+ $bannerList = $this->model->getIndexBanner($this->languageId,$inputData);
+ // 商品banner
+ $goodsBanner = $this->model->getGoodsBanner($this->languageId,$inputData);
+ // 获取推荐商品
+ $bannerListMobile = $this->model->getIndexBannerMobile($this->languageId,$inputData);
+ // 商品分类
+ $goodsCategoryList = $this->model->getIndexGoodsCategoryList($this->languageId,$inputData);
+ // 推荐商品
+ $goodsCommandList = $this->model->getIndexGoodsRecommandList($this->languageId,$inputData);
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'index');
+ // 首页4张图
+ $forthImg = $this->model->getGoodsBanner($this->languageId);
+
+ View::assign('meta',$metaTitle);
+ View::assign('f_image',$forthImg);
+ View::assign('banner_list',$bannerList);
+ View::assign('banner_list_mobile',$bannerListMobile);
+ View::assign('goods_category',$goodsCategoryList);
+ View::assign('goods_is_new',$goodsCommandList);
+ View::assign('goods_banner',$goodsBanner);
+
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'index/index');
+ }
+}
diff --git a/app/index/controller/Join.php b/app/index/controller/Join.php
new file mode 100644
index 0000000..b1fdf4e
--- /dev/null
+++ b/app/index/controller/Join.php
@@ -0,0 +1,78 @@
+model = new JoinModel();
+ parent::initialize();
+ }
+
+ /**
+ * 显示资源列表
+ */
+ public function index():string
+ {
+ $inputData = $this->request->param();
+ $join = [];
+ $join['banner'] = $this->model->getJoinBanner($this->languageId,'加入我们-banner');
+ $join['list'] = $this->model->getJoinList($this->languageId,$inputData);
+ $join['type'] = $this->model->getJoinTypeList($this->languageId,$inputData);
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'join');
+ View::assign('meta',$metaTitle);
+ View::assign('join',$join);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'join/join_us');
+ }
+
+
+ /**
+ * 显示详情资源列表
+ */
+ public function detail():string
+ {
+ $inputData = $this->request->param();
+ //banner
+ $join = $this->model->getInfo($inputData);
+ View::assign('join',$join);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'join/join_detail');
+ }
+
+
+ /**
+ * 更多列表页
+ */
+ public function list():string
+ {
+ $inputData = $this->request->param();
+ $where = [
+ 'site_id' => $this->languageId,
+ 'status' => 0,
+ ];
+ if (isset($inputData['join_type_id']) && $inputData['join_type_id'] != 0) {
+ $where['join_type_id'] = $inputData['join_type_id'];
+ }
+ $listRow = [
+ 'query' => ['join_type_id'=>$inputData['join_type_id']], //url额外参数
+ 'fragment' => '', //url锚点
+ 'var_page' => 'page', //分页变量
+ 'list_rows' => $inputData['size']??4, //每页数量
+ ];
+ $result = $this->model->where($where)->paginate($listRow);
+ View::assign('join',$result->render());
+ View::assign('list',$result->toArray());
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'join/join_list');
+ }
+
+
+}
diff --git a/app/index/controller/News.php b/app/index/controller/News.php
new file mode 100644
index 0000000..9822902
--- /dev/null
+++ b/app/index/controller/News.php
@@ -0,0 +1,62 @@
+model = new NewsModel();
+ parent::initialize();
+ }
+
+
+ /**
+ * 显示资源列表
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $news = [];
+ $news['banner_list'] = $this->model->getNewsBanner($this->languageId,'新闻列表页面-banner');
+ $news['banner_list_mobile'] = $this->model->getNewsBanner($this->languageId,'新闻列表页面-手机-banner');
+
+ $newsPaginate = $this->model->getNewsList($this->languageId,$inputData);
+ $news['page'] = $newsPaginate->render();
+ $news['list'] = $newsPaginate->toArray();
+ $news['type'] = $this->model->getNewsTypeList($this->languageId,$inputData);
+ if (!empty($news['list']['data'])) {
+ foreach ($news['list']['data'] as $key => $item) {
+ $news['list']['data'][$key]['create_time'] = date('Y年m月d日',strtotime($item['create_time']));
+ }
+ }
+ View::assign('news',$news);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'news/news');
+ }
+
+
+ /**
+ * 显示资源列表
+ */
+ public function detail()
+ {
+ $inputData = $this->request->param();
+ //banner
+ $news = $this->model->getInfo($inputData);
+ $news['banner_detail'] = $this->model->getNewsBanner($this->languageId,'新闻详情页面-banner');
+ $news['banner_detail_mobile'] = $this->model->getNewsBanner($this->languageId,'新闻详情页面-手机-banner');
+ $news['create_time'] = date('Y年m月d日',strtotime($news['create_time']));
+ // 获取上一篇下一篇
+ $news['extra'] = $this->model->getPreNexInfo($inputData);
+ View::assign('news',$news);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'news/news_detail');
+ }
+}
diff --git a/app/index/controller/Test.php b/app/index/controller/Test.php
new file mode 100644
index 0000000..865f2a6
--- /dev/null
+++ b/app/index/controller/Test.php
@@ -0,0 +1,37 @@
+model = new \app\index\model\Test();
+ }
+
+ /**
+ * 显示资源列表
+ *
+ */
+ public function index()
+ {
+ $inputData = $this->request->param();
+ $resource = [];
+// $resource['banner'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-banner');
+// $resource['banner_mobile'] = $this->model->getAboutBanner($this->languageId,'关于我们页面-手机-banner');
+ // 增加标签显示
+ $metaTitle = $this->model->getMetaTitle($this->languageId,'about');
+ View::assign('meta',$metaTitle);
+ View::assign('resource',$resource);
+ return View::fetch(Lang::getLangSet().DIRECTORY_SEPARATOR.'about/test');
+ }
+
+}
diff --git a/app/index/event.php b/app/index/event.php
new file mode 100644
index 0000000..4eff890
--- /dev/null
+++ b/app/index/event.php
@@ -0,0 +1,5 @@
+ 'Get list succeeded',
+ '获取列表失败' => 'Failed to get list',
+ '提交成功' => 'Submitted successfully',
+ '提交失败' => 'Submission failed',
+ '分类参数不正确,请检查!' => 'The classification parameters are incorrect, please check!',
+ '获取成功' => 'Get success',
+ '获取失败' => 'Acquisition failed',
+ '新增成功' => 'Successfully added',
+ '新增失败' => 'Failed to add',
+ '修改成功' => 'Modified successfully',
+ '修改失败' => 'Modification failed',
+ '已经提交,不要重新提交' => 'Submitted, do not resubmit',
+ '请选择上传的文件' => 'Submitted, do not resubmit',
+ '上传成功' => 'Upload succeeded',
+ '上传失败' => 'Upload failed',
+ '接口密钥不正确,请检查!' => 'The interface key is incorrect, please check!',
+ '无效的语言包请求' => 'Invalid language pack request',
+ '绑定域名不正确,请检查后台设置' => 'The binding domain is incorrect. Please check the backend settings',
+ "上传失败。文件的最大大小为10MB" => 'Upload failed. The maximum file size is 10MB',
+ '上传失败。文件后缀不允许' => 'Upload failed. File suffix not allowed',
+ '上传失败。文件MIME类型不允许' => 'Upload failed. File MIME type not allowed',
+ '语言包不正确' => 'Incorrect language pack',
+ '平台参数错误' => 'Platform parameter error',
+ '平台不存在,请联系管理员' => 'The platform does not exist, please contact the administrator',
+
+ // Validate Error Message
+ ':attribute require' => ':attribute不能为空',
+ ':attribute must' => ':attribute必须',
+ ':attribute must be numeric' => ':attribute必须是数字',
+ ':attribute must be integer' => ':attribute必须是整数',
+ ':attribute must be float' => ':attribute必须是浮点数',
+ ':attribute must be bool' => ':attribute必须是布尔值',
+ ':attribute not a valid email address' => ':attribute格式不符',
+ ':attribute not a valid mobile' => ':attribute格式不符',
+ ':attribute must be a array' => ':attribute必须是数组',
+ ':attribute must be yes,on or 1' => ':attribute必须是yes、on或者1',
+ ':attribute not a valid datetime' => ':attribute不是一个有效的日期或时间格式',
+ ':attribute not a valid file' => ':attribute不是有效的上传文件',
+ ':attribute not a valid image' => ':attribute不是有效的图像文件',
+ ':attribute must be alpha' => ':attribute只能是字母',
+ ':attribute must be alpha-numeric' => ':attribute只能是字母和数字',
+ ':attribute must be alpha-numeric, dash, underscore' => ':attribute只能是字母、数字和下划线_及破折号-',
+ ':attribute not a valid domain or ip' => ':attribute不是有效的域名或者IP',
+ ':attribute must be chinese' => ':attribute只能是汉字',
+ ':attribute must be chinese or alpha' => ':attribute只能是汉字、字母',
+ ':attribute must be chinese,alpha-numeric' => ':attribute只能是汉字、字母和数字',
+ ':attribute must be chinese,alpha-numeric,underscore, dash' => ':attribute只能是汉字、字母、数字和下划线_及破折号-',
+ ':attribute not a valid url' => ':attribute不是有效的URL地址',
+ ':attribute not a valid ip' => ':attribute不是有效的IP地址',
+ ':attribute must be dateFormat of :rule' => ':attribute必须使用日期格式 :rule',
+ ':attribute must be in :rule' => ':attribute必须在 :rule 范围内',
+ ':attribute be notin :rule' => ':attribute不能在 :rule 范围内',
+ ':attribute must between :1 - :2' => ':attribute只能在 :1 - :2 之间',
+ ':attribute not between :1 - :2' => ':attribute不能在 :1 - :2 之间',
+ 'size of :attribute must be :rule' => ':attribute长度不符合要求 :rule',
+ 'max size of :attribute must be :rule' => ':attribute长度不能超过 :rule',
+ 'min size of :attribute must be :rule' => ':attribute长度不能小于 :rule',
+ ':attribute cannot be less than :rule' => ':attribute日期不能小于 :rule',
+ ':attribute cannot exceed :rule' => ':attribute日期不能超过 :rule',
+ ':attribute not within :rule' => '不在有效期内 :rule',
+ 'access IP is not allowed' => '不允许的IP访问',
+ 'access IP denied' => '禁止的IP访问',
+ ':attribute out of accord with :2' => ':attribute和确认字段:2不一致',
+ ':attribute cannot be same with :2' => ':attribute和比较字段:2不能相同',
+ ':attribute must greater than or equal :rule' => ':attribute必须大于等于 :rule',
+ ':attribute must greater than :rule' => ':attribute必须大于 :rule',
+ ':attribute must less than or equal :rule' => ':attribute必须小于等于 :rule',
+ ':attribute must less than :rule' => ':attribute必须小于 :rule',
+ ':attribute must equal :rule' => ':attribute必须等于 :rule',
+ ':attribute has exists' => ':attribute已存在',
+ ':attribute not conform to the rules' => ':attribute不符合指定规则',
+ 'invalid Request method' => '无效的请求类型',
+ 'invalid token' => '令牌数据无效',
+ 'not conform to the rules' => '规则错误',
+
+];
\ No newline at end of file
diff --git a/app/index/lang/zh-cn.php b/app/index/lang/zh-cn.php
new file mode 100644
index 0000000..84cc327
--- /dev/null
+++ b/app/index/lang/zh-cn.php
@@ -0,0 +1,8 @@
+host();
+ //兼容老数据,1=英文,或者传 us-en, zh-cn,jp
+ $language = $request->param()['language_id']??'zh-cn';
+
+ if ($language == 'zh-cn') {
+ $languageId = 1;
+ } else {
+ if (is_numeric($language)) {
+ show(-999,lang('无效的语言包请求'));
+ }
+ $lang = new Language();
+ $info = $lang->where('code',$language)->where('status',0)->findOrEmpty()->toArray();
+ if (empty($info)) {
+ show(-998,lang('语言包ID不正确'));
+ }
+ $languageId = $info['id'];
+ }
+ // 查找当前品牌所有的语言站点
+ $site = new Site();
+ $domain = [];
+ $languageCode = '';
+ if (Cache::has('site_info')) {
+ $siteInfo = Cache::get('site_info');
+ $languageCode = Cache::get('language_info_'.$languageId) ?: 'zh-cn';
+ $domain = array_column($siteInfo,'domain');
+ } else {
+ $siteInfo = $site->where(['platform_id'=>1,'status'=>0])->select()->toArray();
+ $languageInfo = $site->where(['language_id'=>$languageId,'platform_id'=>1,'status'=>0])->select()->toArray();
+ if (!empty($languageInfo)) {
+ $languageCode = $languageInfo[0]['code'] ?? 'zh-cn';
+ }
+
+ if (!empty($siteInfo)) {
+ $domain = array_column($siteInfo,'domain');
+ }
+ Cache::set('site_info',$siteInfo,7200);
+ Cache::set('language_info_'.$languageId,$languageCode,7200);
+ }
+
+ //检测域名是否合法,添加测试域名
+ $devDomain = ['setmspace.test','setmspace.com','setmspace.cn','dev.setm.f2b211.com'];
+ $domain = array_column($domain,'domain');
+ $wholeDomain = array_merge($devDomain,$domain);
+
+ if (!in_array($url,$wholeDomain)) {
+ //表示请求域名不是绑定的域名,抛出异常
+ show(-995,lang("绑定域名不正确,请检查后台设置"));
+ }
+
+ //老站点英文站兼容密钥
+ $request->platform_id = 1;/*强制为1*/
+ $request->language_id = $languageId;
+ $request->language_code = $languageCode;
+ //组装语言ID请求数据
+ $post = $request->post();
+ $post['language_id'] = $languageId;
+ $request->withPost($post);
+ return $next($request);
+ }
+}
diff --git a/app/index/model/About.php b/app/index/model/About.php
new file mode 100644
index 0000000..5bbd18c
--- /dev/null
+++ b/app/index/model/About.php
@@ -0,0 +1,28 @@
+select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+}
diff --git a/app/index/model/AdvertisePage.php b/app/index/model/AdvertisePage.php
new file mode 100644
index 0000000..c2d94e5
--- /dev/null
+++ b/app/index/model/AdvertisePage.php
@@ -0,0 +1,23 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/AdvertiseSpace.php b/app/index/model/AdvertiseSpace.php
new file mode 100644
index 0000000..dd3a266
--- /dev/null
+++ b/app/index/model/AdvertiseSpace.php
@@ -0,0 +1,25 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'advertise_page_id'=>'int',
+ 'max_num' =>'int',
+ 'width' =>'int',
+ 'height' =>'int',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+}
diff --git a/app/index/model/Advertisement.php b/app/index/model/Advertisement.php
new file mode 100644
index 0000000..0d22fbb
--- /dev/null
+++ b/app/index/model/Advertisement.php
@@ -0,0 +1,31 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'advertise_space_id' =>'int',
+ 'command' =>'string',
+ 'name' =>'string',
+ 'image' =>'string',
+ 'url' =>'string',
+ 'start_time' =>'int',
+ 'stop_time' =>'int',
+ 'play_order' =>'int',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/Attribute.php b/app/index/model/Attribute.php
new file mode 100644
index 0000000..acf5073
--- /dev/null
+++ b/app/index/model/Attribute.php
@@ -0,0 +1,20 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' => 'int',
+ 'name' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+}
diff --git a/app/index/model/BaseModel.php b/app/index/model/BaseModel.php
new file mode 100644
index 0000000..806765b
--- /dev/null
+++ b/app/index/model/BaseModel.php
@@ -0,0 +1,247 @@
+schema);
+ $collection = $this->where(function ($query) use ($data,$fields,$simple,$focus) {
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->order($sort)->select()->toArray();
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ return $collection->order($sort)->select()->toArray();
+ }
+ }
+
+ /**
+ * 获取详情
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getInfo($data)
+ {
+ $result = $this->find($data['id']);
+ return $result ? $result->toArray() : [];
+ }
+
+ /**
+ * 增加数据
+ * @param $data
+ * @return bool
+ */
+ public function addData($data)
+ {
+ return $this->save($data);
+ }
+
+ /**
+ * 编辑数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function editData($data)
+ {
+ $result = $this->find($data['id']);
+ return $result && $result->save($data);
+ }
+
+ /**
+ * 删除数据
+ * @param $id
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function delData($id)
+ {
+ $result = $this->find($id['id']);
+ if ($result) {
+ return $result->delete();
+ }
+ return false;
+ }
+
+ /**
+ * 查询对应ID有没有子项目,比如菜单类,通过ID查询子菜单是否存在
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function checkChildren($data)
+ {
+ $result = $this->where('pid',$data['id'])->find();
+ return (bool)$result;
+ }
+
+ /**
+ * 批量编辑数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function batchEditData($data)
+ {
+ $result = $result1 = true;
+ foreach ($data as $item) {
+ $models = $this->find($item['id']);
+ if ($models) {
+ $result1 = $models->save($item);
+ }
+ $result = $result && $result1;
+ }
+ return $result;
+ }
+
+ /**
+ * 批量删除数据
+ * @param $data
+ * @return bool
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function batchDelData($data)
+ {
+ return $this->destroy($data);
+ }
+
+ /**
+ * 获取最新一条数据
+ * @return array|Model|null
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLatestData($data)
+ {
+ return $this->where($data)->order($this->pk,'desc')->find();
+ }
+
+ /**
+ * 获取语言名称
+ * @param $id
+ * @return string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getLanguageName($id)
+ {
+ $site = Site::find($id);
+ $result = Language::find($site['language_id']);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 获取国家名称
+ * @param $id
+ * @return mixed|string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getCountryName($id)
+ {
+ $result = Country::find($id);
+ return $result ? $result['zh'] : '';
+ }
+
+ /**
+ * 通过ID获取广告位名称
+ * @param $id
+ * @return mixed|string
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAdvertiseSpaceNameById($id)
+ {
+ $result = AdvertiseSpace::find($id);
+ return $result ? $result['name'] : '';
+ }
+
+ /**
+ * 通过广告页ID,获取对应的BANNER
+ * @param $languageId
+ * @param $spaceId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getBanner($languageId,$spaceId):array
+ {
+ $where = [
+ 'site_id' => $languageId,
+ 'advertise_space_id' => $spaceId
+ ];
+ return Advertisement::field(['id','image'])->where($where)->select()->toArray();
+ }
+
+
+ /**
+ * 获取浏览器标签
+ * @param int $languageId
+ * @param string $type
+ * @return array
+ */
+ public function getMetaTitle(int $languageId,string $type) : array
+ {
+ $result = SystemConfig::field('name,value')->where('site_id',$languageId)->where('pos',$type)->column('value','name');
+ if (empty($result)) {
+ return SystemConfig::field('name,value')->where('site_id',$languageId)->where('pos','common')->column('value','name');
+ }
+ return $result;
+ }
+
+}
diff --git a/app/index/model/Brand.php b/app/index/model/Brand.php
new file mode 100644
index 0000000..312f8b1
--- /dev/null
+++ b/app/index/model/Brand.php
@@ -0,0 +1,75 @@
+ $languageId,
+ 'status' => 0,
+ ];
+ if (isset($data['brand_type_id']) && $data['brand_type_id'] != 0) {
+ $where['brand_type_id'] = $data['brand_type_id'];
+ }
+ return $this->where($where)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * 获取品牌矩阵分类
+ * @param $languageId
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getBrandTypeList($languageId,$data):array
+ {
+ $result = BrandType::where('site_id',$languageId)->select()->toArray();
+ if (!empty($result)) {
+ $arr[] = [
+ 'id' => 0,
+ 'name' => '全部',
+ ];
+ $result = array_merge($arr,$result);
+ foreach ($result as $key => $item) {
+ $result[$key]['is_display'] = !empty($data) ? isset($data['brand_type_id']) && $data['brand_type_id'] == $item['id'] : $item['id'] == 0;
+ }
+ return $result;
+ }
+ return [];
+ }
+
+ /**
+ * @param $languageId
+ * @param $data
+ * @return array|string[]
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getBrandBanner($languageId,$data):array
+ {
+ $space = AdvertiseSpace::where('name',$data)->select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+
+}
diff --git a/app/index/model/BrandType.php b/app/index/model/BrandType.php
new file mode 100644
index 0000000..e7b6620
--- /dev/null
+++ b/app/index/model/BrandType.php
@@ -0,0 +1,24 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/Common.php b/app/index/model/Common.php
new file mode 100644
index 0000000..7548ba4
--- /dev/null
+++ b/app/index/model/Common.php
@@ -0,0 +1,14 @@
+select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+}
diff --git a/app/index/model/Goods.php b/app/index/model/Goods.php
new file mode 100644
index 0000000..9a6d600
--- /dev/null
+++ b/app/index/model/Goods.php
@@ -0,0 +1,305 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'main_img' =>'string',
+ 'model_number' =>'string',
+ 'goods_category_id' =>'int',
+ 'price' =>'int',
+ 'is_new' =>'int',
+ 'is_discount' =>'int',
+ 'details' =>'string',
+ 'title' =>'string',
+ 'keywords' =>'string',
+ 'description' =>'string',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+ /**
+ * 商品链接关联模型
+ */
+ public function GoodsBuyNow()
+ {
+ return $this->hasMany(GoodsBuyNow::class);
+ }
+
+ /**
+ * 商品关联商品
+ */
+ public function GoodsConnect()
+ {
+ return $this->hasMany(GoodsConnect::class);
+ }
+
+ /**
+ * 商品手册关联模型
+ * @return \think\model\relation\HasMany
+ */
+ public function GoodsSoftManual()
+ {
+ return $this->hasMany(GoodsSoftManual::class);
+ }
+
+ /**
+ * 商品主图关联模型
+ * @return \think\model\relation\HasMany
+ */
+ public function GoodsImages()
+ {
+ return $this->hasMany(GoodsImages::class);
+ }
+
+ /**
+ * 商品属性关联
+ * @return \think\model\relation\HasMany
+ */
+ public function goodsAttr()
+ {
+ return $this->hasMany(GoodsAttribute::class);
+ }
+
+ /**
+ * 获取父级分类
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFirstLeveCategory($data)
+ {
+ return GoodsCategory::where('pid',0)->where('status',0)->where('site_id',1)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * 获取二级分类
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getSecondLevelCategory($data)
+ {
+ return GoodsCategory::where('pid',$data['cate1'])->where('status',0)->where('site_id',1)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * 获取三级分类
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getThreeLevelCategory($data)
+ {
+ return GoodsCategory::where('pid',$data['cate2'])->where('status',0)->where('site_id',1)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * 获取所有子分类
+ * @param $id
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllSonCategory($id)
+ {
+ $arr = GoodsCategory::where('status',0)->where('site_id',1)->order('sort','desc')->select()->toArray();
+ $feeds = category_to_all_children_id($arr,$id);
+
+ return $feeds;
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @return \think\Paginator
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGoodsList($data,$qstring)
+ {
+ $qs = explode('index/goods/index?',$qstring);
+ parse_str($qs[1],$out);
+
+ $query = $queryOther = [];
+ $forth = [
+ 'is_all','is_recommend','is_hot','is_new'
+ ];
+ foreach ($forth as $f) {
+ if (in_array($f,array_keys($data))) {
+ $queryOther[$f] = $data[$f];
+ }
+ }
+ // 判断是否选择了分类
+ for ($i=1;$i<=3;$i++) {
+ if (isset($data['cate'.$i])) {
+ // 如果是3级分类
+ if ($i === 3 && $data['cate'.$i] != 0) {
+ $query['goods_category_id'] = $data['cate'.$i];
+ }
+ // 如果是2级分类
+ if ($i === 2 && $data['cate'.$i] != 0) {
+ $arr = array_column($this->getThreeLevelCategory(['cate2'=>$data['cate2']]),'id');
+ array_push($arr,(int)$data['cate2']);
+ $query['goods_category_id'] = $arr;
+ }
+ // 如果是1级分类
+ if ($i === 1 && $data['cate'.$i] != 0) {
+ $query['goods_category_id'] = $this->getAllSonCategory($data['cate1']);
+ }
+ }
+ }
+
+ $collection = $this->where('status',0);
+ if (isset($data['model_number'])) {
+ $collection = $collection->where('model_number','like','%'.$data['model_number'].'%')->whereOr('name','like','%'.$data['model_number'].'%')->whereOr('title','like','%'.$data['model_number'].'%');
+ } else {
+ //查询
+ if (!empty($queryOther) && !isset($queryOther['is_all'])) {
+ $collection = $collection->where($queryOther);
+ }
+
+ if (!empty($query) && is_array($query['goods_category_id'])) {
+ // 表示是非3级分类
+ $collection = $collection->whereIn('goods_category_id',$query['goods_category_id']);
+ } else {
+ $collection = $collection->where($query);
+ }
+ }
+
+ $pageNum = SystemConfig::where('pos','goods')->where('name','list_num')->find()->toArray();
+ $listRow = [
+ 'query' => $out, //url额外参数
+ 'fragment' => '', //url锚点
+ 'var_page' => 'page', //分页变量
+ 'list_rows' => (int)$pageNum['value']??4, //每页数量
+ ];
+
+ //return $collection->order('create_time','desc')->paginate($listRow);
+ $resutl = $collection->order('create_time','desc')->paginate($listRow);
+ //dump($this->getLastSql());
+ return $resutl;
+ }
+
+ /**
+ * 通过商品ID,查出所有父级分类
+ */
+ public function getCategoryToParent($id)
+ {
+ $goods = $this->where('id',$id)->find()->toArray();
+ $data = GoodsCategory::where('status',0)->order('sort','desc')->select()->toArray();
+ $arr = category_to_all_pid($data,$goods['goods_category_id']);
+ $arr = GoodsCategory::whereIn('id',$arr)->order('sort','desc')->select()->toArray();
+
+ $url = '';
+ for ($i=0;$i<=count($arr)-1;$i++) {
+ $cate = 'cate'.($i + 1);
+ $url .= http_build_query([$cate =>$arr[$i]['id']])."&";
+ $arr[$i]['qs'] = rtrim($url,'&');
+ }
+ $arr[0]['qs'] = 'cate1='.$arr[0]['id'];
+ return $arr;
+ }
+
+ public function getInfo($data)
+ {
+ $result = $this->where('status',0)->find($data['id']);
+ if ($result) {
+ $goodsAttribute = $result->goodsAttr()->select()->toArray();
+ $attr = $img = [];
+ if ($goodsAttribute) {
+ foreach ($goodsAttribute as $item) {
+ $attr[] = array_merge($item,['attribute_name'=>Attribute::where('id',$item['attribute_id'])->value('name')]);
+ }
+ }
+ $images = $result->goodsImages()->select()->toArray();
+ $connect = $result->goodsConnect()->select()->toArray();
+ if (!empty($connect)) {
+ foreach ($connect as $item) {
+ $res = $this->where('status',0)->find($item['connect_good_id']);
+ if ($item['connect_good_id'] != 0 && $item['connect_good_id'] != '' && $res) {
+ $tmp = $this->where('status',0)->find($item['connect_good_id'])->toArray();
+ $tmp['main_img'] = Env::get('QINIU.cdn').$tmp['main_img'];
+ $connectData[] = array_merge($item,$tmp);
+ }
+ }
+ }
+ //处理相关下载
+ $relate = $result->GoodsSoftManual()->select()->toArray();
+ $newRelate = [];
+ foreach ($relate as $item) {
+ $soft = SoftManual::where('status',0)->find($item['soft_manual_id']);
+ if ($soft) {
+ $btn = SoftManualBtn::where('soft_manual_id',$item['soft_manual_id'])->select()->toArray();
+ $soft = $soft->toArray();
+ $soft['btn'] = $btn;
+ $newRelate[] = array_merge($soft,[]);
+ }
+ }
+
+ if (!empty($newRelate)) {
+ foreach ($newRelate as $key => $item) {
+ $newRelate[$key]['image'] = Env::get('QINIU.cdn').$item['image'];
+ foreach ($item['btn'] as $item1) {
+ $tmp = [
+ 'url' => Env::get('QINIU.cdn').$item1['url'],
+ 'name' => $item1['file_name']
+ ];
+ $arr[$item1['btn_tips']][] = array_merge($tmp,[]);
+ }
+ unset($newRelate[$key]['btn']);
+ $newRelate[$key]['getSoftBtn'] = $arr;
+ $arr = [];
+ }
+ }
+ //处理图片
+ $result['main_img'] = Env::get('QINIU.cdn').$result['main_img'];
+// $img[0] = ['image'=>$result['main_img']];
+ foreach ($images as $item) {
+ $img[] = ['image'=>Env::get('QINIU.cdn').$item['image']];
+ }
+ //
+ $categoryName = GoodsCategory::find($result['goods_category_id']);
+ $result['category_name'] = $categoryName['name'];
+ //buynow
+ $result['buy_now'] = $result->goodsBuyNow()->select()->toArray();
+ $result['goods_attribute'] = $attr;
+ $result['relate_download'] = $newRelate;
+ $result['images'] = empty($img) ? [['image'=>$result['main_img']]] : $img;
+ $result['connect'] = empty($connectData) ? [] : $connectData;
+
+ return $result->toArray();
+ } else {
+ return [];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/index/model/GoodsCategory.php b/app/index/model/GoodsCategory.php
new file mode 100644
index 0000000..9211bc0
--- /dev/null
+++ b/app/index/model/GoodsCategory.php
@@ -0,0 +1,27 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'int',
+ 'desc' =>'int',
+ 'pid' =>'int',
+ 'icon' =>'int',
+ 'sort' =>'int',
+ 'status' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/Index.php b/app/index/model/Index.php
new file mode 100644
index 0000000..5867f97
--- /dev/null
+++ b/app/index/model/Index.php
@@ -0,0 +1,137 @@
+ $languageId,
+ 'advertise_space_id' => 1
+ ];
+ return $this->where($where)->select()->toArray();
+ }
+
+ /**
+ * 首页banner
+ * @param $data
+ * @param $languageId
+ * @return void
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getIndexBannerMobile($languageId,$data):array
+ {
+ $where = [
+ 'site_id' => $languageId,
+ 'advertise_space_id' => 9
+ ];
+ return $this->where($where)->select()->toArray();
+ }
+
+ /**
+ * 获取首页品牌矩阵
+ * @param $data
+ * @param $languageId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getIndexGoodsCategoryList($languageId,$data):array
+ {
+ $where = [
+ 'site_id' => $languageId,
+ 'status' => 0,
+ 'pid' => 0
+ ];
+ return GoodsCategory::where($where)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * @param $languageId
+ * @param $inputData
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getIndexGoodsRecommandList($languageId,$inputData):array
+ {
+ $where = [
+ 'site_id' => $languageId,
+ 'status' => 0,
+ 'is_recommend' => 0
+ ];
+ $isNew = SystemConfig::where('pos','index')->where('name','is_new_num')->find()->toArray();
+ return Goods::where($where)->order('sort','desc')->page(0)->limit((int)$isNew['value'])->select()->toArray();
+ }
+
+
+ /**
+ * @param $languageId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getGoodsBanner($languageId):array
+ {
+ $where = [
+ 'site_id' => $languageId,
+ ];
+ $newData = SystemConfig::field('name,pos,value,image,type')->where($where)->where('pos','index_goods')->column('pos,value,image,type','name');
+ $ret = [
+ 'goods_one' => [
+ 'value' => '',
+ 'image' => ''
+ ],
+ 'goods_two' => [
+ 'value' => '',
+ 'image' => ''
+ ],
+ 'goods_three' => [
+ 'value' => '',
+ 'image' => ''
+ ],
+ 'goods_four' => [
+ 'value' => '',
+ 'image' => ''
+ ],
+ ];
+ if (!empty($newData)) {
+ foreach ($newData as $key => $value) {
+ if ($value['image']) {
+ $images = json_decode($value['image'],true);
+ $newData[$key]['value'] = $value['value']??'';
+ $newData[$key]['image'] = $images[0]['image']??'';
+ } else {
+ $newData[$key]['value'] = '';
+ $newData[$key]['image'] = '';
+ }
+ }
+ return $newData;
+ } else {
+ return $ret;
+ }
+
+ }
+
+}
diff --git a/app/index/model/Join.php b/app/index/model/Join.php
new file mode 100644
index 0000000..64233e9
--- /dev/null
+++ b/app/index/model/Join.php
@@ -0,0 +1,69 @@
+ $languageId,
+ 'status' => 0,
+ ];
+ if (isset($data['join_type_id']) && $data['join_type_id'] != 0) {
+ $where['join_type_id'] = $data['join_type_id'];
+ }
+ return $this->where($where)->order('sort','desc')->select()->toArray();
+ }
+
+ /**
+ * 获取品牌矩阵分类
+ * @param $languageId
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getJoinTypeList($languageId,$data):array
+ {
+ $result = JoinType::where('site_id',$languageId)->select()->toArray();
+ if (!empty($result)) {
+ foreach ($result as $key => $item) {
+ $result[$key]['is_display'] = !empty($data) ? isset($data['join_type_id']) && $data['join_type_id'] == $item['id'] : $item['id'] == 0;
+ }
+ return $result;
+ }
+ return [];
+ }
+
+ /**
+ * @param $languageId
+ * @param $data
+ * @return array|string[]
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getJoinBanner($languageId,$data):array
+ {
+ $space = AdvertiseSpace::where('name',$data)->select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+}
diff --git a/app/index/model/JoinType.php b/app/index/model/JoinType.php
new file mode 100644
index 0000000..4fb0cca
--- /dev/null
+++ b/app/index/model/JoinType.php
@@ -0,0 +1,24 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/Language.php b/app/index/model/Language.php
new file mode 100644
index 0000000..87311be
--- /dev/null
+++ b/app/index/model/Language.php
@@ -0,0 +1,41 @@
+ 'int',
+ 'name' => 'string',
+ 'code' => 'string',
+ 'icon' => 'string',
+ 'locale' => 'string',
+ 'coin' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList($data,$simple = null,$focus = null,$sort = null)
+ {
+ $lang = Site::where('platform_id',$data['platform_id'])->column('language_id');
+ return $this->order($sort)->where('id','in',$lang)->select()->toArray();
+ }
+}
diff --git a/app/index/model/Navigator.php b/app/index/model/Navigator.php
new file mode 100644
index 0000000..84d9778
--- /dev/null
+++ b/app/index/model/Navigator.php
@@ -0,0 +1,83 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'site_id' => 'int',
+ 'language_id' => 'int',
+ 'pid' => 'int',
+ 'name' => 'string',
+ 'desc' => 'string',
+ 'icon' => 'string',
+ 'link' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'is_top' => 'int',
+ 'is_foot' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int'
+ ];
+
+ /**
+ * 获取首页导航菜单
+ * @param $language_id
+ * @param $platform_id
+ * @param $controller
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getNavInfo($language_id,$platform_id,$controller):array
+ {
+ $result = $this->where(function($query) use ($language_id,$platform_id) {
+ $query->where('is_top',0)->where('status',0)->where('platform_id',$platform_id);
+ })->order('sort','desc')->select()->toArray();
+
+ if (!empty($result)) {
+ foreach ($result as $key => $item) {
+ if (isset($controller) && $controller != '') {
+ $url = explode('/',$item['url']);
+ if (count($url) <= 2 && $controller == 'Index') {
+ $result[$key]['is_show'] = true;
+ } else {
+ if (count($url) > 2) {
+ if ($url[2] == Str::snake($controller)) {
+ $result[$key]['is_show'] = true;
+ } else {
+ $result[$key]['is_show'] = false;
+ }
+ } else {
+ $result[$key]['is_show'] = false;
+ }
+ }
+ }
+ }
+ }
+ return $result;
+ }
+
+ /**
+ * 获取首页导航菜单
+ * @param $language_id
+ * @param $platform_id
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFootNavInfo($language_id,$platform_id):array
+ {
+ return $this->where(function($query) use ($language_id,$platform_id) {
+ $query->where('is_foot',0)->where('status',0)->where('platform_id',$platform_id);
+ })->order('sort','desc')->select()->toArray();
+ }
+}
diff --git a/app/index/model/News.php b/app/index/model/News.php
new file mode 100644
index 0000000..93da9f7
--- /dev/null
+++ b/app/index/model/News.php
@@ -0,0 +1,105 @@
+ $languageId,
+ 'status' => 0,
+ ];
+ if (isset($data['news_type_id']) && $data['news_type_id'] != 0) {
+ $where['news_type_id'] = $data['news_type_id'];
+ }
+
+ $listRow = [
+ 'query' => isset($data['news_type_id']) ? ['news_type_id'=>$data['news_type_id']??0] : [], //url额外参数
+ 'fragment' => '', //url锚点
+ 'var_page' => 'page', //分页变量
+ 'list_rows' => $data['size']??6, //每页数量
+ ];
+ return $this->where($where)->order('create_time','desc')->paginate($listRow);
+ }
+
+ /**
+ * 获取品牌矩阵分类
+ * @param $languageId
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getNewsTypeList($languageId,$data):array
+ {
+ $result = NewsType::where('site_id',$languageId)->select()->toArray();
+ if (!empty($result)) {
+ $arr[] = [
+ 'id' => 0,
+ 'name' => '全部新闻',
+ ];
+ $result = array_merge($arr,$result);
+ foreach ($result as $key => $item) {
+ $result[$key]['is_display'] = !empty($data) ? isset($data['news_type_id']) && $data['news_type_id'] == $item['id'] : $item['id'] == 0;
+ }
+ return $result;
+ }
+ return [];
+ }
+
+
+ /**
+ * @param $languageId
+ * @param $data
+ * @return array|string[]
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getNewsBanner($languageId,$data):array
+ {
+ $space = AdvertiseSpace::where('name',$data)->select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+
+ /**
+ * 获取上一篇,下一篇
+ */
+ public function getPreNexInfo($data)
+ {
+ if (isset($data['id'])) {
+ $info = $this->find($data['id'])->toArray();
+ // 下一条
+ $next = $this->field(['id','title'])->where('news_type_id',$info['news_type_id'])->where('id','>',$data['id'])->limit(1)->select()->toArray();
+ // 上一条
+ $pre = $this->field(['id','title'])->where('news_type_id',$info['news_type_id'])->where('id','<',$data['id'])->limit(1)->select()->toArray();
+
+ return [
+ 'pre' => empty($pre) ? [] : $pre[0],
+ 'next' => empty($next) ? [] : $next[0]
+ ];
+ }
+ return [];
+ }
+}
diff --git a/app/index/model/NewsType.php b/app/index/model/NewsType.php
new file mode 100644
index 0000000..9b726f7
--- /dev/null
+++ b/app/index/model/NewsType.php
@@ -0,0 +1,26 @@
+'int',
+ 'platform_id' =>'int',
+ 'site_id' =>'int',
+ 'name' =>'string',
+ 'desc' =>'string',
+ 'icon' =>'string',
+ 'sort' =>'int',
+ 'create_time' =>'int',
+ 'update_time' =>'int',
+ ];
+
+
+}
diff --git a/app/index/model/Platform.php b/app/index/model/Platform.php
new file mode 100644
index 0000000..593aa5e
--- /dev/null
+++ b/app/index/model/Platform.php
@@ -0,0 +1,40 @@
+ 'int',
+ 'vi_color1' => 'string',
+ 'vi_color2' => 'string',
+ 'vi_color3' => 'string',
+ 'language_id' => 'int',
+ 'coin_id' => 'int',
+ 'name' => 'string',
+ 'desc' => 'string',
+ 'icon' => 'string',
+ 'sort' => 'int',
+ 'status' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+ /**
+ * @param string $platformName
+ * @return int
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getPlatformId(string $platformName):int
+ {
+ $result = $this->where('name',$platformName)->find();
+ return $result ? $result->id : 0;
+ }
+}
diff --git a/app/index/model/Product.php b/app/index/model/Product.php
new file mode 100644
index 0000000..1c50d5e
--- /dev/null
+++ b/app/index/model/Product.php
@@ -0,0 +1,27 @@
+select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+}
diff --git a/app/index/model/ReCenter.php b/app/index/model/ReCenter.php
new file mode 100644
index 0000000..48cb750
--- /dev/null
+++ b/app/index/model/ReCenter.php
@@ -0,0 +1,64 @@
+select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+
+ /**
+ * @param $languageId
+ * @param $data
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getResourceList($languageId,$data):array
+ {
+ return $this->where('site_id',$languageId)->where('status',0)->order('sort','desc')->select()->toArray();
+ }
+
+
+ /**
+ * 获取上一篇,下一篇
+ */
+ public function getPreNexInfo($data)
+ {
+ if (isset($data['id'])) {
+ // 下一条
+ $next = $this->field(['id','title'])->where('id','>',$data['id'])->limit(1)->select()->toArray();
+ // 上一条
+ $pre = $this->field(['id','title'])->where('id','<',$data['id'])->limit(1)->select()->toArray();
+
+ return [
+ 'pre' => empty($pre) ? [] : $pre[0],
+ 'next' => empty($next) ? [] : $next[0]
+ ];
+ }
+ return [];
+ }
+
+}
diff --git a/app/index/model/Site.php b/app/index/model/Site.php
new file mode 100644
index 0000000..af7ebb3
--- /dev/null
+++ b/app/index/model/Site.php
@@ -0,0 +1,20 @@
+where('platform_id',$platformId)->column(['domain','language_id']);
+ }
+}
diff --git a/app/index/model/SoftManual.php b/app/index/model/SoftManual.php
new file mode 100644
index 0000000..f929938
--- /dev/null
+++ b/app/index/model/SoftManual.php
@@ -0,0 +1,126 @@
+ 'int',
+ 'platform_id' => 'int',
+ 'site_id' => 'int',
+ 'language_id' => 'int',
+ 'file_type_id' => 'int',
+ 'name' => 'string',
+ 'introduce' => 'string',
+ 'support' => 'string',
+ 'os' => 'string',
+ 'download_count'=> 'int',
+ 'status' => 'int',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+ public function getSoftBtn()
+ {
+ return $this->hasMany(SoftManualBtn::class);
+ }
+
+ /**
+ * 获取列表
+ * @param array $data 查询条件
+ * @param mixed $simple 模糊搜索条件
+ * @param mixed $focus 精准搜索条件
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getAllList($data,$simple = null,$focus = null,$sort = null)
+ {
+ $fields = array_keys($this->schema);
+ $collection = $this->where(function ($query) use ($data,$fields,$simple,$focus) {
+ //模糊查询条件
+ if (!empty($simple)) {
+ foreach ($simple as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->whereOr($key,'like',"%".$item."%");
+ }
+ }
+ }
+ //精准查询
+ if (!empty($focus)) {
+ foreach ($focus as $key => $item) {
+ if (in_array($key,$fields)) {
+ $query->where($key,$item);
+ }
+ }
+ }
+ });
+
+
+
+// $listRow = [
+// 'query' => 'index/download/index', //url额外参数
+// 'fragment' => '', //url锚点
+// 'var_page' => 'page', //分页变量
+// 'list_rows' => $data['size']??4, //每页数量
+// ];
+// return $collection->order($sort)->with('getSoftBtn')->paginate($listRow);
+
+
+ $arr = [];
+ if (isset($data['page']) && isset($data['size'])) {
+ $count = $collection->count() ?: 0;
+ $page = $collection->limit($data['size'])->page($data['page'])->order($sort)->with('getSoftBtn')->select()->toArray();
+// if (!empty($page)) {
+// foreach ($page as $key => $item) {
+// $page[$key]['image'] = Env::get('QINIU.cdn').$item['image'];
+// foreach ($item['getSoftBtn'] as $item1) {
+// $tmp = [
+// 'url' => Env::get('QINIU.cdn').$item1['url'],
+// 'name' => $item1['file_name']
+// ];
+// $arr[$item1['btn_tips']][] = array_merge($tmp,[]);
+// }
+// $page[$key]['getSoftBtn'] = $arr;
+// $arr = [];
+// }
+// }
+ return ['page'=>$page,'count'=>$count];
+ } else {
+ $resData = $collection->order($sort)->with('getSoftBtn')->select()->toArray();
+// dump($resData);
+// if (!empty($resData)) {
+// foreach ($resData as $key => $item) {
+// $resData[$key]['image'] = Env::get('QINIU.cdn').$item['image'];
+// $tmp = [];
+// foreach ($item['getSoftBtn'] as $item1) {
+// $tmp = [
+// 'url' => Env::get('QINIU.cdn').$item1['url'],
+// 'name' => $item1['file_name']
+// ];
+// $arr[$item1['btn_tips']][] = array_merge($tmp,[]);
+// }
+// $resData[$key]['getSoftBtn'] = $arr;
+// }
+// }
+// dump($this->getLastSql());
+ return $resData;
+ }
+ }
+
+
+ /**
+ * 获取分类
+ */
+ public function getDownloadType()
+ {
+ return FileType::select()->toArray();
+ }
+}
diff --git a/app/index/model/SoftManualBtn.php b/app/index/model/SoftManualBtn.php
new file mode 100644
index 0000000..6d864bc
--- /dev/null
+++ b/app/index/model/SoftManualBtn.php
@@ -0,0 +1,19 @@
+ 'int',
+ 'soft_manual_id'=> 'int',
+ 'btn_tips' => 'string',
+ 'url' => 'string',
+ 'file_name' => 'string',
+ 'create_time' => 'int',
+ 'update_time' => 'int',
+ ];
+
+}
diff --git a/app/index/model/SystemConfig.php b/app/index/model/SystemConfig.php
new file mode 100644
index 0000000..a860522
--- /dev/null
+++ b/app/index/model/SystemConfig.php
@@ -0,0 +1,78 @@
+'int',
+ 'platform_id' =>'int',
+ 'language_id' =>'int',
+ 'site_id' =>'int',
+ 'type' =>'int',
+ 'page' =>'string',
+ 'pos' =>'string',
+ 'name' =>'string',
+ 'value' =>'string',
+ 'image' =>'string',
+ 'create_time' =>'int',
+ 'update_time' =>'int'
+ ];
+
+
+ /**
+ * 获取尾部信息
+ * @param $languageId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getFooterInfo($languageId):array
+ {
+ $result = $this->field(['name','value','image'])->where(['site_id'=>$languageId,'pos'=>'footer'])->select()->toArray();
+ if (!empty($result)) {
+ $newData = [];
+ foreach ($result as $value) {
+ if ($value['image']) {
+ $images = json_decode($value['image'],true);
+ $newData[$value['name']]['value'] = $value['value'] != '' ? $value['value'] : $images[0]['image'];
+ } else {
+ $newData[$value['name']]['value'] = '';
+ }
+ }
+ return $newData;
+ }
+ return [];
+ }
+ /**
+ * 获取尾部信息
+ * @param $languageId
+ * @return array
+ * @throws \think\db\exception\DataNotFoundException
+ * @throws \think\db\exception\DbException
+ * @throws \think\db\exception\ModelNotFoundException
+ */
+ public function getWebSiteInfo($languageId):array
+ {
+ $result = $this->field(['name','value','image'])->where(['site_id'=>$languageId,'pos'=>'index'])->select()->toArray();
+ if (!empty($result)) {
+ $newData = [];
+ foreach ($result as $value) {
+ if ($value['image']) {
+ $images = json_decode($value['image'],true);
+ $newData[$value['name']]['value'] = $value['value'] != '' ? $value['value'] : $images[0]['image'];
+ } else {
+ $newData[$value['name']]['value'] = '';
+ }
+ }
+ return $newData;
+ }
+ return [];
+ }
+}
\ No newline at end of file
diff --git a/app/index/model/Test.php b/app/index/model/Test.php
new file mode 100644
index 0000000..2581d00
--- /dev/null
+++ b/app/index/model/Test.php
@@ -0,0 +1,28 @@
+select()->toArray();
+ if (!empty($space)) {
+ return $this->getBanner($languageId,$space[0]['id']);
+ }
+ return ['image' => ''];
+ }
+}
diff --git a/app/index/route/v1.php b/app/index/route/v1.php
new file mode 100644
index 0000000..0b7ca80
--- /dev/null
+++ b/app/index/route/v1.php
@@ -0,0 +1,67 @@
+prefix('\\app\\index\\controller\\')->middleware([
+ app\index\middleware\Auth::class
+]);
\ No newline at end of file
diff --git a/app/index/validate/About.php b/app/index/validate/About.php
new file mode 100644
index 0000000..391defa
--- /dev/null
+++ b/app/index/validate/About.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Brand.php b/app/index/validate/Brand.php
new file mode 100644
index 0000000..b283929
--- /dev/null
+++ b/app/index/validate/Brand.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Common.php b/app/index/validate/Common.php
new file mode 100644
index 0000000..d822401
--- /dev/null
+++ b/app/index/validate/Common.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Concept.php b/app/index/validate/Concept.php
new file mode 100644
index 0000000..f93ba98
--- /dev/null
+++ b/app/index/validate/Concept.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Contact.php b/app/index/validate/Contact.php
new file mode 100644
index 0000000..f69840a
--- /dev/null
+++ b/app/index/validate/Contact.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Join.php b/app/index/validate/Join.php
new file mode 100644
index 0000000..601ea1b
--- /dev/null
+++ b/app/index/validate/Join.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/News.php b/app/index/validate/News.php
new file mode 100644
index 0000000..fc13a48
--- /dev/null
+++ b/app/index/validate/News.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/Product.php b/app/index/validate/Product.php
new file mode 100644
index 0000000..b85f89f
--- /dev/null
+++ b/app/index/validate/Product.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/ReCenter.php b/app/index/validate/ReCenter.php
new file mode 100644
index 0000000..b06d19d
--- /dev/null
+++ b/app/index/validate/ReCenter.php
@@ -0,0 +1,25 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+}
diff --git a/app/index/validate/SoftManual.php b/app/index/validate/SoftManual.php
new file mode 100644
index 0000000..f53b341
--- /dev/null
+++ b/app/index/validate/SoftManual.php
@@ -0,0 +1,41 @@
+ ['规则1','规则2'...]
+ *
+ * @var array
+ */
+ protected $rule = [
+ 'id' => ['require','integer','gt:0'],
+ 'page' => ['integer','gt:0'],
+ 'size' => ['integer','gt:0'],
+ 'site_id' => ['integer','gt:0'],
+ 'file_type_id' => ['integer','gt:0'],
+ 'name' => ['length:1,40'],
+ 'introduce' => ['length:1,255'],
+ 'support' => ['length:1,255'],
+ 'os' => ['length:1,60'],
+ 'download_count'=> ['integer','gt:0'],
+ ];
+
+ /**
+ * 定义错误信息
+ * 格式:'字段名.规则名' => '错误信息'
+ *
+ * @var array
+ */
+ protected $message = [];
+
+ protected $scene = [
+ 'index' => ['page','size','name'],
+ 'read' => ['id'],
+ ];
+}
diff --git a/app/index/view/zh-cn/about/about_us.html b/app/index/view/zh-cn/about/about_us.html
new file mode 100644
index 0000000..9a805a1
--- /dev/null
+++ b/app/index/view/zh-cn/about/about_us.html
@@ -0,0 +1,531 @@
+{include file='zh-cn/common/header' title='关于我们' keywords='关于我们'
+description='关于我们'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 品牌简介
+ Brand Profile
+
+
+ 牛顿定律(NTONPOWER)是深圳市元创时代科技有限公司旗下的全球化科技品牌,成立于2015年,专注于智能充电领域的技术创新。公司以严谨的科学方法和系统性研究为导向,致力于在消费电子充电领域提供创新的技术解决方案。
+
+
+
+
+
+
+
+
+
+
+ 品牌使命
+ Brand Interpretation
+
+
+ 让生活电力十足。Power Up Your Life.
+ 以科学家严谨求真的精神和创新探索的态度,用智能充电科技释放生活的无限可能。
+ ● 安全:智能防护,守护充电瞬间
+ ● 实用:精准设计,满足多元场景
+ ● 创新:突破技术边界,简化使用体验
+
+
+
+
+
+
+
+
+
+
+
+
+ 品牌里程
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 创立初期(2015-2017年)
+ -
+
+ 2015年,牛顿定律(NTONPOWER)成立,专注于智能生活充电产品(如:插线板、充电头)。
+
+
+
+
+ 快速发展期(2018-2021年)
+ -
+
+ 专注智能充电生态,创新覆盖多元应用场景。海外线上销售稳居行业前十,业务覆盖全球30多个国家 ,引领行业创新发展。
+
+
+
+
+ 2022
+ -
+
+ 拓展国内线上电商渠道,加强本土市场品牌认知度。
+
+
+
+
+
+ 2023
+ -
+
+ 插线板全球销量1000万台。
+
+
+
+
+ 2024
+ -
+
+ 用户规模突破海内外用户3500万+、全球社交媒体粉丝60万+。
+
+
+
+
+ 2025
+ -
+
+ 全面进军新消费平台、锂电池和充电宝赛道,构建便携能源生态系统。
+
+
+
+
+
+
+
+
+
+
+
+
+ 所获荣誉
+
+
+
+
+ 旅行便携类 海外TOP 10
+
+
+
+
+
+
+
+
+
+
+ 斩获红点奖、缪斯设计奖
+
+
+
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/index/view/zh-cn/about/mileage.html b/app/index/view/zh-cn/about/mileage.html
new file mode 100644
index 0000000..826e253
--- /dev/null
+++ b/app/index/view/zh-cn/about/mileage.html
@@ -0,0 +1,453 @@
+{include file='zh-cn/common/header' title='关于我们' keywords='关于我们'
+description='关于我们'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+
+
+
+ 品牌里程
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 创立初期(2015-2017年)
+ -
+
+ 2015年,牛顿定律(NTONPOWER)成立,专注于智能生活充电产品(如:插线板、充电头)。
+
+
+
+
+ 快速发展期(2018-2021年)
+ -
+
+ 专注智能充电生态,创新覆盖多元应用场景。海外线上销售稳居行业前十,业务覆盖全球30多个国家 ,引领行业创新发展。
+
+
+
+
+ 2022
+ -
+
+ 拓展国内线上电商渠道,加强本土市场品牌认知度。
+
+
+
+
+
+ 2023
+ -
+
+ 插线板全球销量1000万台。
+
+
+
+
+ 2024
+ -
+
+ 用户规模突破海内外用户3500万+、全球社交媒体粉丝60万+。
+
+
+
+
+ 2025
+ -
+
+ 全面进军新消费平台、锂电池和充电宝赛道,构建便携能源生态系统。
+
+
+
+
+
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/index/view/zh-cn/about/test.html b/app/index/view/zh-cn/about/test.html
new file mode 100644
index 0000000..f153f41
--- /dev/null
+++ b/app/index/view/zh-cn/about/test.html
@@ -0,0 +1,311 @@
+{include file='zh-cn/common/header' title='关于我们' keywords='关于我们'
+description='关于我们'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 品牌简介
+ Brand Profile
+
+
+ 牛顿定律(NTONPOWER)是深圳市元创时代科技有限公司旗下的全球化科技品牌,成立于2015年,专注于智能充电领域的技术创新。公司以严谨的科学方法和系统性研究为导向,致力于在消费电子充电领域提供创新的技术解决方案。
+
+
+
+
+
+
+
+
+
+
+ 品牌使命
+ Brand Interpretation
+
+
+ 让生活电力十足。Power Up Your Life.
+ 以科学家严谨求真的精神和创新探索的态度,用智能充电科技释放生活的无限可能。
+ ● 安全:智能防护,守护充电瞬间
+ ● 实用:精准设计,满足多元场景
+ ● 创新:突破技术边界,简化使用体验
+
+
+
+
+
+
+
+
+
+
+
+
+ 品牌活动
+
+
+
+
+ 旅行便携类 海外TOP 10
+
+
+
+
+
+
+
+
+
+
+ 斩获红点奖、缪斯设计奖
+
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/index/view/zh-cn/common/footer.html b/app/index/view/zh-cn/common/footer.html
new file mode 100644
index 0000000..08010ef
--- /dev/null
+++ b/app/index/view/zh-cn/common/footer.html
@@ -0,0 +1,65 @@
+
+
diff --git a/app/index/view/zh-cn/common/header.html b/app/index/view/zh-cn/common/header.html
new file mode 100644
index 0000000..8bd52a7
--- /dev/null
+++ b/app/index/view/zh-cn/common/header.html
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+ {$meta['meta_title']??''}
+
+
+
+ {if false == $is_dev}
+
+ {/if}
+
+
+
+
+
+
+
+
+
diff --git a/app/index/view/zh-cn/common/nav.html b/app/index/view/zh-cn/common/nav.html
new file mode 100644
index 0000000..f51244f
--- /dev/null
+++ b/app/index/view/zh-cn/common/nav.html
@@ -0,0 +1,146 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/index/view/zh-cn/common/script.html b/app/index/view/zh-cn/common/script.html
new file mode 100644
index 0000000..2eab237
--- /dev/null
+++ b/app/index/view/zh-cn/common/script.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/index/view/zh-cn/contact/contact.html b/app/index/view/zh-cn/contact/contact.html
new file mode 100644
index 0000000..50148dc
--- /dev/null
+++ b/app/index/view/zh-cn/contact/contact.html
@@ -0,0 +1,31 @@
+{include file='zh-cn/common/header' title='联系我们' keywords='联系我们' description='联系我们'} {include file='zh-cn/common/nav'}
+
+
+
+
+
+
+
+
+
+
+
+
+ 400-6696-298
+ 全国统一服务热线
+ 周一至周五:上午9:00 —下午6:00
+
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script'}
diff --git a/app/index/view/zh-cn/download/download.html b/app/index/view/zh-cn/download/download.html
new file mode 100644
index 0000000..61603c9
--- /dev/null
+++ b/app/index/view/zh-cn/download/download.html
@@ -0,0 +1,93 @@
+{include file='zh-cn/common/header' title='服务与支持' keywords='服务与支持' description='服务与支持'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+
+
+
+
+
+ {if count($resource.list) > 0} {foreach $resource.list as $list}
+
+
+
+
+
+
+ {$list.name}
+ {$list.introduce | raw}
+
+
+ 适合型号:
+ {$list.support}
+ 支持系统:
+ {$list.os}
+
+
+ {$list.getSoftBtn.0.btn_tips}
+
+
+
+
+
+ {/foreach} {/if}
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/index/view/zh-cn/goods/detail.html b/app/index/view/zh-cn/goods/detail.html
new file mode 100644
index 0000000..95cfc10
--- /dev/null
+++ b/app/index/view/zh-cn/goods/detail.html
@@ -0,0 +1,90 @@
+{include file='zh-cn/common/header' title='商品详情' keywords='商品详情' description='商品详情'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {foreach $resource.goodsInfo.images as $img}
+
+ {/foreach}
+
+
+
+
+
+ {$resource.goodsInfo.name}
+ {$resource.goodsInfo.description}
+
+
+
+ - 型号:{$resource.goodsInfo.model_number}
+ - 类型:{$resource.goodsInfo.category_name}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {$resource.goodsInfo.details | raw}
+
+
+
+
+ {if count($resource.goodsInfo.goods_attribute) > 0} {foreach $resource.goodsInfo.goods_attribute as $attr}
+
+
+ - {$attr.attribute_name}{$attr.value}
+
+
+ {/foreach} {/if}
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script'}
diff --git a/app/index/view/zh-cn/goods/list.html b/app/index/view/zh-cn/goods/list.html
new file mode 100644
index 0000000..a1ac1c3
--- /dev/null
+++ b/app/index/view/zh-cn/goods/list.html
@@ -0,0 +1,144 @@
+{include file='zh-cn/common/header' title='商品列表' keywords='商品列表' description='商品列表'} {include file='zh-cn/common/nav' }
+
+
+
+
+
+ - 一级分类
+ -
+ {foreach $resource.category as $cate}
+ {$cate.name}
+ {/foreach}
+
+
+
+ - 二级分类
+ -
+ {if !empty($resource.category_two)} {foreach $resource.category_two as $cate2}
+ {$cate2.name}
+ {/foreach} {else}
+
+ {/if}
+
+
+
+ - 三级分类
+ -
+ {if !empty($resource.category_three)} {foreach $resource.category_three as $cate3}
+ {$cate3.name}
+ {/foreach} {else}
+
+ {/if}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {if count($resource.list.data) > 0} {foreach $resource.list.data as $goods}
+
+
+
+
+ {/foreach} {else}
+
+
+
+ 暂无商品
+
+
+ {/if}
+
+
+
+
+
+
+ {$resource.page | raw}
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/index/view/zh-cn/index/index.html b/app/index/view/zh-cn/index/index.html
new file mode 100644
index 0000000..2d946fe
--- /dev/null
+++ b/app/index/view/zh-cn/index/index.html
@@ -0,0 +1,112 @@
+{include file='zh-cn/common/header' title='首页' keywords='首页' description='首页'} {include file='zh-cn/common/nav' }
+
+
+ {foreach $banner_list as $item}
+
+ {/foreach}
+
+
+
+
+
+
+
+ {foreach $nav_info as $item} {if isset($item.children)} {if $item.id === 1} {foreach $item.children as $it1}
+ -
+
+ {$it1.name}
+
+
+ {/foreach} {/if} {/if} {/foreach}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SETMSPACE
+
+ {$f_image['goods_four']['value']??"" | raw }
+
+
+
+
+
+
+
+
+
+
+
+ 新品推荐
+
+
+
+
+ {foreach $goods_is_new as $good}
+
+
+
+
+ {/foreach}
+
+
+
+
+
+
+
+
+{include file='zh-cn/common/footer'} {include file='zh-cn/common/script' }
diff --git a/app/library/KafkaClient.php b/app/library/KafkaClient.php
new file mode 100644
index 0000000..d1a67e2
--- /dev/null
+++ b/app/library/KafkaClient.php
@@ -0,0 +1,151 @@
+kafkaProducerConfig = [
+ 'username' => 'orico',
+ 'password' => 'password',/**/
+ 'broker_list' => '127.0.0.1:9092',/*如果有多个,ip:port,ip2:port,ip3:port*/
+ 'topic' => 'topics'
+ ];
+ }
+
+ /**
+ * 初始化kafka消费配置
+ * @return string[]
+ */
+ private function initKafkaConsumerConfig() :array
+ {
+ return $this->kafkaConsumerConfig = [
+ 'username' => 'orico',
+ 'password' => 'password',/**/
+ 'brokerlist' => '127.0.0.1:9092',/*如果有多个,ip:port,ip2:port,ip3:port*/
+ 'topic' => 'topics'
+ ];
+ }
+
+ /**
+ * kafka 生产者核心方法
+ * @param array $config kafka 配置参数
+ * @param array $data 需要生产的数据
+ */
+ public function kafkaProducer(array $config, array $data)
+ {
+ if (empty($this->kafkaProducerConfig)) {
+ $this->initKafkaProducerConfig();
+ }
+ $conf = new \RdKafka\Conf();
+ $conf->set('sasl.mechanisms', 'PLAIN');
+ $conf->set('security.protocol', 'SASL_PLAINTEXT');
+ $conf->set('sasl.username', $config['username']);
+ $conf->set('sasl.password', $config['password']);
+ $conf->set('socket.keepalive.enable', 'true'); // socket不操作保持长连
+ $conf->set('log.connection.close', 'false'); // 静默所有自发断开连接日志
+ $conf->set('metadata.broker.list', $config['broker_list']);
+
+ $producer = new \RdKafka\Producer($conf);
+
+ $topic = $producer->newTopic($this->topicProduce);
+
+ for ($i = 0; $i < 10; $i++) {
+ $topic->produce(RD_KAFKA_PARTITION_UA, 0,$data);
+ $producer->poll(0);
+ }
+
+ for ($flushRetries = 0; $flushRetries < 10; $flushRetries++) {
+ $result = $producer->flush(10000);
+ if (RD_KAFKA_RESP_ERR_NO_ERROR === $result) {
+ break;
+ }
+ }
+
+ if (RD_KAFKA_RESP_ERR_NO_ERROR !== $result) {
+ throw new \RuntimeException('Was unable to flush, messages might be lost!');
+ }
+
+ }
+
+
+ /**
+ * kafka 消息者核心方法
+ * @param array $config kafka 配置参数
+ * @param array $data 需要生产的数据
+ */
+ public function kafkaConsumer(array $config, array $data)
+ {
+ if (empty($this->kafkaConsumerConfig)) {
+ $this->initKafkaConsumerConfig();
+ }
+ return ($this->kafkaConfig());
+ }
+
+ /**
+ * curl请求
+ * @param $url string 请求的url链接
+ * @param $data string|array|mixed 请求的数据
+ * @param bool $is_post 是否是post请求,默认false
+ * @param array $options 是否附带请求头
+ * @return array|mixed
+ */
+ private function http(string $url, array $data, bool $is_post=false, array $options=[]):array
+ {
+ $data = json_encode($data);
+ $headerArray = [
+ 'Content-type: application/json;charset=utf-8',
+ 'Accept: application/json'
+ ];
+ $curl = curl_init();
+ $arr = [];
+ array_push($arr,$url);
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
+ if ($is_post) {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ }
+ curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ if (!empty($options['cookie'])) {
+ curl_setopt($curl, CURLOPT_COOKIE, $options['cookie']);
+ }
+ $output = curl_exec($curl);
+ $http_status = curl_errno($curl);
+ $http_msg = curl_error($curl);
+ curl_close($curl);
+ if ($http_status == 0) {
+ return json_decode($output, true);
+ } else {
+ return ['status' => $http_status, 'message' => $http_msg, 'data' => []];
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/app/library/LogToKafka.php b/app/library/LogToKafka.php
new file mode 100644
index 0000000..4fde149
--- /dev/null
+++ b/app/library/LogToKafka.php
@@ -0,0 +1,154 @@
+ Env::get('SSO.UC_URL'),
+ 'apiRoute' => '/journal/v1/kafkaproducer/send',
+ 'signStr' => 'logsmonitor',
+ 'secretKey' => 'logsmonitorscretlist',
+ 'dbName' => 'users'
+ ];
+ }
+
+ /**
+ * 发送请求,生成到api日志kafka
+ * @param array $data 请求数据
+ * @param string $logType 日志类型
+ * @param string $database 操作数据库
+ * @param string $dotype 调用接口方式
+ * @return bool
+ */
+ public static function sendLogsToKafkaProduce(array $data, string $logType, string $database, string $dotype):bool
+ {
+ if (empty(self::$sendLogToKafkaConfig)) {
+ self::initLogConfig();
+ }
+ $newData = [
+ 'action_logs' => "",
+ 'api_logs' => "",
+ 'lg_logs_view' => "",
+ 'lg_task_queue' => ""
+ ];
+ //先构建好数据
+ if ($logType != '' && in_array($logType,self::$logType)) {
+ $newData[$logType] = json_encode($data);
+ }
+ //构建数据库
+ if ($database) {
+ $newData['database'] = $database;
+ }
+ //构建写入kafka的类型,
+ if ($dotype != '' && in_array($dotype,self::$methodType)) {
+ $newData['dotype'] = $dotype;
+ }
+ //拿到数据,构建签名
+ $newData['sign'] = self::getSign($newData);
+ //构建请求接口
+ $url = self::$sendLogToKafkaConfig['LogsSSOUrl'].self::$sendLogToKafkaConfig['apiRoute'];
+ $result = self::http($url,$newData,true);
+ Cache::set('$url',$url,300);
+ Cache::set('result',$result,300);
+ if(isset($result['errno']) && $result['errno'] == 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * 签名
+ * @param array $param 用于验证数据完整性
+ * @return string
+ */
+ public static function getSign(array $param):string
+ {
+ ksort($param);
+ $signStr = self::$sendLogToKafkaConfig['signStr'];
+ $secretKey = self::$sendLogToKafkaConfig['secretKey'];
+ foreach ( $param as $key => $value ) {
+ $signStr = $signStr . $key . "=" . $value . "&";
+ }
+ $signStr = substr($signStr, 0, -1);
+ return base64_encode(hash_hmac("sha1", $signStr, $secretKey, true));
+ }
+
+
+ /**
+ * curl请求
+ * @param $url string 请求的url链接
+ * @param $data string|array|mixed 请求的数据
+ * @param bool $is_post 是否是post请求,默认false
+ * @param array $options 是否附带请求头
+ * @return array|mixed
+ */
+ private static function http(string $url, array $data, bool $is_post=false, array $options=[]):array
+ {
+ $data = json_encode($data);
+ $headerArray = [
+ 'Content-type: application/json;charset=utf-8',
+ 'Accept: application/json'
+ ];
+ $curl = curl_init();
+ $arr = [];
+ array_push($arr,$url);
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
+ if ($is_post) {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ }
+ curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ if (!empty($options['cookie'])) {
+ curl_setopt($curl, CURLOPT_COOKIE, $options['cookie']);
+ }
+ $output = curl_exec($curl);
+ $http_status = curl_errno($curl);
+ $http_msg = curl_error($curl);
+ curl_close($curl);
+ if ($http_status == 0) {
+ return json_decode($output, true);
+ } else {
+ return ['status' => $http_status, 'message' => $http_msg, 'data' => []];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/library/SSOApi.php b/app/library/SSOApi.php
new file mode 100644
index 0000000..a4cd039
--- /dev/null
+++ b/app/library/SSOApi.php
@@ -0,0 +1,459 @@
+ '/authorize/token',/*获取应用授权接口*/
+ 'getDeptList' => '/dept/list',/*部门分页数据*/
+ 'getDeptDetail' => '/dept/detail',/*根据ID部门详细*/
+ 'getDeptDetailDeptCode' => '/dept/detail/dept_code',/*根据编码部门详细*/
+ 'getDeptHead' => '/dept/head',/*根据编码获取部门主管*/
+ 'getDeptChainId' => '/dept/chain/id/{id}',/*根据部门ID获取部门上下级*/
+ 'getDeptChainCode' => '/dept/chain/code/{code}',/*根据部门编码获取部门上下级*/
+ 'getStaffList' => '/staff/list',/*员工分页数据*/
+ 'getStaffListDept' => '/staff/list/dept',/*根据部门编码获取员工数据*/
+ 'getUserDetailUid' => '/user/detail/uid',/*根据用户ID获取用户详细*/
+ 'getUserDetailStaffCode' => '/user/detail/staff_code',/*根据用户(员工)编码获取用户(员工)详情*/
+ 'getUserDepts' => '/user/depts',/*根据用户ID获取用户所属部门*/
+ 'getUserDeptsStaffCode' => '/user/depts/staff_code',/*根据用户编码获取用户所属部门*/
+ 'getUserDetailMobile' => '/user/detail/mobile',/*根据手机号获取用户详细*/
+ 'getRoleDetailId' => '/role/detail/id/{id}',/*根据ID获取角色详细*/
+ 'getRoleDetailCode' => '/role/detail/code/{code}',/*根据编码获取角色详细*/
+ 'getMenuListApp' => '/menu/list/app',/*获取应用的菜单*/
+ 'getMenuListUserCode' => '/menu/list/user/{code}',/*获取用户权限菜单*/
+ ];
+
+ /**
+ * 初始化配置,需要手动去.env文件里面填写以下配置项
+ *
+ * [SSO]
+ * UC_URL='https://uc.test'
+ * UC_CACHE_KEY='crm_dev'
+ * APPID='cfcd05b1f3576e90cf53dc8a3d221ff7'
+ * APPSECRET='271491c88ef42303da0251034aee3e5c'
+ * UC_API_VERSION=v1
+ * PUB_KEY='-----BEGIN PUBLIC KEY-----
+ * -----END PUBLIC KEY-----'
+ * PRI_KEY='-----BEGIN PRIVATE KEY-----
+ * -----END PRIVATE KEY-----'
+ *
+ * UC_URL: 单点域名
+ * UC_CACHE_KEY:单点应用 token 缓存key值,用于标识是哪个应用的,比如crm系统,线上使用orico_crm,测试使用 dev_crm,
+ * APPID : 应用ID
+ * APPSECRET:应用密钥
+ */
+ private function initSSOConfig(): array
+ {
+ if (Cache::has('app_get_auth') && Cache::get('app_get_auth') == 1) {
+ return $this->ssoApiConfig = [
+ 'appId' => Cache::get('app')['app_id'],/*应用的APPID*/
+ 'appSecret' => Cache::get('app')['app_secret'],/*应用密钥*/
+ 'ssoApiUrl' => Env::get('SSO.UC_URL'),/*单点请求链接*/
+ 'cacheKey' => Cache::get('app')['uc_cache_key'].'_app_token',/*应用token缓存key*/
+ 'apiVersion' => '/api/'.Env::get('SSO.UC_API_VERSION')/*接口版本*/
+ ];
+ } else {
+ return $this->ssoApiConfig = [
+ 'appId' => Session::get('app')['app_id'],/*应用的APPID*/
+ 'appSecret' => Session::get('app')['app_secret'],/*应用密钥*/
+ 'ssoApiUrl' => Env::get('SSO.UC_URL'),/*单点请求链接*/
+ 'cacheKey' => Session::get('app')['uc_cache_key'].'_app_token',/*应用token缓存key*/
+ 'apiVersion' => '/api/'.Env::get('SSO.UC_API_VERSION')/*接口版本*/
+ ];
+ }
+
+ }
+
+ /**
+ * 生成请求接口
+ * @param array $data 请求数据
+ * @param string $funcName 请求方法名
+ * @param bool $isPost 请求类型,true = post| false = get
+ * @param array $options 请求头
+ * @return array
+ */
+ public function setRequestURI(array $data, string $funcName, bool $isPost = false,array $options = []):array
+ {
+// if (empty($this->ssoApiConfig)) {
+ $this->initSSOConfig();
+// }
+ //设置接口token
+ if (empty($this->appToken) && $funcName != 'getAuthorizeToken') {
+ $this->getAuthorizeToken();
+ }
+
+ $arrToken = [];
+ if ($funcName != 'getAuthorizeToken') {
+ $arrToken['access_token'] = $this->appToken['access_token'];
+ $data['access_token'] = $this->appToken['access_token'];
+ }
+ $params = null;
+ if (false === $isPost) {
+ //get请求
+ if ($funcName == 'getStaffListDept') {
+ $params = '?' . http_build_query($data);
+ } else {
+ $params = '?' . http_build_query($arrToken);
+ }
+ }
+
+ //拼接请求链接
+ $url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$this->apis[$funcName];/*post 请求*/
+
+ if (!is_null($params)) {
+ //get 请求
+ if (false === strpos($this->apis[$funcName],'{')) {
+ $url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$this->apis[$funcName].$params;
+ } else {
+ //解析出参数,restful 接口。 id/{:id}
+ $arr = explode('/{',$this->apis[$funcName]);
+ if (2 === count($arr)) {
+ $param = rtrim($arr[1],'}');
+ $newUrl = $arr[0];
+ $url = $this->ssoApiConfig['ssoApiUrl'].$this->ssoApiConfig['apiVersion'].$newUrl.DIRECTORY_SEPARATOR.$data[$param].$params;
+ }
+
+ }
+ }
+ //执行请求
+ $result = $this->http($url,$data,$isPost,$options);
+// \think\facade\Log::record($url);
+// \think\facade\Log::record(json_encode($result));
+ if (isset($result['status']) && $result['status'] == 200) {
+ return $result['data'];
+ }
+ return [];
+ }
+
+ /**
+ * 获取应用token
+ */
+ public function getAuthorizeToken():array
+ {
+// if (empty($this->ssoApiConfig)) {
+ $this->initSSOConfig();
+// }
+ $data = [
+ 'appid' => $this->ssoApiConfig['appId'],
+ 'app_secret'=> $this->ssoApiConfig['appSecret']
+ ];
+ $this->appToken = Cache::get($this->ssoApiConfig['cacheKey']);
+ if (is_null($this->appToken) || $this->appToken['expires_time'] - time() <= 600) {
+ $data = $this->setRequestURI($data,__FUNCTION__,true);
+ if (!empty($data)) {
+ $data['expires_time'] = time() + $data['expires_in'];
+ Cache::set($this->ssoApiConfig['cacheKey'], $data, $data['expires_in']-1000);
+ $this->appToken = $data;
+ return $data;
+ }
+ }
+ return $this->appToken;
+ }
+
+ /**
+ * 部门分页数据
+ * @param int $page 页码
+ * @param int $size 每页条数
+ * @param array $filter 查询条件,{"keywords":"dept_name=欧洲团"}
+ * @return array
+ */
+ public function getDeptList(int $page = 0,int $size = 0,array $filter = []):array
+ {
+ $data = [];
+
+ if ($page != 0) {
+ $data['page'] = $page;
+ }
+
+ if ($size != 0) {
+ $data['size'] = $size;
+ }
+
+ if (!empty($filter)) {
+ $data['filter'] = $filter;
+ }
+
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据ID部门详细
+ * @param int $deptId 部门ID
+ * @return array
+ */
+ public function getDeptDetail(int $deptId):array
+ {
+ $data = [
+ 'id' => $deptId
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据ID部门详细
+ * @param string $deptCode 部门dept_code
+ * @return array
+ */
+ public function getDeptDetailDeptCode(string $deptCode):array
+ {
+ $data = [
+ 'dept_code' => $deptCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据编码获取部门主管
+ * @param string $deptCode 部门dept_codes
+ * @return array
+ */
+ public function getDeptHead(string $deptCode):array
+ {
+ $data = [
+ 'dept_code' => $deptCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 根据部门ID获取部门上下级
+ * @param int $deptId 部门ID
+ * @return array
+ */
+ public function getDeptChainId(int $deptId):array
+ {
+ $data = [
+ 'id' => $deptId
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 根据部门code获取部门上下级
+ * @param string $deptCode 部门dept_code
+ * @return array
+ */
+ public function getDeptChainCode(string $deptCode):array
+ {
+ $data = [
+ 'code' => $deptCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 员工分页数据
+ * @param int $page 页码
+ * @param int $size 每页条数
+ * @return array
+ */
+ public function getStaffList(int $page = 0,int $size = 0):array
+ {
+ $data = [];
+
+ if ($page != 0) {
+ $data['page'] = $page;
+ }
+
+ if ($size != 0) {
+ $data['size'] = $size;
+ }
+
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据部门编码获取员工数据
+ * @param string $deptCode 部门dept_code
+ * @return array
+ */
+ public function getStaffListDept(string $deptCode):array
+ {
+ $data = [
+ 'dept_code' => $deptCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 根据用户ID获取用户详细
+ * @param int $uid 部门ID
+ * @return array
+ */
+ public function getUserDetailUid(int $uid):array
+ {
+ $data = [
+ 'uid' => $uid
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据用户(员工)编码获取用户(员工)详情
+ * @param string $staffCode 员工staff_code
+ * @return array
+ */
+ public function getUserDetailStaffCode(string $staffCode):array
+ {
+ $data = [
+ 'staff_code' => $staffCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据用户ID获取用户所属部门
+ * @param int $uid 部门ID
+ * @return array
+ */
+ public function getUserDepts(int $uid):array
+ {
+ $data = [
+ 'uid' => $uid
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据用户编码获取用户所属部门
+ * @param string $staffCode 员工staff_code
+ * @return array
+ */
+ public function getUserDeptsStaffCode(string $staffCode):array
+ {
+ $data = [
+ 'staff_code' => $staffCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据手机号获取用户详细
+ * @param string $mobile 手机号
+ * @return array
+ */
+ public function getUserDetailMobile(string $mobile):array
+ {
+ $data = [
+ 'mobile' => $mobile
+ ];
+ return $this->setRequestURI($data,__FUNCTION__,true);
+ }
+
+ /**
+ * 根据ID获取角色详细
+ * @param int $roleId 角色role_id
+ * @return array
+ */
+ public function getRoleDetailId(int $roleId):array
+ {
+ $data = [
+ 'id' => $roleId
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 根据编码获取角色详细
+ * @param string $roleCode 角色role_code
+ * @return array
+ */
+ public function getRoleDetailCode(string $roleCode):array
+ {
+ $data = [
+ 'code' => $roleCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * 获取应用的菜单
+ * @return array
+ */
+ public function getMenuListApp():array
+ {
+ return $this->setRequestURI([],__FUNCTION__);
+ }
+
+ /**
+ * 获取用户权限菜单
+ * @param string $staffCode 用户staff_code
+ * @return array
+ */
+ public function getMenuListUserCode(string $staffCode):array
+ {
+ // 是否是用于检测有没有权限
+ $this->appToken = [];
+
+ $data = [
+ 'code' => $staffCode
+ ];
+ return $this->setRequestURI($data,__FUNCTION__);
+ }
+
+ /**
+ * curl请求
+ * @param $url string 请求的url链接
+ * @param $data string|array|mixed 请求的数据
+ * @param bool $is_post 是否是post请求,默认false
+ * @param array $options 是否附带请求头
+ * @return array|mixed
+ */
+ private function http(string $url, array $data, bool $is_post=false, array $options=[]):array
+ {
+ $data = json_encode($data);
+ $headerArray = [
+ 'Content-type: application/json;charset=utf-8',
+ 'Accept: application/json'
+ ];
+ $curl = curl_init();
+ $arr = [];
+ array_push($arr,$url);
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
+ if ($is_post) {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ }
+ curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ if (!empty($options['cookie'])) {
+ curl_setopt($curl, CURLOPT_COOKIE, $options['cookie']);
+ }
+ $output = curl_exec($curl);
+ $http_status = curl_errno($curl);
+ $http_msg = curl_error($curl);
+ curl_close($curl);
+ if ($http_status == 0) {
+ return json_decode($output, true);
+ } else {
+ return ['status' => $http_status, 'message' => $http_msg, 'data' => []];
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/middleware.php b/app/middleware.php
new file mode 100644
index 0000000..b6ab063
--- /dev/null
+++ b/app/middleware.php
@@ -0,0 +1,10 @@
+ Request::class,
+ 'think\exception\Handle' => ExceptionHandle::class,
+];
diff --git a/app/service.php b/app/service.php
new file mode 100644
index 0000000..db1ee6a
--- /dev/null
+++ b/app/service.php
@@ -0,0 +1,9 @@
+=7.1.0",
+ "topthink/framework": "^6.0.0",
+ "topthink/think-orm": "^2.0",
+ "topthink/think-migration": "^3.0",
+ "topthink/think-multi-app": "^1.0",
+ "topthink/think-captcha": "^3.0",
+ "qiniu/php-sdk": "^7.3",
+ "phpmailer/phpmailer": "^6.4",
+ "phpoffice/phpspreadsheet": "^1.17",
+ "egulias/email-validator": "^3.1",
+ "fcesky/test": "^1.0",
+ "geoip2/geoip2": "~2.0",
+ "matomo/device-detector": "^5.0",
+ "rosell-dk/webp-convert": "^2.9",
+ "baiy/think-async": "^1.0",
+ "topthink/think-view": "^1.0"
+ },
+ "require-dev": {
+ "symfony/var-dumper": "^4.2",
+ "topthink/think-trace":"^1.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "app\\": "app"
+ },
+ "psr-0": {
+ "": "extend/"
+ }
+ },
+ "config": {
+ "preferred-install": "dist"
+ },
+ "scripts": {
+ "post-autoload-dump": [
+ "@php think service:discover",
+ "@php think vendor:publish"
+ ]
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..1eb4be6
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,3847 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "f699ecd893f3ddbe6c52c701d71001d7",
+ "packages": [
+ {
+ "name": "baiy/think-async",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/baiy/think-async.git",
+ "reference": "0b625ac58134ca139d9314c379801f8401ff43bc"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/baiy/think-async/zipball/0b625ac58134ca139d9314c379801f8401ff43bc",
+ "reference": "0b625ac58134ca139d9314c379801f8401ff43bc",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "topthink/think-queue": "^3.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "Baiy\\ThinkAsync\\Service"
+ ],
+ "config": {
+ "async": "src/config.php"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Baiy\\ThinkAsync\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "baiy",
+ "email": "wo@baiy.org"
+ }
+ ],
+ "description": "thinkphp 异步代码执行/异步延迟执行/异步事件订阅",
+ "homepage": "https://github.com/baiy/think-async",
+ "support": {
+ "issues": "https://github.com/baiy/think-async/issues",
+ "source": "https://github.com/baiy/think-async/tree/1.0.1"
+ },
+ "time": "2021-09-26T07:46:39+00:00"
+ },
+ {
+ "name": "composer/ca-bundle",
+ "version": "1.3.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/ca-bundle.git",
+ "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
+ "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpstan/phpstan": "^0.12.55",
+ "psr/log": "^1.0",
+ "symfony/phpunit-bridge": "^4.2 || ^5",
+ "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0 || ^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\CaBundle\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+ "keywords": [
+ "cabundle",
+ "cacert",
+ "certificate",
+ "ssl",
+ "tls"
+ ],
+ "support": {
+ "irc": "irc://irc.freenode.org/composer",
+ "issues": "https://github.com/composer/ca-bundle/issues",
+ "source": "https://github.com/composer/ca-bundle/tree/1.3.1"
+ },
+ "funding": [
+ {
+ "url": "https://packagist.com",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/composer",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-10-28T20:44:15+00:00"
+ },
+ {
+ "name": "doctrine/lexer",
+ "version": "1.2.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/doctrine/lexer.git",
+ "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229",
+ "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "doctrine/coding-standard": "^9.0",
+ "phpstan/phpstan": "^1.3",
+ "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+ "vimeo/psalm": "^4.11"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Guilherme Blanco",
+ "email": "guilhermeblanco@gmail.com"
+ },
+ {
+ "name": "Roman Borschel",
+ "email": "roman@code-factory.org"
+ },
+ {
+ "name": "Johannes Schmitt",
+ "email": "schmittjoh@gmail.com"
+ }
+ ],
+ "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.",
+ "homepage": "https://www.doctrine-project.org/projects/lexer.html",
+ "keywords": [
+ "annotations",
+ "docblock",
+ "lexer",
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/1.2.3"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-02-28T11:07:21+00:00"
+ },
+ {
+ "name": "egulias/email-validator",
+ "version": "3.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/egulias/EmailValidator.git",
+ "reference": "a5ed8d58ed0c340a7c2109f587951b1c84cf6286"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/a5ed8d58ed0c340a7c2109f587951b1c84cf6286",
+ "reference": "a5ed8d58ed0c340a7c2109f587951b1c84cf6286",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "doctrine/lexer": "^1.2",
+ "php": ">=7.2",
+ "symfony/polyfill-intl-idn": "^1.15"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.2",
+ "phpunit/phpunit": "^8.5.8|^9.3.3",
+ "vimeo/psalm": "^4"
+ },
+ "suggest": {
+ "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Egulias\\EmailValidator\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Eduardo Gulias Davis"
+ }
+ ],
+ "description": "A library for validating emails against several RFCs",
+ "homepage": "https://github.com/egulias/EmailValidator",
+ "keywords": [
+ "email",
+ "emailvalidation",
+ "emailvalidator",
+ "validation",
+ "validator"
+ ],
+ "support": {
+ "issues": "https://github.com/egulias/EmailValidator/issues",
+ "source": "https://github.com/egulias/EmailValidator/tree/3.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/egulias",
+ "type": "github"
+ }
+ ],
+ "time": "2022-05-28T22:19:18+00:00"
+ },
+ {
+ "name": "ezyang/htmlpurifier",
+ "version": "v4.14.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/ezyang/htmlpurifier.git",
+ "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
+ "reference": "12ab42bd6e742c70c0a52f7b82477fcd44e64b75",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.2"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "library/HTMLPurifier.composer.php"
+ ],
+ "psr-0": {
+ "HTMLPurifier": "library/"
+ },
+ "exclude-from-classmap": [
+ "/library/HTMLPurifier/Language/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Edward Z. Yang",
+ "email": "admin@htmlpurifier.org",
+ "homepage": "http://ezyang.com"
+ }
+ ],
+ "description": "Standards compliant HTML filter written in PHP",
+ "homepage": "http://htmlpurifier.org/",
+ "keywords": [
+ "html"
+ ],
+ "support": {
+ "issues": "https://github.com/ezyang/htmlpurifier/issues",
+ "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0"
+ },
+ "time": "2021-12-25T01:21:49+00:00"
+ },
+ {
+ "name": "fcesky/test",
+ "version": "v1.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sdftcsdftc/upload_test.git",
+ "reference": "109e2a13fe455f4d66169fb333192d6795ca1cbb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sdftcsdftc/upload_test/zipball/109e2a13fe455f4d66169fb333192d6795ca1cbb",
+ "reference": "109e2a13fe455f4d66169fb333192d6795ca1cbb",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.6.0"
+ },
+ "type": "l",
+ "autoload": {
+ "psr-4": {
+ "FceskyUpload\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "FCesky",
+ "email": "sdftcsdftc@outlook.com"
+ }
+ ],
+ "description": "This is a test package,please use it with caution.",
+ "support": {
+ "issues": "https://github.com/sdftcsdftc/upload_test/issues",
+ "source": "https://github.com/sdftcsdftc/upload_test/tree/v1.0.7"
+ },
+ "time": "2021-03-02T03:05:10+00:00"
+ },
+ {
+ "name": "geoip2/geoip2",
+ "version": "v2.12.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maxmind/GeoIP2-php.git",
+ "reference": "83adb44ac4b9553d36b579a14673ed124583082f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maxmind/GeoIP2-php/zipball/83adb44ac4b9553d36b579a14673ed124583082f",
+ "reference": "83adb44ac4b9553d36b579a14673ed124583082f",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "maxmind-db/reader": "~1.8",
+ "maxmind/web-service-common": "~0.8",
+ "php": ">=7.2"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "3.*",
+ "phpstan/phpstan": "*",
+ "phpunit/phpunit": "^8.0 || ^9.0",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GeoIp2\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Gregory J. Oschwald",
+ "email": "goschwald@maxmind.com",
+ "homepage": "https://www.maxmind.com/"
+ }
+ ],
+ "description": "MaxMind GeoIP2 PHP API",
+ "homepage": "https://github.com/maxmind/GeoIP2-php",
+ "keywords": [
+ "IP",
+ "geoip",
+ "geoip2",
+ "geolocation",
+ "maxmind"
+ ],
+ "support": {
+ "issues": "https://github.com/maxmind/GeoIP2-php/issues",
+ "source": "https://github.com/maxmind/GeoIP2-php/tree/v2.12.2"
+ },
+ "time": "2021-11-30T18:15:25+00:00"
+ },
+ {
+ "name": "league/flysystem",
+ "version": "1.1.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/flysystem.git",
+ "reference": "094defdb4a7001845300334e7c1ee2335925ef99"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/094defdb4a7001845300334e7c1ee2335925ef99",
+ "reference": "094defdb4a7001845300334e7c1ee2335925ef99",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "league/mime-type-detection": "^1.3",
+ "php": "^7.2.5 || ^8.0"
+ },
+ "conflict": {
+ "league/flysystem-sftp": "<1.0.6"
+ },
+ "require-dev": {
+ "phpspec/prophecy": "^1.11.1",
+ "phpunit/phpunit": "^8.5.8"
+ },
+ "suggest": {
+ "ext-ftp": "Allows you to use FTP server storage",
+ "ext-openssl": "Allows you to use FTPS server storage",
+ "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2",
+ "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3",
+ "league/flysystem-azure": "Allows you to use Windows Azure Blob storage",
+ "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching",
+ "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem",
+ "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files",
+ "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib",
+ "league/flysystem-webdav": "Allows you to use WebDAV storage",
+ "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter",
+ "spatie/flysystem-dropbox": "Allows you to use Dropbox storage",
+ "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "Filesystem abstraction: Many filesystems, one API.",
+ "keywords": [
+ "Cloud Files",
+ "WebDAV",
+ "abstraction",
+ "aws",
+ "cloud",
+ "copy.com",
+ "dropbox",
+ "file systems",
+ "files",
+ "filesystem",
+ "filesystems",
+ "ftp",
+ "rackspace",
+ "remote",
+ "s3",
+ "sftp",
+ "storage"
+ ],
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem/issues",
+ "source": "https://github.com/thephpleague/flysystem/tree/1.1.9"
+ },
+ "funding": [
+ {
+ "url": "https://offset.earth/frankdejonge",
+ "type": "other"
+ }
+ ],
+ "time": "2021-12-09T09:40:50+00:00"
+ },
+ {
+ "name": "league/flysystem-cached-adapter",
+ "version": "1.1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/flysystem-cached-adapter.git",
+ "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/flysystem-cached-adapter/zipball/d1925efb2207ac4be3ad0c40b8277175f99ffaff",
+ "reference": "d1925efb2207ac4be3ad0c40b8277175f99ffaff",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "league/flysystem": "~1.0",
+ "psr/cache": "^1.0.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9",
+ "phpspec/phpspec": "^3.4",
+ "phpunit/phpunit": "^5.7",
+ "predis/predis": "~1.0",
+ "tedivm/stash": "~0.12"
+ },
+ "suggest": {
+ "ext-phpredis": "Pure C implemented extension for PHP"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "League\\Flysystem\\Cached\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "frankdejonge",
+ "email": "info@frenky.net"
+ }
+ ],
+ "description": "An adapter decorator to enable meta-data caching.",
+ "support": {
+ "issues": "https://github.com/thephpleague/flysystem-cached-adapter/issues",
+ "source": "https://github.com/thephpleague/flysystem-cached-adapter/tree/master"
+ },
+ "time": "2020-07-25T15:56:04+00:00"
+ },
+ {
+ "name": "league/mime-type-detection",
+ "version": "1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/mime-type-detection.git",
+ "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+ "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-fileinfo": "*",
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^3.2",
+ "phpstan/phpstan": "^0.12.68",
+ "phpunit/phpunit": "^8.5.8 || ^9.3"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "League\\MimeTypeDetection\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Frank de Jonge",
+ "email": "info@frankdejonge.nl"
+ }
+ ],
+ "description": "Mime-type detection for Flysystem",
+ "support": {
+ "issues": "https://github.com/thephpleague/mime-type-detection/issues",
+ "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/frankdejonge",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/league/flysystem",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-17T13:12:02+00:00"
+ },
+ {
+ "name": "maennchen/zipstream-php",
+ "version": "2.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maennchen/ZipStream-PHP.git",
+ "reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/211e9ba1530ea5260b45d90c9ea252f56ec52729",
+ "reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "myclabs/php-enum": "^1.5",
+ "php": "^7.4 || ^8.0",
+ "psr/http-message": "^1.0",
+ "symfony/polyfill-mbstring": "^1.0"
+ },
+ "require-dev": {
+ "ext-zip": "*",
+ "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0",
+ "mikey179/vfsstream": "^1.6",
+ "php-coveralls/php-coveralls": "^2.4",
+ "phpunit/phpunit": "^8.5.8 || ^9.4.2",
+ "vimeo/psalm": "^4.1"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "ZipStream\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Paul Duncan",
+ "email": "pabs@pablotron.org"
+ },
+ {
+ "name": "Jonatan Männchen",
+ "email": "jonatan@maennchen.ch"
+ },
+ {
+ "name": "Jesse Donat",
+ "email": "donatj@gmail.com"
+ },
+ {
+ "name": "András Kolesár",
+ "email": "kolesar@kolesar.hu"
+ }
+ ],
+ "description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
+ "keywords": [
+ "stream",
+ "zip"
+ ],
+ "support": {
+ "issues": "https://github.com/maennchen/ZipStream-PHP/issues",
+ "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/zipstream",
+ "type": "open_collective"
+ }
+ ],
+ "time": "2022-05-18T15:52:06+00:00"
+ },
+ {
+ "name": "markbaker/complex",
+ "version": "3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPComplex.git",
+ "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/ab8bc271e404909db09ff2d5ffa1e538085c0f22",
+ "reference": "ab8bc271e404909db09ff2d5ffa1e538085c0f22",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.2 || ^8.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Complex\\": "classes/src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@lange.demon.co.uk"
+ }
+ ],
+ "description": "PHP Class for working with complex numbers",
+ "homepage": "https://github.com/MarkBaker/PHPComplex",
+ "keywords": [
+ "complex",
+ "mathematics"
+ ],
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPComplex/issues",
+ "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.1"
+ },
+ "time": "2021-06-29T15:32:53+00:00"
+ },
+ {
+ "name": "markbaker/matrix",
+ "version": "3.0.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/MarkBaker/PHPMatrix.git",
+ "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/c66aefcafb4f6c269510e9ac46b82619a904c576",
+ "reference": "c66aefcafb4f6c269510e9ac46b82619a904c576",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.1 || ^8.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpdocumentor/phpdocumentor": "2.*",
+ "phploc/phploc": "^4.0",
+ "phpmd/phpmd": "2.*",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.3",
+ "sebastian/phpcpd": "^4.0",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Matrix\\": "classes/src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Mark Baker",
+ "email": "mark@demon-angel.eu"
+ }
+ ],
+ "description": "PHP Class for working with matrices",
+ "homepage": "https://github.com/MarkBaker/PHPMatrix",
+ "keywords": [
+ "mathematics",
+ "matrix",
+ "vector"
+ ],
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPMatrix/issues",
+ "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.0"
+ },
+ "time": "2021-07-01T19:01:15+00:00"
+ },
+ {
+ "name": "matomo/device-detector",
+ "version": "5.0.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/matomo-org/device-detector.git",
+ "reference": "cd1283126b4cf5081fdc0381b5b5e7849333cfa4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/matomo-org/device-detector/zipball/cd1283126b4cf5081fdc0381b5b5e7849333cfa4",
+ "reference": "cd1283126b4cf5081fdc0381b5b5e7849333cfa4",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "mustangostang/spyc": "*",
+ "php": "^7.2|^8.0"
+ },
+ "replace": {
+ "piwik/device-detector": "self.version"
+ },
+ "require-dev": {
+ "matthiasmullie/scrapbook": "^1.4.7",
+ "mayflower/mo4-coding-standard": "^v8.0.0",
+ "phpstan/phpstan": "^0.12.52",
+ "phpunit/phpunit": "^8.5.8",
+ "psr/cache": "^1.0.1",
+ "psr/simple-cache": "^1.0.1",
+ "symfony/yaml": "^5.1.7"
+ },
+ "suggest": {
+ "doctrine/cache": "Can directly be used for caching purpose",
+ "ext-yaml": "Necessary for using the Pecl YAML parser"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "DeviceDetector\\": ""
+ },
+ "exclude-from-classmap": [
+ "Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "The Matomo Team",
+ "email": "hello@matomo.org",
+ "homepage": "https://matomo.org/team/"
+ }
+ ],
+ "description": "The Universal Device Detection library, that parses User Agents and detects devices (desktop, tablet, mobile, tv, cars, console, etc.), clients (browsers, media players, mobile apps, feed readers, libraries, etc), operating systems, devices, brands and models.",
+ "homepage": "https://matomo.org",
+ "keywords": [
+ "devicedetection",
+ "parser",
+ "useragent"
+ ],
+ "support": {
+ "forum": "https://forum.matomo.org/",
+ "issues": "https://github.com/matomo-org/device-detector/issues",
+ "source": "https://github.com/matomo-org/matomo",
+ "wiki": "https://dev.matomo.org/"
+ },
+ "time": "2022-03-08T09:22:55+00:00"
+ },
+ {
+ "name": "maxmind-db/reader",
+ "version": "v1.11.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maxmind/MaxMind-DB-Reader-php.git",
+ "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maxmind/MaxMind-DB-Reader-php/zipball/b1f3c0699525336d09cc5161a2861268d9f2ae5b",
+ "reference": "b1f3c0699525336d09cc5161a2861268d9f2ae5b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.2"
+ },
+ "conflict": {
+ "ext-maxminddb": "<1.10.1,>=2.0.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "3.*",
+ "php-coveralls/php-coveralls": "^2.1",
+ "phpstan/phpstan": "*",
+ "phpunit/phpcov": ">=6.0.0",
+ "phpunit/phpunit": ">=8.0.0,<10.0.0",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "suggest": {
+ "ext-bcmath": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
+ "ext-gmp": "bcmath or gmp is required for decoding larger integers with the pure PHP decoder",
+ "ext-maxminddb": "A C-based database decoder that provides significantly faster lookups"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "MaxMind\\Db\\": "src/MaxMind/Db"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Gregory J. Oschwald",
+ "email": "goschwald@maxmind.com",
+ "homepage": "https://www.maxmind.com/"
+ }
+ ],
+ "description": "MaxMind DB Reader API",
+ "homepage": "https://github.com/maxmind/MaxMind-DB-Reader-php",
+ "keywords": [
+ "database",
+ "geoip",
+ "geoip2",
+ "geolocation",
+ "maxmind"
+ ],
+ "support": {
+ "issues": "https://github.com/maxmind/MaxMind-DB-Reader-php/issues",
+ "source": "https://github.com/maxmind/MaxMind-DB-Reader-php/tree/v1.11.0"
+ },
+ "time": "2021-10-18T15:23:10+00:00"
+ },
+ {
+ "name": "maxmind/web-service-common",
+ "version": "v0.9.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/maxmind/web-service-common-php.git",
+ "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/maxmind/web-service-common-php/zipball/4dc5a3e8df38aea4ca3b1096cee3a038094e9b53",
+ "reference": "4dc5a3e8df38aea4ca3b1096cee3a038094e9b53",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "composer/ca-bundle": "^1.0.3",
+ "ext-curl": "*",
+ "ext-json": "*",
+ "php": ">=7.2"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "3.*",
+ "phpstan/phpstan": "*",
+ "phpunit/phpunit": "^8.0 || ^9.0",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "MaxMind\\Exception\\": "src/Exception",
+ "MaxMind\\WebService\\": "src/WebService"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "Gregory Oschwald",
+ "email": "goschwald@maxmind.com"
+ }
+ ],
+ "description": "Internal MaxMind Web Service API",
+ "homepage": "https://github.com/maxmind/web-service-common-php",
+ "support": {
+ "issues": "https://github.com/maxmind/web-service-common-php/issues",
+ "source": "https://github.com/maxmind/web-service-common-php/tree/v0.9.0"
+ },
+ "time": "2022-03-28T17:43:20+00:00"
+ },
+ {
+ "name": "mustangostang/spyc",
+ "version": "0.6.3",
+ "source": {
+ "type": "git",
+ "url": "git@github.com:mustangostang/spyc.git",
+ "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/mustangostang/spyc/zipball/4627c838b16550b666d15aeae1e5289dd5b77da0",
+ "reference": "4627c838b16550b666d15aeae1e5289dd5b77da0",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "4.3.*@dev"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.5.x-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "Spyc.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "mustangostang",
+ "email": "vlad.andersen@gmail.com"
+ }
+ ],
+ "description": "A simple YAML loader/dumper class for PHP",
+ "homepage": "https://github.com/mustangostang/spyc/",
+ "keywords": [
+ "spyc",
+ "yaml",
+ "yml"
+ ],
+ "time": "2019-09-10T13:16:29+00:00"
+ },
+ {
+ "name": "myclabs/php-enum",
+ "version": "1.6.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/myclabs/php-enum.git",
+ "reference": "32c4202886c51fbe5cc3a7c34ec5c9a4a790345e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/myclabs/php-enum/zipball/32c4202886c51fbe5cc3a7c34ec5c9a4a790345e",
+ "reference": "32c4202886c51fbe5cc3a7c34ec5c9a4a790345e",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35|^5.7|^6.0",
+ "squizlabs/php_codesniffer": "1.*"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "MyCLabs\\Enum\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP Enum contributors",
+ "homepage": "https://github.com/myclabs/php-enum/graphs/contributors"
+ }
+ ],
+ "description": "PHP Enum implementation",
+ "homepage": "http://github.com/myclabs/php-enum",
+ "keywords": [
+ "enum"
+ ],
+ "support": {
+ "issues": "https://github.com/myclabs/php-enum/issues",
+ "source": "https://github.com/myclabs/php-enum/tree/master"
+ },
+ "time": "2019-02-04T21:18:49+00:00"
+ },
+ {
+ "name": "nesbot/carbon",
+ "version": "2.58.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/briannesbitt/Carbon.git",
+ "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/97a34af22bde8d0ac20ab34b29d7bfe360902055",
+ "reference": "97a34af22bde8d0ac20ab34b29d7bfe360902055",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "php": "^7.1.8 || ^8.0",
+ "symfony/polyfill-mbstring": "^1.0",
+ "symfony/polyfill-php80": "^1.16",
+ "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0"
+ },
+ "require-dev": {
+ "doctrine/dbal": "^2.0 || ^3.0",
+ "doctrine/orm": "^2.7",
+ "friendsofphp/php-cs-fixer": "^3.0",
+ "kylekatarnls/multi-tester": "^2.0",
+ "phpmd/phpmd": "^2.9",
+ "phpstan/extension-installer": "^1.0",
+ "phpstan/phpstan": "^0.12.54 || ^1.0",
+ "phpunit/php-file-iterator": "^2.0.5",
+ "phpunit/phpunit": "^7.5.20 || ^8.5.23",
+ "squizlabs/php_codesniffer": "^3.4"
+ },
+ "bin": [
+ "bin/carbon"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-3.x": "3.x-dev",
+ "dev-master": "2.x-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Carbon\\Laravel\\ServiceProvider"
+ ]
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Carbon\\": "src/Carbon/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Brian Nesbitt",
+ "email": "brian@nesbot.com",
+ "homepage": "https://markido.com"
+ },
+ {
+ "name": "kylekatarnls",
+ "homepage": "https://github.com/kylekatarnls"
+ }
+ ],
+ "description": "An API extension for DateTime that supports 281 different languages.",
+ "homepage": "https://carbon.nesbot.com",
+ "keywords": [
+ "date",
+ "datetime",
+ "time"
+ ],
+ "support": {
+ "docs": "https://carbon.nesbot.com/docs",
+ "issues": "https://github.com/briannesbitt/Carbon/issues",
+ "source": "https://github.com/briannesbitt/Carbon"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/Carbon",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-25T19:31:17+00:00"
+ },
+ {
+ "name": "phpmailer/phpmailer",
+ "version": "v6.6.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPMailer/PHPMailer.git",
+ "reference": "a4bf414da618f22fd9ffd88afd6ed0bc287ab932"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a4bf414da618f22fd9ffd88afd6ed0bc287ab932",
+ "reference": "a4bf414da618f22fd9ffd88afd6ed0bc287ab932",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-filter": "*",
+ "ext-hash": "*",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
+ "doctrine/annotations": "^1.2",
+ "php-parallel-lint/php-console-highlighter": "^0.5.0",
+ "php-parallel-lint/php-parallel-lint": "^1.3.1",
+ "phpcompatibility/php-compatibility": "^9.3.5",
+ "roave/security-advisories": "dev-latest",
+ "squizlabs/php_codesniffer": "^3.6.2",
+ "yoast/phpunit-polyfills": "^1.0.0"
+ },
+ "suggest": {
+ "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses",
+ "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication",
+ "league/oauth2-google": "Needed for Google XOAUTH2 authentication",
+ "psr/log": "For optional PSR-3 debug logging",
+ "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication",
+ "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PHPMailer\\PHPMailer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-2.1-only"
+ ],
+ "authors": [
+ {
+ "name": "Marcus Bointon",
+ "email": "phpmailer@synchromedia.co.uk"
+ },
+ {
+ "name": "Jim Jagielski",
+ "email": "jimjag@gmail.com"
+ },
+ {
+ "name": "Andy Prevost",
+ "email": "codeworxtech@users.sourceforge.net"
+ },
+ {
+ "name": "Brent R. Matzelle"
+ }
+ ],
+ "description": "PHPMailer is a full-featured email creation and transfer class for PHP",
+ "support": {
+ "issues": "https://github.com/PHPMailer/PHPMailer/issues",
+ "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/Synchro",
+ "type": "github"
+ }
+ ],
+ "time": "2022-06-14T08:19:03+00:00"
+ },
+ {
+ "name": "phpoffice/phpspreadsheet",
+ "version": "1.23.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
+ "reference": "21e4cf62699eebf007db28775f7d1554e612ed9e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/21e4cf62699eebf007db28775f7d1554e612ed9e",
+ "reference": "21e4cf62699eebf007db28775f7d1554e612ed9e",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-ctype": "*",
+ "ext-dom": "*",
+ "ext-fileinfo": "*",
+ "ext-gd": "*",
+ "ext-iconv": "*",
+ "ext-libxml": "*",
+ "ext-mbstring": "*",
+ "ext-simplexml": "*",
+ "ext-xml": "*",
+ "ext-xmlreader": "*",
+ "ext-xmlwriter": "*",
+ "ext-zip": "*",
+ "ext-zlib": "*",
+ "ezyang/htmlpurifier": "^4.13",
+ "maennchen/zipstream-php": "^2.1",
+ "markbaker/complex": "^3.0",
+ "markbaker/matrix": "^3.0",
+ "php": "^7.3 || ^8.0",
+ "psr/http-client": "^1.0",
+ "psr/http-factory": "^1.0",
+ "psr/simple-cache": "^1.0 || ^2.0"
+ },
+ "require-dev": {
+ "dealerdirect/phpcodesniffer-composer-installer": "dev-master",
+ "dompdf/dompdf": "^1.0",
+ "friendsofphp/php-cs-fixer": "^3.2",
+ "jpgraph/jpgraph": "^4.0",
+ "mpdf/mpdf": "8.0.17",
+ "phpcompatibility/php-compatibility": "^9.3",
+ "phpstan/phpstan": "^1.1",
+ "phpstan/phpstan-phpunit": "^1.0",
+ "phpunit/phpunit": "^8.5 || ^9.0",
+ "squizlabs/php_codesniffer": "^3.6",
+ "tecnickcom/tcpdf": "^6.4"
+ },
+ "suggest": {
+ "dompdf/dompdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)",
+ "jpgraph/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
+ "mpdf/mpdf": "Option for rendering PDF with PDF Writer",
+ "tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer (doesn't yet support PHP8)"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Maarten Balliauw",
+ "homepage": "https://blog.maartenballiauw.be"
+ },
+ {
+ "name": "Mark Baker",
+ "homepage": "https://markbakeruk.net"
+ },
+ {
+ "name": "Franck Lefevre",
+ "homepage": "https://rootslabs.net"
+ },
+ {
+ "name": "Erik Tilt"
+ },
+ {
+ "name": "Adrien Crivelli"
+ }
+ ],
+ "description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
+ "homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
+ "keywords": [
+ "OpenXML",
+ "excel",
+ "gnumeric",
+ "ods",
+ "php",
+ "spreadsheet",
+ "xls",
+ "xlsx"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
+ "source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.23.0"
+ },
+ "time": "2022-04-24T13:53:10+00:00"
+ },
+ {
+ "name": "psr/cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/cache.git",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Cache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for caching libraries",
+ "keywords": [
+ "cache",
+ "psr",
+ "psr-6"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/cache/tree/master"
+ },
+ "time": "2016-08-06T20:24:11+00:00"
+ },
+ {
+ "name": "psr/container",
+ "version": "1.1.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/container.git",
+ "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
+ "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.4.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Psr\\Container\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common Container Interface (PHP FIG PSR-11)",
+ "homepage": "https://github.com/php-fig/container",
+ "keywords": [
+ "PSR-11",
+ "container",
+ "container-interface",
+ "container-interop",
+ "psr"
+ ],
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.2"
+ },
+ "time": "2021-11-05T16:50:12+00:00"
+ },
+ {
+ "name": "psr/http-client",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-client.git",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^7.0 || ^8.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Client\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP clients",
+ "homepage": "https://github.com/php-fig/http-client",
+ "keywords": [
+ "http",
+ "http-client",
+ "psr",
+ "psr-18"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-client/tree/master"
+ },
+ "time": "2020-06-29T06:28:15+00:00"
+ },
+ {
+ "name": "psr/http-factory",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-factory.git",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.0.0",
+ "psr/http-message": "^1.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for PSR-7 HTTP message factories",
+ "keywords": [
+ "factory",
+ "http",
+ "message",
+ "psr",
+ "psr-17",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/master"
+ },
+ "time": "2019-04-30T12:38:16+00:00"
+ },
+ {
+ "name": "psr/http-message",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/http-message.git",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Http\\Message\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for HTTP messages",
+ "homepage": "https://github.com/php-fig/http-message",
+ "keywords": [
+ "http",
+ "http-message",
+ "psr",
+ "psr-7",
+ "request",
+ "response"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
+ "time": "2016-08-06T14:39:51+00:00"
+ },
+ {
+ "name": "psr/log",
+ "version": "1.1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/log.git",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+ "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\Log\\": "Psr/Log/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "https://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interface for logging libraries",
+ "homepage": "https://github.com/php-fig/log",
+ "keywords": [
+ "log",
+ "psr",
+ "psr-3"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.4"
+ },
+ "time": "2021-05-03T11:20:27+00:00"
+ },
+ {
+ "name": "psr/simple-cache",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/php-fig/simple-cache.git",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Psr\\SimpleCache\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "PHP-FIG",
+ "homepage": "http://www.php-fig.org/"
+ }
+ ],
+ "description": "Common interfaces for simple caching",
+ "keywords": [
+ "cache",
+ "caching",
+ "psr",
+ "psr-16",
+ "simple-cache"
+ ],
+ "support": {
+ "source": "https://github.com/php-fig/simple-cache/tree/master"
+ },
+ "time": "2017-10-23T01:57:42+00:00"
+ },
+ {
+ "name": "qiniu/php-sdk",
+ "version": "v7.6.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/qiniu/php-sdk.git",
+ "reference": "57033fab64c92f8c7ae165222dd958553741e711"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/qiniu/php-sdk/zipball/57033fab64c92f8c7ae165222dd958553741e711",
+ "reference": "57033fab64c92f8c7ae165222dd958553741e711",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "myclabs/php-enum": "1.6.6",
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "paragonie/random_compat": ">=2",
+ "phpunit/phpunit": "~4.0",
+ "squizlabs/php_codesniffer": "~3.6"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/Qiniu/functions.php"
+ ],
+ "psr-4": {
+ "Qiniu\\": "src/Qiniu"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Qiniu",
+ "email": "sdk@qiniu.com",
+ "homepage": "http://www.qiniu.com"
+ }
+ ],
+ "description": "Qiniu Resource (Cloud) Storage SDK for PHP",
+ "homepage": "http://developer.qiniu.com/",
+ "keywords": [
+ "cloud",
+ "qiniu",
+ "sdk",
+ "storage"
+ ],
+ "support": {
+ "issues": "https://github.com/qiniu/php-sdk/issues",
+ "source": "https://github.com/qiniu/php-sdk/tree/v7.6.0"
+ },
+ "time": "2022-06-08T10:05:47+00:00"
+ },
+ {
+ "name": "rosell-dk/exec-with-fallback",
+ "version": "1.2.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/exec-with-fallback.git",
+ "reference": "f88a6b29abd0b580566056b7c1eb0434eb5db20d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/exec-with-fallback/zipball/f88a6b29abd0b580566056b7c1eb0434eb5db20d",
+ "reference": "f88a6b29abd0b580566056b7c1eb0434eb5db20d",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6 | ^7.0 | ^8.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "suggest": {
+ "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "ExecWithFallback\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ }
+ ],
+ "description": "An exec() with fallback to emulations (proc_open, etc)",
+ "keywords": [
+ "command",
+ "exec",
+ "fallback",
+ "open_proc",
+ "resiliant",
+ "sturdy"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/exec-with-fallback/issues",
+ "source": "https://github.com/rosell-dk/exec-with-fallback/tree/1.2.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2021-12-08T12:09:43+00:00"
+ },
+ {
+ "name": "rosell-dk/file-util",
+ "version": "0.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/file-util.git",
+ "reference": "2ff895308c37f448b34b031cfbfd8e45f43936fd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/file-util/zipball/2ff895308c37f448b34b031cfbfd8e45f43936fd",
+ "reference": "2ff895308c37f448b34b031cfbfd8e45f43936fd",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.4",
+ "rosell-dk/exec-with-fallback": "^1.0.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "mikey179/vfsstream": "^1.6",
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "FileUtil\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ }
+ ],
+ "description": "Functions for dealing with files and paths",
+ "keywords": [
+ "files",
+ "path",
+ "util"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/file-util/issues",
+ "source": "https://github.com/rosell-dk/file-util/tree/0.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2022-04-19T10:12:31+00:00"
+ },
+ {
+ "name": "rosell-dk/image-mime-type-guesser",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/image-mime-type-guesser.git",
+ "reference": "72f7040e95a78937ae2edece452530224fcacea6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/image-mime-type-guesser/zipball/72f7040e95a78937ae2edece452530224fcacea6",
+ "reference": "72f7040e95a78937ae2edece452530224fcacea6",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6 | ^7.0 | ^8.0",
+ "rosell-dk/image-mime-type-sniffer": "^1.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "ImageMimeTypeGuesser\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ }
+ ],
+ "description": "Guess mime type of images",
+ "keywords": [
+ "image",
+ "images",
+ "mime",
+ "mime type"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/image-mime-type-guesser/issues",
+ "source": "https://github.com/rosell-dk/image-mime-type-guesser/tree/1.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2022-05-19T09:57:15+00:00"
+ },
+ {
+ "name": "rosell-dk/image-mime-type-sniffer",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/image-mime-type-sniffer.git",
+ "reference": "9ed14cc5d2c14c417660a4dd1946b5f056494691"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/image-mime-type-sniffer/zipball/9ed14cc5d2c14c417660a4dd1946b5f056494691",
+ "reference": "9ed14cc5d2c14c417660a4dd1946b5f056494691",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.4"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "mikey179/vfsstream": "^1.6",
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "ImageMimeTypeSniffer\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ }
+ ],
+ "description": "Sniff mime type (images only)",
+ "keywords": [
+ "image",
+ "images",
+ "mime",
+ "mime type"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/image-mime-type-sniffer/issues",
+ "source": "https://github.com/rosell-dk/image-mime-type-sniffer/tree/1.1.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2022-04-20T14:31:25+00:00"
+ },
+ {
+ "name": "rosell-dk/locate-binaries",
+ "version": "1.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/locate-binaries.git",
+ "reference": "bd2f493383ecd55aa519828dd2898e30f3b9cbb0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/locate-binaries/zipball/bd2f493383ecd55aa519828dd2898e30f3b9cbb0",
+ "reference": "bd2f493383ecd55aa519828dd2898e30f3b9cbb0",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=5.6",
+ "rosell-dk/exec-with-fallback": "^1.0.0",
+ "rosell-dk/file-util": "^0.1.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "LocateBinaries\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ }
+ ],
+ "description": "Locate a binaries by means of exec() or similar",
+ "keywords": [
+ "binary",
+ "discover",
+ "locate",
+ "whereis",
+ "which"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/locate-binaries/issues",
+ "source": "https://github.com/rosell-dk/locate-binaries/tree/1.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2022-04-20T07:20:07+00:00"
+ },
+ {
+ "name": "rosell-dk/webp-convert",
+ "version": "2.9.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/rosell-dk/webp-convert.git",
+ "reference": "5ccba85ebe3b28ae229459fd0baed25314616ac9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/rosell-dk/webp-convert/zipball/5ccba85ebe3b28ae229459fd0baed25314616ac9",
+ "reference": "5ccba85ebe3b28ae229459fd0baed25314616ac9",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": "^5.6 | ^7.0 | ^8.0",
+ "rosell-dk/exec-with-fallback": "^1.0.0",
+ "rosell-dk/image-mime-type-guesser": "^1.1.1",
+ "rosell-dk/locate-binaries": "^1.0"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "^2.11",
+ "phpstan/phpstan": "^1.5",
+ "phpunit/phpunit": "^9.3",
+ "squizlabs/php_codesniffer": "3.*"
+ },
+ "suggest": {
+ "ext-gd": "to use GD extension for converting. Note: Gd must be compiled with webp support",
+ "ext-imagick": "to use Imagick extension for converting. Note: Gd must be compiled with webp support",
+ "ext-vips": "to use Vips extension for converting.",
+ "php-stan/php-stan": "Suggested for dev, in order to analyse code before committing"
+ },
+ "type": "library",
+ "extra": {
+ "scripts-descriptions": {
+ "ci": "Run tests before CI",
+ "phpcs": "Checks coding styles (PSR2) of file/dir, which you must supply. To check all, supply 'src'",
+ "phpcbf": "Fix coding styles (PSR2) of file/dir, which you must supply. To fix all, supply 'src'",
+ "cs-fix-all": "Fix the coding style of all the source files, to comply with the PSR-2 coding standard",
+ "cs-fix": "Fix the coding style of a PHP file or directory, which you must specify.",
+ "test": "Launches the preconfigured PHPUnit"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "WebPConvert\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bjørn Rosell",
+ "homepage": "https://www.bitwise-it.dk/contact",
+ "role": "Project Author"
+ },
+ {
+ "name": "Martin Folkers",
+ "homepage": "https://twobrain.io",
+ "role": "Collaborator"
+ }
+ ],
+ "description": "Convert JPEG & PNG to WebP with PHP",
+ "keywords": [
+ "Webp",
+ "cwebp",
+ "gd",
+ "image conversion",
+ "images",
+ "imagick",
+ "jpg",
+ "jpg2webp",
+ "png",
+ "png2webp"
+ ],
+ "support": {
+ "issues": "https://github.com/rosell-dk/webp-convert/issues",
+ "source": "https://github.com/rosell-dk/webp-convert/tree/2.9.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/rosell-dk",
+ "type": "github"
+ },
+ {
+ "url": "https://ko-fi.com/rosell",
+ "type": "ko_fi"
+ }
+ ],
+ "time": "2022-05-19T13:56:36+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-idn",
+ "version": "v1.25.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-idn.git",
+ "reference": "749045c69efb97c70d25d7463abba812e91f3a44"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44",
+ "reference": "749045c69efb97c70d25d7463abba812e91f3a44",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1",
+ "symfony/polyfill-intl-normalizer": "^1.10",
+ "symfony/polyfill-php72": "^1.10"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.23-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Idn\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Laurent Bassin",
+ "email": "laurent@bassin.info"
+ },
+ {
+ "name": "Trevor Rowbotham",
+ "email": "trevor.rowbotham@pm.me"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "idn",
+ "intl",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-09-14T14:02:44+00:00"
+ },
+ {
+ "name": "symfony/polyfill-intl-normalizer",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+ "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "suggest": {
+ "ext-intl": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for intl's Normalizer class and related functions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "intl",
+ "normalizer",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-mbstring",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "provide": {
+ "ext-mbstring": "*"
+ },
+ "suggest": {
+ "ext-mbstring": "For best performance"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Mbstring\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill for the Mbstring extension",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "mbstring",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php72",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php72.git",
+ "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2",
+ "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php72\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-24T11:49:31+00:00"
+ },
+ {
+ "name": "symfony/polyfill-php80",
+ "version": "v1.26.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/polyfill-php80.git",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "1.26-dev"
+ },
+ "thanks": {
+ "name": "symfony/polyfill",
+ "url": "https://github.com/symfony/polyfill"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ],
+ "psr-4": {
+ "Symfony\\Polyfill\\Php80\\": ""
+ },
+ "classmap": [
+ "Resources/stubs"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ion Bazan",
+ "email": "ion.bazan@gmail.com"
+ },
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "compatibility",
+ "polyfill",
+ "portable",
+ "shim"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-10T07:21:04+00:00"
+ },
+ {
+ "name": "symfony/process",
+ "version": "v4.4.41",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/process.git",
+ "reference": "9eedd60225506d56e42210a70c21bb80ca8456ce"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/process/zipball/9eedd60225506d56e42210a70c21bb80ca8456ce",
+ "reference": "9eedd60225506d56e42210a70c21bb80ca8456ce",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Component\\Process\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Executes commands in sub-processes",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v4.4.41"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-04-04T10:19:07+00:00"
+ },
+ {
+ "name": "symfony/translation",
+ "version": "v6.0.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation.git",
+ "reference": "9ba011309943955a3807b8236c17cff3b88f67b6"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation/zipball/9ba011309943955a3807b8236c17cff3b88f67b6",
+ "reference": "9ba011309943955a3807b8236c17cff3b88f67b6",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=8.0.2",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/translation-contracts": "^2.3|^3.0"
+ },
+ "conflict": {
+ "symfony/config": "<5.4",
+ "symfony/console": "<5.4",
+ "symfony/dependency-injection": "<5.4",
+ "symfony/http-kernel": "<5.4",
+ "symfony/twig-bundle": "<5.4",
+ "symfony/yaml": "<5.4"
+ },
+ "provide": {
+ "symfony/translation-implementation": "2.3|3.0"
+ },
+ "require-dev": {
+ "psr/log": "^1|^2|^3",
+ "symfony/config": "^5.4|^6.0",
+ "symfony/console": "^5.4|^6.0",
+ "symfony/dependency-injection": "^5.4|^6.0",
+ "symfony/finder": "^5.4|^6.0",
+ "symfony/http-client-contracts": "^1.1|^2.0|^3.0",
+ "symfony/http-kernel": "^5.4|^6.0",
+ "symfony/intl": "^5.4|^6.0",
+ "symfony/polyfill-intl-icu": "^1.21",
+ "symfony/service-contracts": "^1.1.2|^2|^3",
+ "symfony/yaml": "^5.4|^6.0"
+ },
+ "suggest": {
+ "psr/log-implementation": "To use logging capability in translator",
+ "symfony/config": "",
+ "symfony/yaml": ""
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\Translation\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Fabien Potencier",
+ "email": "fabien@symfony.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides tools to internationalize your application",
+ "homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/translation/tree/v6.0.9"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-06T14:27:17+00:00"
+ },
+ {
+ "name": "symfony/translation-contracts",
+ "version": "v3.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/translation-contracts.git",
+ "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9",
+ "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=8.0.2"
+ },
+ "suggest": {
+ "symfony/translation-implementation": ""
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-main": "3.0-dev"
+ },
+ "thanks": {
+ "name": "symfony/contracts",
+ "url": "https://github.com/symfony/contracts"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Symfony\\Contracts\\Translation\\": ""
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Generic abstractions related to translation",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "abstractions",
+ "contracts",
+ "decoupling",
+ "interfaces",
+ "interoperability",
+ "standards"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-01-02T09:55:41+00:00"
+ },
+ {
+ "name": "topthink/framework",
+ "version": "v6.0.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/framework.git",
+ "reference": "e478316ac843c1a884a3b3a7a94db17c4001ff5c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/framework/zipball/e478316ac843c1a884a3b3a7a94db17c4001ff5c",
+ "reference": "e478316ac843c1a884a3b3a7a94db17c4001ff5c",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-mbstring": "*",
+ "league/flysystem": "^1.1.4",
+ "league/flysystem-cached-adapter": "^1.0",
+ "php": ">=7.2.5",
+ "psr/container": "~1.0",
+ "psr/http-message": "^1.0",
+ "psr/log": "~1.0",
+ "psr/simple-cache": "^1.0",
+ "topthink/think-helper": "^3.1.1",
+ "topthink/think-orm": "^2.0"
+ },
+ "require-dev": {
+ "guzzlehttp/psr7": "^2.1.0",
+ "mikey179/vfsstream": "^1.6",
+ "mockery/mockery": "^1.2",
+ "phpunit/phpunit": "^7.0"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [],
+ "psr-4": {
+ "think\\": "src/think/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ },
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "The ThinkPHP Framework.",
+ "homepage": "http://thinkphp.cn/",
+ "keywords": [
+ "framework",
+ "orm",
+ "thinkphp"
+ ],
+ "support": {
+ "issues": "https://github.com/top-think/framework/issues",
+ "source": "https://github.com/top-think/framework/tree/v6.0.12"
+ },
+ "time": "2022-01-21T06:31:07+00:00"
+ },
+ {
+ "name": "topthink/think-captcha",
+ "version": "v3.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-captcha.git",
+ "reference": "a450602932a5d9ba183e288b79921ba3b9a92331"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-captcha/zipball/a450602932a5d9ba183e288b79921ba3b9a92331",
+ "reference": "a450602932a5d9ba183e288b79921ba3b9a92331",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "topthink/framework": "^6.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\captcha\\CaptchaService"
+ ],
+ "config": {
+ "captcha": "src/config.php"
+ }
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/helper.php"
+ ],
+ "psr-4": {
+ "think\\captcha\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "captcha package for thinkphp",
+ "support": {
+ "issues": "https://github.com/top-think/think-captcha/issues",
+ "source": "https://github.com/top-think/think-captcha/tree/v3.0.7"
+ },
+ "time": "2022-04-23T02:38:14+00:00"
+ },
+ {
+ "name": "topthink/think-helper",
+ "version": "v3.1.6",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-helper.git",
+ "reference": "769acbe50a4274327162f9c68ec2e89a38eb2aff"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-helper/zipball/769acbe50a4274327162f9c68ec2e89a38eb2aff",
+ "reference": "769acbe50a4274327162f9c68ec2e89a38eb2aff",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "src/helper.php"
+ ],
+ "psr-4": {
+ "think\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "The ThinkPHP6 Helper Package",
+ "support": {
+ "issues": "https://github.com/top-think/think-helper/issues",
+ "source": "https://github.com/top-think/think-helper/tree/v3.1.6"
+ },
+ "time": "2021-12-15T04:27:55+00:00"
+ },
+ {
+ "name": "topthink/think-migration",
+ "version": "v3.0.3",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-migration.git",
+ "reference": "5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-migration/zipball/5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79",
+ "reference": "5717d9e5f3ea745f6dbfd1e30b4402aaadff9a79",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "topthink/framework": "^6.0.0",
+ "topthink/think-helper": "^3.0.3"
+ },
+ "require-dev": {
+ "fzaninotto/faker": "^1.8"
+ },
+ "suggest": {
+ "fzaninotto/faker": "Required to use the factory builder (^1.8)."
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\migration\\Service"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Phinx\\": "phinx/src/Phinx",
+ "think\\migration\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/top-think/think-migration/issues",
+ "source": "https://github.com/top-think/think-migration/tree/v3.0.3"
+ },
+ "time": "2020-12-07T05:54:22+00:00"
+ },
+ {
+ "name": "topthink/think-multi-app",
+ "version": "v1.0.14",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-multi-app.git",
+ "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-multi-app/zipball/ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
+ "reference": "ccaad7c2d33f42cb1cc2a78d6610aaec02cea4c3",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/framework": "^6.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\app\\Service"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "think\\app\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "thinkphp6 multi app support",
+ "support": {
+ "issues": "https://github.com/top-think/think-multi-app/issues",
+ "source": "https://github.com/top-think/think-multi-app/tree/master"
+ },
+ "time": "2020-07-12T13:50:37+00:00"
+ },
+ {
+ "name": "topthink/think-orm",
+ "version": "v2.0.52",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-orm.git",
+ "reference": "407a60658f37fc57422ab95a9922c6f69af90f46"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-orm/zipball/407a60658f37fc57422ab95a9922c6f69af90f46",
+ "reference": "407a60658f37fc57422ab95a9922c6f69af90f46",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "ext-pdo": "*",
+ "php": ">=7.1.0",
+ "psr/log": "~1.0",
+ "psr/simple-cache": "^1.0",
+ "topthink/think-helper": "^3.1"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^7|^8|^9.5"
+ },
+ "type": "library",
+ "autoload": {
+ "files": [
+ "stubs/load_stubs.php"
+ ],
+ "psr-4": {
+ "think\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "think orm",
+ "keywords": [
+ "database",
+ "orm"
+ ],
+ "support": {
+ "issues": "https://github.com/top-think/think-orm/issues",
+ "source": "https://github.com/top-think/think-orm/tree/v2.0.52"
+ },
+ "time": "2022-01-25T06:00:05+00:00"
+ },
+ {
+ "name": "topthink/think-queue",
+ "version": "v3.0.7",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-queue.git",
+ "reference": "cded7616e313f9daa55c0ad0de5791f0d1fb3066"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-queue/zipball/cded7616e313f9daa55c0ad0de5791f0d1fb3066",
+ "reference": "cded7616e313f9daa55c0ad0de5791f0d1fb3066",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "ext-json": "*",
+ "nesbot/carbon": "^2.16",
+ "symfony/process": "^4.2",
+ "topthink/framework": "^6.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.2",
+ "phpunit/phpunit": "^6.2",
+ "topthink/think-migration": "^3.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\queue\\Service"
+ ],
+ "config": {
+ "queue": "src/config.php"
+ }
+ }
+ },
+ "autoload": {
+ "files": [
+ "src/common.php"
+ ],
+ "psr-4": {
+ "think\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "yunwuxin",
+ "email": "448901948@qq.com"
+ }
+ ],
+ "description": "The ThinkPHP6 Queue Package",
+ "support": {
+ "issues": "https://github.com/top-think/think-queue/issues",
+ "source": "https://github.com/top-think/think-queue/tree/v3.0.7"
+ },
+ "time": "2021-12-20T08:04:36+00:00"
+ },
+ {
+ "name": "topthink/think-template",
+ "version": "v2.0.8",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-template.git",
+ "reference": "abfc293f74f9ef5127b5c416310a01fe42e59368"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-template/zipball/abfc293f74f9ef5127b5c416310a01fe42e59368",
+ "reference": "abfc293f74f9ef5127b5c416310a01fe42e59368",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "psr/simple-cache": "^1.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "the php template engine",
+ "support": {
+ "issues": "https://github.com/top-think/think-template/issues",
+ "source": "https://github.com/top-think/think-template/tree/v2.0.8"
+ },
+ "time": "2020-12-10T07:52:03+00:00"
+ },
+ {
+ "name": "topthink/think-view",
+ "version": "v1.0.14",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-view.git",
+ "reference": "edce0ae2c9551ab65f9e94a222604b0dead3576d"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-view/zipball/edce0ae2c9551ab65f9e94a222604b0dead3576d",
+ "reference": "edce0ae2c9551ab65f9e94a222604b0dead3576d",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/think-template": "^2.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "think\\view\\driver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "thinkphp template driver",
+ "support": {
+ "issues": "https://github.com/top-think/think-view/issues",
+ "source": "https://github.com/top-think/think-view/tree/v1.0.14"
+ },
+ "time": "2019-11-06T11:40:13+00:00"
+ }
+ ],
+ "packages-dev": [
+ {
+ "name": "symfony/var-dumper",
+ "version": "v4.4.42",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/symfony/var-dumper.git",
+ "reference": "742aab50ad097bcb62d91fccb613f66b8047d2ca"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/symfony/var-dumper/zipball/742aab50ad097bcb62d91fccb613f66b8047d2ca",
+ "reference": "742aab50ad097bcb62d91fccb613f66b8047d2ca",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.3",
+ "symfony/polyfill-mbstring": "~1.0",
+ "symfony/polyfill-php72": "~1.5",
+ "symfony/polyfill-php80": "^1.16"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0",
+ "symfony/console": "<3.4"
+ },
+ "require-dev": {
+ "ext-iconv": "*",
+ "symfony/console": "^3.4|^4.0|^5.0",
+ "symfony/process": "^4.4|^5.0",
+ "twig/twig": "^1.43|^2.13|^3.0.4"
+ },
+ "suggest": {
+ "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
+ "ext-intl": "To show region name in time zone dump",
+ "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
+ },
+ "bin": [
+ "Resources/bin/var-dump-server"
+ ],
+ "type": "library",
+ "autoload": {
+ "files": [
+ "Resources/functions/dump.php"
+ ],
+ "psr-4": {
+ "Symfony\\Component\\VarDumper\\": ""
+ },
+ "exclude-from-classmap": [
+ "/Tests/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nicolas Grekas",
+ "email": "p@tchwork.com"
+ },
+ {
+ "name": "Symfony Community",
+ "homepage": "https://symfony.com/contributors"
+ }
+ ],
+ "description": "Provides mechanisms for walking through any arbitrary PHP variable",
+ "homepage": "https://symfony.com",
+ "keywords": [
+ "debug",
+ "dump"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/var-dumper/tree/v4.4.42"
+ },
+ "funding": [
+ {
+ "url": "https://symfony.com/sponsor",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/fabpot",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2022-05-21T10:00:54+00:00"
+ },
+ {
+ "name": "topthink/think-trace",
+ "version": "v1.4",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/top-think/think-trace.git",
+ "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/top-think/think-trace/zipball/9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
+ "reference": "9a9fa8f767b6c66c5a133ad21ca1bc96ad329444",
+ "shasum": "",
+ "mirrors": [
+ {
+ "url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
+ "preferred": true
+ }
+ ]
+ },
+ "require": {
+ "php": ">=7.1.0",
+ "topthink/framework": "^6.0.0"
+ },
+ "type": "library",
+ "extra": {
+ "think": {
+ "services": [
+ "think\\trace\\Service"
+ ],
+ "config": {
+ "trace": "src/config.php"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "think\\trace\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "Apache-2.0"
+ ],
+ "authors": [
+ {
+ "name": "liu21st",
+ "email": "liu21st@gmail.com"
+ }
+ ],
+ "description": "thinkphp debug trace",
+ "support": {
+ "issues": "https://github.com/top-think/think-trace/issues",
+ "source": "https://github.com/top-think/think-trace/tree/v1.4"
+ },
+ "time": "2020-06-29T05:27:28+00:00"
+ }
+ ],
+ "aliases": [],
+ "minimum-stability": "stable",
+ "stability-flags": [],
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": {
+ "php": ">=7.1.0"
+ },
+ "platform-dev": [],
+ "plugin-api-version": "2.3.0"
+}
diff --git a/config/app.php b/config/app.php
new file mode 100644
index 0000000..8c15313
--- /dev/null
+++ b/config/app.php
@@ -0,0 +1,32 @@
+ env('app.host', ''),
+ // 应用的命名空间
+ 'app_namespace' => '',
+ // 是否启用路由
+ 'with_route' => true,
+ // 默认应用
+ 'default_app' => 'index',
+ // 默认时区
+ 'default_timezone' => 'Asia/Shanghai',
+
+ // 应用映射(自动多应用模式有效)
+ 'app_map' => [],
+ // 域名绑定(自动多应用模式有效)
+ 'domain_bind' => [],
+ // 禁止URL访问的应用列表(自动多应用模式有效)
+ 'deny_app_list' => [],
+
+ // 异常页面的模板文件
+ 'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
+
+ // 错误显示信息,非调试模式有效
+ 'error_message' => '页面错误!请稍后再试~',
+ // 显示错误信息
+ 'show_error_msg' => true,
+];
diff --git a/config/async.php b/config/async.php
new file mode 100644
index 0000000..ae72195
--- /dev/null
+++ b/config/async.php
@@ -0,0 +1,31 @@
+ 'async_exec_method',
+ // 异步执行自定义队列
+ 'async_exec_method_custom_queue' => [
+ 'async_exec_method_custom' => '自定义异步执行队列',
+ ],
+
+ // 异步订阅默认队列名称
+ 'subscribe_default_queue' => 'subscribe_default',
+ // 异步订阅事件获取类
+ 'subscribe_event_get_class' => ConfigFileEventGetter::class,
+ // 异步订阅事件配置(可通过修改`subscribe_event_get_class`改变配置来源)
+ 'subscribe_event_config' => [
+ [
+ 'name' => 'demo',
+ 'title' => '演示事件',
+ 'queue' => 'async_subscribe_demo', // 事件处理队列 为空使用异步订阅默认队列
+
+ // 事件订阅者配置
+ 'subscriber' => [
+ [DemoSubscriber::class, 'handle'],
+ ]
+ ]
+ ]
+];
\ No newline at end of file
diff --git a/config/cache.php b/config/cache.php
new file mode 100644
index 0000000..f12267d
--- /dev/null
+++ b/config/cache.php
@@ -0,0 +1,38 @@
+ env('cache.driver', 'redis'),
+
+ // 缓存连接方式配置
+ 'stores' => [
+ 'file' => [
+ // 驱动方式
+ 'type' => 'File',
+ // 缓存保存目录
+ 'path' => '',
+ // 缓存前缀
+ 'prefix' => '',
+ // 缓存有效期 0表示永久缓存
+ 'expire' => 0,
+ // 缓存标签前缀
+ 'tag_prefix' => 'tag:',
+ // 序列化机制 例如 ['serialize', 'unserialize']
+ 'serialize' => [],
+ ],
+ 'redis' => [
+ 'type' => 'redis',
+ 'host' => Env::get('redis.host'),
+ 'port' => Env::get('redis.port'),
+ 'password' => Env::get('redis.pass'),
+ 'select' => Env::get('redis.select'),
+ ]
+ // 更多的缓存连接
+ ],
+];
diff --git a/config/captcha.php b/config/captcha.php
new file mode 100644
index 0000000..9bbf529
--- /dev/null
+++ b/config/captcha.php
@@ -0,0 +1,39 @@
+ 5,
+ // 验证码字符集合
+ 'codeSet' => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',
+ // 验证码过期时间
+ 'expire' => 1800,
+ // 是否使用中文验证码
+ 'useZh' => false,
+ // 是否使用算术验证码
+ 'math' => false,
+ // 是否使用背景图
+ 'useImgBg' => false,
+ //验证码字符大小
+ 'fontSize' => 25,
+ // 是否使用混淆曲线
+ 'useCurve' => true,
+ //是否添加杂点
+ 'useNoise' => true,
+ // 验证码字体 不设置则随机
+ 'fontttf' => '',
+ //背景颜色
+ 'bg' => [243, 251, 254],
+ // 验证码图片高度
+ 'imageH' => 0,
+ // 验证码图片宽度
+ 'imageW' => 0,
+
+ // 添加额外的验证码设置
+ // verify => [
+ // 'length'=>4,
+ // ...
+ //],
+];
diff --git a/config/console.php b/config/console.php
new file mode 100644
index 0000000..a818a98
--- /dev/null
+++ b/config/console.php
@@ -0,0 +1,9 @@
+ [
+ ],
+];
diff --git a/config/cookie.php b/config/cookie.php
new file mode 100644
index 0000000..9c4732a
--- /dev/null
+++ b/config/cookie.php
@@ -0,0 +1,20 @@
+ 0,
+ // cookie 保存路径
+ 'path' => '/',
+ // cookie 有效域名
+ 'domain' => '',
+ // cookie 启用安全传输
+ 'secure' => true,
+ // httponly设置
+ 'httponly' => false,
+ // 是否使用 setcookie
+ 'setcookie' => true,
+ // samesite 设置,支持 'strict' 'lax'
+ 'samesite' => '',
+];
diff --git a/config/database.php b/config/database.php
new file mode 100644
index 0000000..1686f59
--- /dev/null
+++ b/config/database.php
@@ -0,0 +1,59 @@
+ env('database.driver', 'mysql'),
+
+ // 自定义时间查询规则
+ 'time_query_rule' => [],
+
+ // 自动写入时间戳字段
+ // true为自动识别类型 false关闭
+ // 字符串则明确指定时间字段类型 支持 int timestamp datetime date
+ 'auto_timestamp' => true,
+
+ // 时间字段取出后的默认时间格式
+ 'datetime_format' => 'Y-m-d H:i:s',
+
+ // 数据库连接配置信息
+ 'connections' => [
+ 'mysql' => [
+ // 数据库类型
+ 'type' => env('database.type', 'mysql'),
+ // 服务器地址
+ 'hostname' => env('database.hostname', '127.0.0.1'),
+ // 数据库名
+ 'database' => env('database.database', ''),
+ // 用户名
+ 'username' => env('database.username', 'root'),
+ // 密码
+ 'password' => env('database.password', ''),
+ // 端口
+ 'hostport' => env('database.hostport', '3306'),
+ // 数据库连接参数
+ 'params' => [],
+ // 数据库编码默认采用utf8
+ 'charset' => env('database.charset', 'utf8'),
+ // 数据库表前缀
+ 'prefix' => env('database.prefix', ''),
+
+ // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
+ 'deploy' => 0,
+ // 数据库读写是否分离 主从式有效
+ 'rw_separate' => false,
+ // 读写分离后 主服务器数量
+ 'master_num' => 1,
+ // 指定从服务器序号
+ 'slave_no' => '',
+ // 是否严格检查字段是否存在
+ 'fields_strict' => true,
+ // 是否需要断线重连
+ 'break_reconnect' => false,
+ // 监听SQL
+ 'trigger_sql' => env('app_debug', true),
+ // 开启字段缓存
+ 'fields_cache' => false,
+ ]
+ // 更多的数据库配置信息
+ ],
+];
diff --git a/config/filesystem.php b/config/filesystem.php
new file mode 100644
index 0000000..965297e
--- /dev/null
+++ b/config/filesystem.php
@@ -0,0 +1,24 @@
+ env('filesystem.driver', 'local'),
+ // 磁盘列表
+ 'disks' => [
+ 'local' => [
+ 'type' => 'local',
+ 'root' => app()->getRuntimePath() . 'storage',
+ ],
+ 'public' => [
+ // 磁盘类型
+ 'type' => 'local',
+ // 磁盘路径
+ 'root' => app()->getRootPath() . 'public/storage',
+ // 磁盘路径对应的外部URL路径
+ 'url' => '/storage',
+ // 可见性
+ 'visibility' => 'public',
+ ],
+ // 更多的磁盘配置信息
+ ],
+];
diff --git a/config/lang.php b/config/lang.php
new file mode 100644
index 0000000..6b00300
--- /dev/null
+++ b/config/lang.php
@@ -0,0 +1,27 @@
+ env('lang.default_lang', ''),
+ // 允许的语言列表
+ 'allow_lang_list' => [],
+ // 多语言自动侦测变量名
+ 'detect_var' => 'lang',
+ // 是否使用Cookie记录
+ 'use_cookie' => false,
+ // 多语言cookie变量
+ 'cookie_var' => '',
+ // 多语言header变量
+ 'header_var' => '',
+ // 扩展语言包
+ 'extend_list' => [],
+ // Accept-Language转义为对应语言包名称
+ 'accept_language' => [
+// 'zh-hans-cn' => 'zh-cn',
+ ],
+ // 是否支持语言分组
+ 'allow_group' => false,
+];
diff --git a/config/log.php b/config/log.php
new file mode 100644
index 0000000..ea24ff9
--- /dev/null
+++ b/config/log.php
@@ -0,0 +1,45 @@
+ env('log.channel', 'file'),
+ // 日志记录级别
+ 'level' => [],
+ // 日志类型记录的通道 ['error'=>'email',...]
+ 'type_channel' => [],
+ // 关闭全局日志写入
+ 'close' => false,
+ // 全局日志处理 支持闭包
+ 'processor' => null,
+
+ // 日志通道列表
+ 'channels' => [
+ 'file' => [
+ // 日志记录方式
+ 'type' => 'File',
+ // 日志保存目录
+ 'path' => '',
+ // 单文件日志写入
+ 'single' => false,
+ // 独立日志级别
+ 'apart_level' => [],
+ // 最大日志文件数量
+ 'max_files' => 0,
+ // 使用JSON格式记录
+ 'json' => false,
+ // 日志处理
+ 'processor' => null,
+ // 关闭通道日志写入
+ 'close' => false,
+ // 日志输出格式化
+ 'format' => '[%s][%s] %s',
+ // 是否实时写入
+ 'realtime_write' => false,
+ ],
+ // 其它日志通道配置
+ ],
+
+];
diff --git a/config/middleware.php b/config/middleware.php
new file mode 100644
index 0000000..7e1972f
--- /dev/null
+++ b/config/middleware.php
@@ -0,0 +1,8 @@
+ [],
+ // 优先级设置,此数组中的中间件会按照数组中的顺序优先执行
+ 'priority' => [],
+];
diff --git a/config/queue.php b/config/queue.php
new file mode 100644
index 0000000..10988b3
--- /dev/null
+++ b/config/queue.php
@@ -0,0 +1,41 @@
+
+// +----------------------------------------------------------------------
+
+use think\facade\Env;
+
+return [
+ 'default' => 'redis',
+ 'connections' => [
+ 'sync' => [
+ 'type' => 'sync',
+ ],
+ 'database' => [
+ 'type' => 'database',
+ 'queue' => 'default',
+ 'table' => 'jobs',
+ 'connection' => null,
+ ],
+ 'redis' => [
+ 'type' => 'redis',
+ 'queue' => 'default',
+ 'host' => Env::get('redis.host'),
+ 'port' => Env::get('redis.port'),
+ 'password' => Env::get('redis.pass'),
+ 'select' => Env::get('redis.select'),
+ 'timeout' => 0,
+ 'persistent' => false,
+ ],
+ ],
+ 'failed' => [
+ 'type' => 'none',
+ 'table' => 'failed_jobs',
+ ],
+];
diff --git a/config/route.php b/config/route.php
new file mode 100644
index 0000000..5bdb299
--- /dev/null
+++ b/config/route.php
@@ -0,0 +1,45 @@
+ '/',
+ // URL伪静态后缀
+ 'url_html_suffix' => 'html',
+ // URL普通方式参数 用于自动生成
+ 'url_common_param' => true,
+ // 是否开启路由延迟解析
+ 'url_lazy_route' => true,
+ // 是否强制使用路由
+ 'url_route_must' => false,
+ // 合并路由规则
+ 'route_rule_merge' => false,
+ // 路由是否完全匹配
+ 'route_complete_match' => true,
+ // 访问控制器层名称
+ 'controller_layer' => 'controller',
+ // 空控制器名
+ 'empty_controller' => 'Error',
+ // 是否使用控制器后缀
+ 'controller_suffix' => false,
+ // 默认的路由变量规则
+ 'default_route_pattern' => '[\w\.]+',
+ // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则
+ 'request_cache_key' => false,
+ // 请求缓存有效期
+ 'request_cache_expire' => null,
+ // 全局请求缓存排除规则
+ 'request_cache_except' => [],
+ // 默认控制器名
+ 'default_controller' => 'Index',
+ // 默认操作名
+ 'default_action' => 'index',
+ // 操作方法后缀
+ 'action_suffix' => '',
+ // 默认JSONP格式返回的处理方法
+ 'default_jsonp_handler' => 'jsonpReturn',
+ // 默认JSONP处理方法
+ 'var_jsonp_handler' => 'callback',
+];
diff --git a/config/session.php b/config/session.php
new file mode 100644
index 0000000..b3fed5e
--- /dev/null
+++ b/config/session.php
@@ -0,0 +1,19 @@
+ 'PHPSESSID',
+ // SESSION_ID的提交变量,解决flash上传跨域
+ 'var_session_id' => '',
+ // 驱动方式 支持file cache
+ 'type' => 'cache',
+ // 存储连接标识 当type使用cache的时候有效
+ 'store' => null,
+ // 过期时间
+ 'expire' => 3600,
+ // 前缀
+ 'prefix' => '',
+];
diff --git a/config/trace.php b/config/trace.php
new file mode 100644
index 0000000..fad2392
--- /dev/null
+++ b/config/trace.php
@@ -0,0 +1,10 @@
+ 'Html',
+ // 读取的日志通道名
+ 'channel' => '',
+];
diff --git a/config/view.php b/config/view.php
new file mode 100644
index 0000000..01259a0
--- /dev/null
+++ b/config/view.php
@@ -0,0 +1,25 @@
+ 'Think',
+ // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
+ 'auto_rule' => 1,
+ // 模板目录名
+ 'view_dir_name' => 'view',
+ // 模板后缀
+ 'view_suffix' => 'html',
+ // 模板文件名分隔符
+ 'view_depr' => DIRECTORY_SEPARATOR,
+ // 模板引擎普通标签开始标记
+ 'tpl_begin' => '{',
+ // 模板引擎普通标签结束标记
+ 'tpl_end' => '}',
+ // 标签库标签开始标记
+ 'taglib_begin' => '{',
+ // 标签库标签结束标记
+ 'taglib_end' => '}',
+];
diff --git a/database/migrations/20210324015153_admin_create.php b/database/migrations/20210324015153_admin_create.php
new file mode 100644
index 0000000..496f694
--- /dev/null
+++ b/database/migrations/20210324015153_admin_create.php
@@ -0,0 +1,52 @@
+table('admin',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'管理员表'])->addIndex('id');
+ $table
+ ->addColumn('mobile','string',['limit'=>11,'default'=>'','null'=>false,'comment'=>'手机号'])
+ ->addColumn('code','string',['limit'=>10,'default'=>'','null'=>false,'comment'=>'业务员编码'])
+ ->addColumn('role_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'角色ID'])
+ ->addColumn('org_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'组织ID'])
+ ->addColumn('dept_group_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'部门分组ID'])
+ ->addColumn('dept_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'部门ID'])
+ ->addColumn('avatar','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'头像'])
+ ->addColumn('nickname','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'昵称'])
+ ->addColumn('username','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'用户名'])
+ ->addColumn('password','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'密码'])
+ ->addColumn('create_ip','string',['limit'=>15,'default'=>'0.0.0.0','null'=>false,'comment'=>'注册IP'])
+ ->addColumn('last_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'最后登录时间'])
+ ->addColumn('last_ip','string',['limit'=>15,'default'=>'0.0.0.0','null'=>false,'comment'=>'最后登录IP'])
+ ->addColumn('status','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210324044700_role_create.php b/database/migrations/20210324044700_role_create.php
new file mode 100644
index 0000000..8998a7e
--- /dev/null
+++ b/database/migrations/20210324044700_role_create.php
@@ -0,0 +1,39 @@
+table('role',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'角色表'])->addIndex('id');
+ $table
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'角色名称'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210324055445_menu_create.php b/database/migrations/20210324055445_menu_create.php
new file mode 100644
index 0000000..be73be7
--- /dev/null
+++ b/database/migrations/20210324055445_menu_create.php
@@ -0,0 +1,45 @@
+table('menu',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'菜单表'])->addIndex('id');
+// $table
+// ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+// ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'菜单名称'])
+// ->addColumn('action','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'菜单规则'])
+// ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图标'])
+// ->addColumn('pid','integer',['limit'=> MysqlAdapter::INT_SMALL,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'父ID'])
+// ->addColumn('sort','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>255,'null'=>false,'comment'=>'排序'])
+// ->addColumn('is_show','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>1,'null'=>false,'comment'=>'是否显示,0=隐藏,1=显示'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->create();
+ }
+}
diff --git a/database/migrations/20210324061342_role_to_menu_create.php b/database/migrations/20210324061342_role_to_menu_create.php
new file mode 100644
index 0000000..3f9ff96
--- /dev/null
+++ b/database/migrations/20210324061342_role_to_menu_create.php
@@ -0,0 +1,42 @@
+table('role_to_menu',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'角色菜单表'])->addIndex('id');
+// $table
+// ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+// ->addColumn('role_id','integer',['limit'=> MysqlAdapter::INT_SMALL,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'角色ID'])
+// ->addColumn('menu_id','integer',['limit'=> MysqlAdapter::INT_SMALL,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'菜单ID'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->addIndex(['role_id','menu_id'],['unique'=>true])
+// ->create();
+ }
+}
diff --git a/database/migrations/20210329054522_menu_modify.php b/database/migrations/20210329054522_menu_modify.php
new file mode 100644
index 0000000..a5959a9
--- /dev/null
+++ b/database/migrations/20210329054522_menu_modify.php
@@ -0,0 +1,40 @@
+table('menu');
+// $table
+// ->addColumn('path','string',['limit'=>64,'after'=>'icon','default'=>'','null'=>false,'comment'=>'菜单路径'])
+// ->addColumn('component','string',['limit'=>128,'default'=>'','after'=>'path','null'=>false,'comment'=>'操作,如:/api/info'])
+// ->addColumn('redirect','string',['limit'=>128,'default'=>'','after'=>'component','null'=>false,'comment'=>'跳转'])
+// ->addColumn('is_menu','integer',['limit'=> MysqlAdapter::INT_SMALL,'after'=>'redirect','signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否为菜单,0=否,1=是'])
+// ->update();
+ }
+}
diff --git a/database/migrations/20210329081619_goods_category_create.php b/database/migrations/20210329081619_goods_category_create.php
new file mode 100644
index 0000000..433711a
--- /dev/null
+++ b/database/migrations/20210329081619_goods_category_create.php
@@ -0,0 +1,46 @@
+table('goods_category',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'分类名'])
+ ->addColumn('desc','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('pid','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'父ID'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'电脑端分类图标'])
+ ->addColumn('sort','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=禁用,1=启用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210329084545_language_create.php b/database/migrations/20210329084545_language_create.php
new file mode 100644
index 0000000..13085f2
--- /dev/null
+++ b/database/migrations/20210329084545_language_create.php
@@ -0,0 +1,46 @@
+table('language',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'语言包表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('name','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'语言包名'])
+ ->addColumn('code','string',['limit'=>20,'default'=>'','null'=>false,'comment'=>'标识'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图标'])
+ ->addColumn('locale','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'作用范围'])
+ ->addColumn('coin','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'货币'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210329090112_goods_create.php b/database/migrations/20210329090112_goods_create.php
new file mode 100644
index 0000000..6a7af97
--- /dev/null
+++ b/database/migrations/20210329090112_goods_create.php
@@ -0,0 +1,51 @@
+table('goods',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品标题'])
+ ->addColumn('model_number','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品型号'])
+ ->addColumn('goods_category_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'商品分类ID'])
+ ->addColumn('price','decimal',['scale'=>2,'precision'=>10,'signed'=>false,'default'=>0.00,'null'=>false,'comment'=>'商品价格'])
+ ->addColumn('details','text',['comment'=>'商品详情'])
+ ->addColumn('params','text',['comment'=>'商品参数'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'页面title'])
+ ->addColumn('keywords','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'关键词'])
+ ->addColumn('description','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'页面描述SEO用'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210331061712_nav_menu_create.php b/database/migrations/20210331061712_nav_menu_create.php
new file mode 100644
index 0000000..03f9c96
--- /dev/null
+++ b/database/migrations/20210331061712_nav_menu_create.php
@@ -0,0 +1,48 @@
+table('navigator',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'导航栏表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('pid','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'父ID'])
+ ->addColumn('name','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图标'])
+ ->addColumn('link','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0 启用 1 禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20210331071533_platform_create.php b/database/migrations/20210331071533_platform_create.php
new file mode 100644
index 0000000..c5dffa1
--- /dev/null
+++ b/database/migrations/20210331071533_platform_create.php
@@ -0,0 +1,43 @@
+table('platform',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'平台表'])->addIndex('id');
+ $table
+ ->addColumn('name','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0 启用 1 禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210401012551_question_create.php b/database/migrations/20210401012551_question_create.php
new file mode 100644
index 0000000..3956930
--- /dev/null
+++ b/database/migrations/20210401012551_question_create.php
@@ -0,0 +1,48 @@
+table('question',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'用户反馈'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('country_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'国家ID'])
+ ->addColumn('name','string',['limit'=>40,'default'=>'','null'=>false,'comment'=>'姓名'])
+ ->addColumn('email','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'邮箱'])
+ ->addColumn('order_sn','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('product_model','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品型号'])
+ ->addColumn('os','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'操作系统'])
+ ->addColumn('desc','text',['comment'=>'描述'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210401013411_country_create.php b/database/migrations/20210401013411_country_create.php
new file mode 100644
index 0000000..697bf46
--- /dev/null
+++ b/database/migrations/20210401013411_country_create.php
@@ -0,0 +1,43 @@
+table('country',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'国家表'])->addIndex('id');
+ $table
+ ->addColumn('code','string',['limit'=>4,'default'=>'','null'=>false,'comment'=>'地区码'])
+ ->addColumn('en','string',['limit'=>30,'default'=>'','null'=>false,'comment'=>'英文名'])
+ ->addColumn('locale','string',['limit'=>10,'default'=>'','null'=>false,'comment'=>'缩写'])
+ ->addColumn('zh','string',['limit'=>20,'default'=>'','null'=>false,'comment'=>'简体中文名'])
+ ->addColumn('tw','string',['limit'=>20,'default'=>'','null'=>false,'comment'=>'繁体中文名'])
+ ->addColumn('icon','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'国旗图标'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210401060214_soft_manual_create.php b/database/migrations/20210401060214_soft_manual_create.php
new file mode 100644
index 0000000..3008ff7
--- /dev/null
+++ b/database/migrations/20210401060214_soft_manual_create.php
@@ -0,0 +1,46 @@
+table('soft_manual',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'软件帮助手册表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('file_type_id','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'文件类型ID'])
+ ->addColumn('name','string',['limit'=>40,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->addColumn('introduce','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'下载介绍'])
+ ->addColumn('support','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'支持型号'])
+ ->addColumn('os','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'操作系统'])
+ ->addColumn('download_count','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'下载次数'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210401065205_article_create.php b/database/migrations/20210401065205_article_create.php
new file mode 100644
index 0000000..bb37557
--- /dev/null
+++ b/database/migrations/20210401065205_article_create.php
@@ -0,0 +1,47 @@
+table('article',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'文章表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文章标题'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章描述'])
+ ->addColumn('thumb','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章缩略图'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('detail','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('click_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'点击次数'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210402074714_log_visit_create.php b/database/migrations/20210402074714_log_visit_create.php
new file mode 100644
index 0000000..5bc27b6
--- /dev/null
+++ b/database/migrations/20210402074714_log_visit_create.php
@@ -0,0 +1,46 @@
+table('log_visit',['engine'=>'innodb','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'日志记录表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('admin_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'管理员ID'])
+ ->addColumn('admin_name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'管理员名称'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'请求的URL'])
+ ->addColumn('params','text',['comment'=>'请求参数'])
+ ->addColumn('controller','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'操作模块'])
+ ->addColumn('action','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'操作方法'])
+ ->addColumn('ip','string',['limit'=>15,'default'=>'','null'=>false,'comment'=>'访问IP'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->addIndex(['controller','create_time'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406071303_goods_images_create.php b/database/migrations/20210406071303_goods_images_create.php
new file mode 100644
index 0000000..5c6b790
--- /dev/null
+++ b/database/migrations/20210406071303_goods_images_create.php
@@ -0,0 +1,40 @@
+table('goods_images',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品主图表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品ID'])
+ ->addColumn('image','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品图片'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406071431_goods_buy_now_create.php b/database/migrations/20210406071431_goods_buy_now_create.php
new file mode 100644
index 0000000..1b6fe37
--- /dev/null
+++ b/database/migrations/20210406071431_goods_buy_now_create.php
@@ -0,0 +1,41 @@
+table('goods_buy_now',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品链接表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品ID'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'链接名称'])
+ ->addColumn('url','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'链接地址'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406071843_goods_connect_create.php b/database/migrations/20210406071843_goods_connect_create.php
new file mode 100644
index 0000000..8c4315e
--- /dev/null
+++ b/database/migrations/20210406071843_goods_connect_create.php
@@ -0,0 +1,41 @@
+table('goods_connect',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品相关表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品ID'])
+ ->addColumn('goods_category_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品分类ID'])
+ ->addColumn('connect_good_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'关联商品ID'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406074619_bulk_buy_create.php b/database/migrations/20210406074619_bulk_buy_create.php
new file mode 100644
index 0000000..db26e09
--- /dev/null
+++ b/database/migrations/20210406074619_bulk_buy_create.php
@@ -0,0 +1,46 @@
+table('bulk_buy',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'大量采购表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品标题'])
+ ->addColumn('mode_number','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品型号'])
+ ->addColumn('email','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'邮箱'])
+ ->addColumn('arrival_country','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'收货地址'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('delivery_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'交货日期'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406080230_file_type_create.php b/database/migrations/20210406080230_file_type_create.php
new file mode 100644
index 0000000..18e1dff
--- /dev/null
+++ b/database/migrations/20210406080230_file_type_create.php
@@ -0,0 +1,44 @@
+table('file_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'文件类型'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406081049_comment_create.php b/database/migrations/20210406081049_comment_create.php
new file mode 100644
index 0000000..fb1942b
--- /dev/null
+++ b/database/migrations/20210406081049_comment_create.php
@@ -0,0 +1,46 @@
+table('comment',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'客户评价表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('avatar','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'头像'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('nickname','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'客户昵称'])
+ ->addColumn('comment','text',['comment'=>'评论'])
+ ->addColumn('url','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'产品链接'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210406082129_comment_image_create.php b/database/migrations/20210406082129_comment_image_create.php
new file mode 100644
index 0000000..c6fce31
--- /dev/null
+++ b/database/migrations/20210406082129_comment_image_create.php
@@ -0,0 +1,40 @@
+table('comment_image',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'客户评价图片表'])->addIndex('id');
+ $table
+ ->addColumn('comment_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'评论ID'])
+ ->addColumn('image','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图片'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210407060030_goods_soft_manual_create.php b/database/migrations/20210407060030_goods_soft_manual_create.php
new file mode 100644
index 0000000..dcdd0bb
--- /dev/null
+++ b/database/migrations/20210407060030_goods_soft_manual_create.php
@@ -0,0 +1,41 @@
+table('goods_soft_manual',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品手册驱动表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'文件类型ID'])
+ ->addColumn('file_type_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'文件类型ID'])
+ ->addColumn('soft_manual_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'文档驱动ID'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210408015958_admin_add_field.php b/database/migrations/20210408015958_admin_add_field.php
new file mode 100644
index 0000000..6b30f44
--- /dev/null
+++ b/database/migrations/20210408015958_admin_add_field.php
@@ -0,0 +1,36 @@
+table('admin');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'after'=>'id','default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210408055250_question_attachment.php b/database/migrations/20210408055250_question_attachment.php
new file mode 100644
index 0000000..1353b5d
--- /dev/null
+++ b/database/migrations/20210408055250_question_attachment.php
@@ -0,0 +1,39 @@
+table('question_attachment',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'用户反馈附件表'])->addIndex('id');
+ $table
+ ->addColumn('question_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'反馈ID'])
+ ->addColumn('attach','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'附件'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210408074527_advertisement_create.php b/database/migrations/20210408074527_advertisement_create.php
new file mode 100644
index 0000000..28f0ad9
--- /dev/null
+++ b/database/migrations/20210408074527_advertisement_create.php
@@ -0,0 +1,50 @@
+table('advertisement',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'广告表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('advertise_space_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'广告位ID'])
+ ->addColumn('advertise_space_name','string',['limit'=>30,'signed'=>false,'default'=>'','null'=>false,'comment'=>'广告位名称'])
+ ->addColumn('ad_name','string',['limit'=>40,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->addColumn('image','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'广告图'])
+ ->addColumn('url','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'广告图链接'])
+ ->addColumn('start_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'开始时间'])
+ ->addColumn('stop_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'结束时间'])
+ ->addColumn('play_order','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'轮播顺序'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=可用,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210408082344_advertise_space_create.php b/database/migrations/20210408082344_advertise_space_create.php
new file mode 100644
index 0000000..8fcba09
--- /dev/null
+++ b/database/migrations/20210408082344_advertise_space_create.php
@@ -0,0 +1,46 @@
+table('advertise_space',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'广告位表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('advertise_page_id','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'广告页面ID'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'广告位名称'])
+ ->addColumn('max_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'数量上限'])
+ ->addColumn('width','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'宽,单位像素'])
+ ->addColumn('height','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'长,单位像素'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210408083002_advertise_page_create.php b/database/migrations/20210408083002_advertise_page_create.php
new file mode 100644
index 0000000..b649018
--- /dev/null
+++ b/database/migrations/20210408083002_advertise_page_create.php
@@ -0,0 +1,43 @@
+table('advertise_page',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'广告所属页表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>30,'default'=>'','null'=>false,'comment'=>'页面名称'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20210409085237_goods_coupon_create.php b/database/migrations/20210409085237_goods_coupon_create.php
new file mode 100644
index 0000000..8bb11a6
--- /dev/null
+++ b/database/migrations/20210409085237_goods_coupon_create.php
@@ -0,0 +1,43 @@
+table('goods_coupon',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'优惠券表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('old_code','string',['limit'=>30,'default'=>'','null'=>false,'comment'=>'旧口令'])
+ ->addColumn('new_code','string',['limit'=>30,'default'=>'','null'=>false,'comment'=>'新口令'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20210410020249_platform_add_field.php b/database/migrations/20210410020249_platform_add_field.php
new file mode 100644
index 0000000..796ef12
--- /dev/null
+++ b/database/migrations/20210410020249_platform_add_field.php
@@ -0,0 +1,38 @@
+table('platform');
+ $table
+ ->addColumn('vi_color1','string',['limit'=>10,'after'=>'name','default'=>'','null'=>false,'comment'=>'品牌vi色1'])
+ ->addColumn('vi_color2','string',['limit'=>10,'after'=>'vi_color1','default'=>'','null'=>false,'comment'=>'品牌vi色2'])
+ ->addColumn('vi_color3','string',['limit'=>10,'after'=>'vi_color2','default'=>'','null'=>false,'comment'=>'品牌vi色3'])
+ ->addColumn('language_id','integer',['limit'=>10,'after'=>'vi_color3','signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言ID'])
+ ->addColumn('currency_id','integer',['limit'=>10,'after'=>'language_id','signed'=>false,'default'=>0,'null'=>false,'comment'=>'币种ID'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210410023648_currency_create.php b/database/migrations/20210410023648_currency_create.php
new file mode 100644
index 0000000..f379c7f
--- /dev/null
+++ b/database/migrations/20210410023648_currency_create.php
@@ -0,0 +1,42 @@
+table('currency',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'币种表'])->addIndex('id');
+ $table
+ ->addColumn('name','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'货币名称'])
+ ->addColumn('code','string',['limit'=>20,'default'=>'','null'=>false,'comment'=>'英文缩写'])
+ ->addColumn('signal','string',['limit'=>20,'default'=>'','null'=>false,'comment'=>'符号'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210411131000_platform_language_create.php b/database/migrations/20210411131000_platform_language_create.php
new file mode 100644
index 0000000..8021bd0
--- /dev/null
+++ b/database/migrations/20210411131000_platform_language_create.php
@@ -0,0 +1,38 @@
+table('platform_language',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'平台语言表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言ID'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210411132944_menu_language_create.php b/database/migrations/20210411132944_menu_language_create.php
new file mode 100644
index 0000000..332688f
--- /dev/null
+++ b/database/migrations/20210411132944_menu_language_create.php
@@ -0,0 +1,39 @@
+table('menu_language',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'菜单语言表'])->addIndex('id');
+// $table
+// ->addColumn('menu_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'菜单ID'])
+// ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言ID'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->create();
+ }
+}
diff --git a/database/migrations/20210412015616_platform_coin_create.php b/database/migrations/20210412015616_platform_coin_create.php
new file mode 100644
index 0000000..a9b3adf
--- /dev/null
+++ b/database/migrations/20210412015616_platform_coin_create.php
@@ -0,0 +1,39 @@
+table('platform_coin',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'平台币种表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('currency_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'币种ID'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210412021449_platform_menu_create.php b/database/migrations/20210412021449_platform_menu_create.php
new file mode 100644
index 0000000..b498256
--- /dev/null
+++ b/database/migrations/20210412021449_platform_menu_create.php
@@ -0,0 +1,39 @@
+table('platform_menu',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'平台菜单表'])->addIndex('id');
+// $table
+// ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言ID'])
+// ->addColumn('menu_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'菜单ID'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->create();
+ }
+}
diff --git a/database/migrations/20210412030346_site_create.php b/database/migrations/20210412030346_site_create.php
new file mode 100644
index 0000000..c64f426
--- /dev/null
+++ b/database/migrations/20210412030346_site_create.php
@@ -0,0 +1,43 @@
+table('site',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'站点表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'所属品牌ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('currency_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'币种ID'])
+ ->addColumn('domain','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'域名'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210412031252_site_menu_create.php b/database/migrations/20210412031252_site_menu_create.php
new file mode 100644
index 0000000..ed45172
--- /dev/null
+++ b/database/migrations/20210412031252_site_menu_create.php
@@ -0,0 +1,40 @@
+table('site_menu',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'站点栏目表'])->addIndex('id');
+// $table
+// ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言ID'])
+// ->addColumn('menu_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'菜单ID'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->create();
+
+ }
+}
diff --git a/database/migrations/20210412092533_drop_platform_menu_create.php b/database/migrations/20210412092533_drop_platform_menu_create.php
new file mode 100644
index 0000000..da0bf9c
--- /dev/null
+++ b/database/migrations/20210412092533_drop_platform_menu_create.php
@@ -0,0 +1,33 @@
+table('platform_menu')->drop();
+ }
+}
diff --git a/database/migrations/20210412095945_site_menu_change.php b/database/migrations/20210412095945_site_menu_change.php
new file mode 100644
index 0000000..1ab1390
--- /dev/null
+++ b/database/migrations/20210412095945_site_menu_change.php
@@ -0,0 +1,36 @@
+table('site_menu');
+// $table
+// ->renameColumn('menu_id','navigator_id')
+// ->update();
+ }
+}
diff --git a/database/migrations/20210413083208_menu_platform_create.php b/database/migrations/20210413083208_menu_platform_create.php
new file mode 100644
index 0000000..ff7ce47
--- /dev/null
+++ b/database/migrations/20210413083208_menu_platform_create.php
@@ -0,0 +1,41 @@
+table('menu_platform',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'站点栏目表'])->addIndex('id');
+// $table
+// ->addColumn('menu_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'菜单ID'])
+// ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'品牌ID'])
+// ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+// ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+// ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+// ->create();
+ }
+}
diff --git a/database/migrations/20210413130939_menu_change_field_is_show_to_status.php b/database/migrations/20210413130939_menu_change_field_is_show_to_status.php
new file mode 100644
index 0000000..91af359
--- /dev/null
+++ b/database/migrations/20210413130939_menu_change_field_is_show_to_status.php
@@ -0,0 +1,36 @@
+table('menu');
+// $table
+// ->renameColumn('is_show','status')
+// ->update();
+ }
+}
diff --git a/database/migrations/20210414160618_soft_manual_add_field.php b/database/migrations/20210414160618_soft_manual_add_field.php
new file mode 100644
index 0000000..9da98c0
--- /dev/null
+++ b/database/migrations/20210414160618_soft_manual_add_field.php
@@ -0,0 +1,40 @@
+table('soft_manual');
+ $table
+ ->addColumn('file_name','string',['limit'=>60,'after'=>'introduce','default'=>'','null'=>false,'comment'=>'下载名称'])
+ ->addColumn('url','string',['limit'=>128,'after'=>'file_name','default'=>'','null'=>false,'comment'=>'下载链接'])
+ ->addColumn('btn_tips','string',['limit'=>50,'after'=>'file_name','default'=>'','null'=>false,'comment'=>'下载提示语'])
+ ->changeColumn('introduce','string',['limit'=>500,'default'=>'','null'=>false,'comment'=>'下载介绍'])
+ ->update();
+
+ }
+}
diff --git a/database/migrations/20210415014222_faq_create.php b/database/migrations/20210415014222_faq_create.php
new file mode 100644
index 0000000..03ad644
--- /dev/null
+++ b/database/migrations/20210415014222_faq_create.php
@@ -0,0 +1,45 @@
+table('faq',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'常见问题表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'所属品牌ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('faq_type_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'常见问题分类ID'])
+ ->addColumn('question','string',['limit'=>150,'default'=>'','null'=>false,'comment'=>'问题内容'])
+ ->addColumn('answer','text',['comment'=>'回答内容'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210415014325_faq_type_create.php b/database/migrations/20210415014325_faq_type_create.php
new file mode 100644
index 0000000..015473e
--- /dev/null
+++ b/database/migrations/20210415014325_faq_type_create.php
@@ -0,0 +1,44 @@
+table('faq_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'常见问题分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210415074326_comment_modify_field.php b/database/migrations/20210415074326_comment_modify_field.php
new file mode 100644
index 0000000..648f8ba
--- /dev/null
+++ b/database/migrations/20210415074326_comment_modify_field.php
@@ -0,0 +1,36 @@
+table('comment');
+ $table
+ ->changeColumn('avatar','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'头像'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210415092350_advertisement_modify_field.php b/database/migrations/20210415092350_advertisement_modify_field.php
new file mode 100644
index 0000000..2354091
--- /dev/null
+++ b/database/migrations/20210415092350_advertisement_modify_field.php
@@ -0,0 +1,37 @@
+table('advertisement');
+ $table
+ ->renameColumn('ad_name','name')
+ ->changeColumn('name','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210415094038_question_add_field.php b/database/migrations/20210415094038_question_add_field.php
new file mode 100644
index 0000000..256285f
--- /dev/null
+++ b/database/migrations/20210415094038_question_add_field.php
@@ -0,0 +1,37 @@
+table('question');
+ $table
+ ->addColumn('is_done','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'sort','signed'=>false,'default'=>0,'null'=>false,'comment'=>'解决与否,0=未解决,1=已解决'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210415100810_coupon_subscribe.php b/database/migrations/20210415100810_coupon_subscribe.php
new file mode 100644
index 0000000..c3cb05e
--- /dev/null
+++ b/database/migrations/20210415100810_coupon_subscribe.php
@@ -0,0 +1,42 @@
+table('coupon_subscribe',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'优惠券领用记录表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'所属品牌ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('goods_coupon_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'优惠券ID'])
+ ->addColumn('email','string',['limit'=>150,'default'=>'','null'=>false,'comment'=>'订阅邮箱'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210417030635_goods_attribute_create.php b/database/migrations/20210417030635_goods_attribute_create.php
new file mode 100644
index 0000000..61a10bf
--- /dev/null
+++ b/database/migrations/20210417030635_goods_attribute_create.php
@@ -0,0 +1,43 @@
+table('goods_attribute',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品属性表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品ID'])
+ ->addColumn('attribute_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'属性ID'])
+ ->addColumn('value','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'商品属性值'])
+ ->addColumn('sort','integer',['limit'=> MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+
+ }
+}
diff --git a/database/migrations/20210417031148_attribute_create.php b/database/migrations/20210417031148_attribute_create.php
new file mode 100644
index 0000000..996dc66
--- /dev/null
+++ b/database/migrations/20210417031148_attribute_create.php
@@ -0,0 +1,40 @@
+table('attribute',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'属性表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'属性名'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210417054827_goods_cates_create.php b/database/migrations/20210417054827_goods_cates_create.php
new file mode 100644
index 0000000..a9852ed
--- /dev/null
+++ b/database/migrations/20210417054827_goods_cates_create.php
@@ -0,0 +1,39 @@
+table('goods_cate',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'商品多分类表'])->addIndex('id');
+ $table
+ ->addColumn('goods_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'商品ID'])
+ ->addColumn('goods_category_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'属性ID'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210417064504_goods_add_field.php b/database/migrations/20210417064504_goods_add_field.php
new file mode 100644
index 0000000..359f646
--- /dev/null
+++ b/database/migrations/20210417064504_goods_add_field.php
@@ -0,0 +1,37 @@
+table('goods');
+ $table
+ ->addColumn('main_img','string',['limit'=>128,'default'=>'','after'=>'model_number','null'=>false,'comment'=>'产品主图'])
+ ->removeColumn('params')
+ ->update();
+ }
+}
diff --git a/database/migrations/20210417072211_goods_modify_field.php b/database/migrations/20210417072211_goods_modify_field.php
new file mode 100644
index 0000000..491c3cd
--- /dev/null
+++ b/database/migrations/20210417072211_goods_modify_field.php
@@ -0,0 +1,38 @@
+table('goods');
+ $table
+ ->changeColumn('title','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'页面title'])
+ ->changeColumn('keywords','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'关键词'])
+ ->changeColumn('description','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'页面描述SEO用'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210417084728_soft_manual_add_field_image.php b/database/migrations/20210417084728_soft_manual_add_field_image.php
new file mode 100644
index 0000000..b192a30
--- /dev/null
+++ b/database/migrations/20210417084728_soft_manual_add_field_image.php
@@ -0,0 +1,36 @@
+table('soft_manual');
+ $table
+ ->addColumn('image','string',['limit'=>60,'after'=>'url','default'=>'','null'=>false,'comment'=>'图片'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210417092911_common_modify_field.php b/database/migrations/20210417092911_common_modify_field.php
new file mode 100644
index 0000000..114dff2
--- /dev/null
+++ b/database/migrations/20210417092911_common_modify_field.php
@@ -0,0 +1,37 @@
+table('comment');
+ $table
+ ->changeColumn('name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'评论标题'])
+ ->changeColumn('nickname','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'客户昵称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210419095734_language_remove_platform_id.php b/database/migrations/20210419095734_language_remove_platform_id.php
new file mode 100644
index 0000000..ad50b57
--- /dev/null
+++ b/database/migrations/20210419095734_language_remove_platform_id.php
@@ -0,0 +1,34 @@
+table('language');
+ $table->removeColumn('platform_id')->update();
+ }
+}
diff --git a/database/migrations/20210420024741_soft_manual_modify_field.php b/database/migrations/20210420024741_soft_manual_modify_field.php
new file mode 100644
index 0000000..6d1d672
--- /dev/null
+++ b/database/migrations/20210420024741_soft_manual_modify_field.php
@@ -0,0 +1,36 @@
+table('soft_manual');
+ $table
+ ->changeColumn('name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210420031501_bulk_buy_add_field.php b/database/migrations/20210420031501_bulk_buy_add_field.php
new file mode 100644
index 0000000..2b9b46e
--- /dev/null
+++ b/database/migrations/20210420031501_bulk_buy_add_field.php
@@ -0,0 +1,36 @@
+table('bulk_buy');
+ $table
+ ->addColumn('needed_num','integer',['limit'=>10,'after'=>'mode_number','default'=>0,'null'=>false,'comment'=>'需要数量'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210420035207_faq_modify_field.php b/database/migrations/20210420035207_faq_modify_field.php
new file mode 100644
index 0000000..bd9b459
--- /dev/null
+++ b/database/migrations/20210420035207_faq_modify_field.php
@@ -0,0 +1,37 @@
+table('faq');
+ $table
+ ->changeColumn('question','text',['comment'=>'问题内容'])
+ ->update();
+
+ }
+}
diff --git a/database/migrations/20210420035731_soft_manual_modify_image_field.php b/database/migrations/20210420035731_soft_manual_modify_image_field.php
new file mode 100644
index 0000000..257a459
--- /dev/null
+++ b/database/migrations/20210420035731_soft_manual_modify_image_field.php
@@ -0,0 +1,36 @@
+table('soft_manual');
+ $table
+ ->changeColumn('image','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'图片'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210421031859_goods_add_fields.php b/database/migrations/20210421031859_goods_add_fields.php
new file mode 100644
index 0000000..d7b6fea
--- /dev/null
+++ b/database/migrations/20210421031859_goods_add_fields.php
@@ -0,0 +1,38 @@
+table('goods');
+ $table
+ ->addColumn('model','string',['limit'=>128,'default'=>'','after'=>'model_number','null'=>false,'comment'=>'模型型号'])
+ ->addColumn('sku','string',['limit'=>128,'default'=>'','after'=>'model','null'=>false,'comment'=>'SKU'])
+ ->addColumn('viewed','integer',['limit'=>10,'signed'=>false,'default'=>0,'after'=>'sku','null'=>false,'comment'=>'查看次数'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210421121233_navigator_modify_field.php b/database/migrations/20210421121233_navigator_modify_field.php
new file mode 100644
index 0000000..87fc76c
--- /dev/null
+++ b/database/migrations/20210421121233_navigator_modify_field.php
@@ -0,0 +1,36 @@
+table('navigator');
+ $table
+ ->renameColumn('link','url')
+ ->update();
+ }
+}
diff --git a/database/migrations/20210421142424_soft_manual_add_field_status.php b/database/migrations/20210421142424_soft_manual_add_field_status.php
new file mode 100644
index 0000000..56bf74a
--- /dev/null
+++ b/database/migrations/20210421142424_soft_manual_add_field_status.php
@@ -0,0 +1,37 @@
+table('soft_manual');
+ $table
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'download_count','signed'=>false,'default'=>0,'null'=>false,'comment'=>'状态,0=正常,1=禁用'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210423015349_soft_manual_btn_create.php b/database/migrations/20210423015349_soft_manual_btn_create.php
new file mode 100644
index 0000000..a36e0ea
--- /dev/null
+++ b/database/migrations/20210423015349_soft_manual_btn_create.php
@@ -0,0 +1,40 @@
+table('soft_manual_btn',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'文档手册分表'])->addIndex('id');
+ $table
+ ->addColumn('soft_manual_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'文档手册主表ID'])
+ ->addColumn('btn_tips','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'按钮名称'])
+ ->addColumn('url','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'下载链接'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210423044621_soft_manual_modify_field_file_name.php b/database/migrations/20210423044621_soft_manual_modify_field_file_name.php
new file mode 100644
index 0000000..b4f7576
--- /dev/null
+++ b/database/migrations/20210423044621_soft_manual_modify_field_file_name.php
@@ -0,0 +1,36 @@
+table('soft_manual');
+ $table
+ ->changeColumn('file_name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文件名'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210430094547_goods_connect_modify_field.php b/database/migrations/20210430094547_goods_connect_modify_field.php
new file mode 100644
index 0000000..0220e9f
--- /dev/null
+++ b/database/migrations/20210430094547_goods_connect_modify_field.php
@@ -0,0 +1,37 @@
+table('goods_connect');
+ $table
+ ->renameColumn('goods_category_id','type')
+ ->changeColumn('type','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'页面标识'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210507084247_question_add_field_email.php b/database/migrations/20210507084247_question_add_field_email.php
new file mode 100644
index 0000000..ec9502b
--- /dev/null
+++ b/database/migrations/20210507084247_question_add_field_email.php
@@ -0,0 +1,40 @@
+table('question');
+ $table
+ ->addColumn('is_send_email','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'is_done','signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否发送邮件,0=否,1=是'])
+ ->addColumn('is_send_status','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'is_send_email','signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否发送成功,0=否,1=是'])
+ ->addColumn('send_time','integer',['limit'=>10,'after'=>'is_send_status','signed'=>false,'default'=>0,'null'=>false,'comment'=>'发送时间'])
+ ->addColumn('send_details','text',['after'=>'send_time','null'=>true,'comment'=>'发送反馈'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210514074651_soft_manual_add_field_sort.php b/database/migrations/20210514074651_soft_manual_add_field_sort.php
new file mode 100644
index 0000000..176d953
--- /dev/null
+++ b/database/migrations/20210514074651_soft_manual_add_field_sort.php
@@ -0,0 +1,37 @@
+table('soft_manual');
+ $table
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'os','signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210517055631_navigator_add_field.php b/database/migrations/20210517055631_navigator_add_field.php
new file mode 100644
index 0000000..4f4b8a7
--- /dev/null
+++ b/database/migrations/20210517055631_navigator_add_field.php
@@ -0,0 +1,38 @@
+table('navigator');
+ $table
+ ->addColumn('is_top','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'status','signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否顶部导航,0=是,1=否'])
+ ->addColumn('is_foot','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'is_top','signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否底部导航,0=是,1=否'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210602084418_goods_connect_modify_field_type.php b/database/migrations/20210602084418_goods_connect_modify_field_type.php
new file mode 100644
index 0000000..e6556de
--- /dev/null
+++ b/database/migrations/20210602084418_goods_connect_modify_field_type.php
@@ -0,0 +1,37 @@
+table('goods_connect');
+ $table
+ ->changeColumn('type','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'商品分类ID'])
+ ->renameColumn('type','goods_category_id')
+ ->update();
+ }
+}
diff --git a/database/migrations/20210611084756_do_select_id_to_null.php b/database/migrations/20210611084756_do_select_id_to_null.php
new file mode 100644
index 0000000..461f341
--- /dev/null
+++ b/database/migrations/20210611084756_do_select_id_to_null.php
@@ -0,0 +1,142 @@
+table('advertise_space');
+ $table
+ ->changeColumn('advertise_page_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'广告页面ID'])
+ ->update();
+
+ $table = $this->table('advertisement');
+ $table
+ ->changeColumn('advertise_space_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'广告位ID'])
+ ->update();
+
+ $table = $this->table('coupon_subscribe');
+ $table
+ ->changeColumn('goods_coupon_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'优惠券ID'])
+ ->update();
+
+ $table = $this->table('faq');
+ $table
+ ->changeColumn('faq_type_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'常见问题分类ID'])
+ ->update();
+
+ $table = $this->table('faq');
+ $table
+ ->changeColumn('faq_type_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'常见问题分类ID'])
+ ->update();
+
+
+ $table = $this->table('goods');
+ $table
+ ->changeColumn('goods_category_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品分类ID'])
+ ->update();
+
+ $table = $this->table('goods');
+ $table
+ ->changeColumn('goods_category_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品分类ID'])
+ ->update();
+
+
+ $table = $this->table('goods_attribute');
+ $table
+ ->changeColumn('goods_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品ID'])
+ ->changeColumn('attribute_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'属性ID'])
+ ->update();
+
+ $table = $this->table('goods_buy_now');
+ $table
+ ->changeColumn('goods_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品ID'])
+ ->update();
+
+ $table = $this->table('goods_connect');
+ $table
+ ->changeColumn('goods_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品ID'])
+ ->changeColumn('goods_category_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品分类ID'])
+ ->changeColumn('connect_good_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'关联商品ID'])
+ ->update();
+
+
+ $table = $this->table('goods_soft_manual');
+ $table
+ ->changeColumn('goods_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'商品ID'])
+ ->changeColumn('file_type_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'文件类型ID'])
+ ->changeColumn('soft_manual_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'文档驱动ID'])
+ ->update();
+
+// $table = $this->table('menu_language');
+// $table
+// ->changeColumn('menu_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'菜单ID'])
+// ->update();
+
+
+// $table = $this->table('menu_platform');
+// $table
+// ->changeColumn('menu_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'菜单ID'])
+// ->update();
+//
+// $table = $this->table('menu_platform');
+// $table
+// ->changeColumn('menu_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'菜单ID'])
+// ->update();
+
+ $table = $this->table('question');
+ $table
+ ->changeColumn('country_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'国家ID'])
+ ->changeColumn('order_sn','string',['limit'=>50,'default'=>'','null'=>false,'comment'=>'订单号'])
+ ->update();
+
+
+ $table = $this->table('soft_manual');
+ $table
+ ->changeColumn('file_type_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'文件类型ID'])
+ ->update();
+
+// $table = $this->table('platform');
+// $table
+// ->renameColumn('coin_id','currency_id')
+// ->changeColumn('currency_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'币种ID'])
+// ->update();
+
+// $table = $this->table('platform_coin');
+// $table
+// ->renameColumn('coin_id','currency_id')
+// ->changeColumn('currency_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'币种ID'])
+// ->update();
+
+// $table = $this->table('site');
+// $table
+// ->renameColumn('coin_id','currency_id')
+// ->changeColumn('currency_id','integer',['limit'=>10,'default'=>null,'null'=>true,'comment'=>'币种ID'])
+// ->update();
+
+ }
+}
diff --git a/database/migrations/20210612033548_goods_add_field_is_new.php b/database/migrations/20210612033548_goods_add_field_is_new.php
new file mode 100644
index 0000000..88f4970
--- /dev/null
+++ b/database/migrations/20210612033548_goods_add_field_is_new.php
@@ -0,0 +1,38 @@
+table('goods');
+ $table
+ ->addColumn('is_new','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'price','signed'=>false,'null'=>false,'default'=>1,'comment'=>'是否新品,0=是,1=否'])
+ ->addColumn('is_discount','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'price','signed'=>false,'null'=>false,'default'=>1,'comment'=>'折扣商品,0=是,1=否'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210616031448_comment_modify_field_sort.php b/database/migrations/20210616031448_comment_modify_field_sort.php
new file mode 100644
index 0000000..1a99a04
--- /dev/null
+++ b/database/migrations/20210616031448_comment_modify_field_sort.php
@@ -0,0 +1,37 @@
+table('comment');
+ $table
+ ->changeColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'null'=>false,'default'=>1,'comment'=>'排序'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210616041105_faq_type_modify_name.php b/database/migrations/20210616041105_faq_type_modify_name.php
new file mode 100644
index 0000000..bfcaeda
--- /dev/null
+++ b/database/migrations/20210616041105_faq_type_modify_name.php
@@ -0,0 +1,36 @@
+table('faq_type');
+ $table
+ ->changeColumn('name','string',['limit'=>60,'null'=>false,'default'=>'','comment'=>'分类名称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210621034622_advertisement_add_fields.php b/database/migrations/20210621034622_advertisement_add_fields.php
new file mode 100644
index 0000000..9d871af
--- /dev/null
+++ b/database/migrations/20210621034622_advertisement_add_fields.php
@@ -0,0 +1,36 @@
+table('advertisement');
+ $table
+ ->addColumn('command','string',['limit'=>255,'after'=>'play_order','null'=>false,'default'=>'','comment'=>'悬浮提示'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210623020217_goods_modify_sort_filed_default.php b/database/migrations/20210623020217_goods_modify_sort_filed_default.php
new file mode 100644
index 0000000..d52a03e
--- /dev/null
+++ b/database/migrations/20210623020217_goods_modify_sort_filed_default.php
@@ -0,0 +1,36 @@
+table('goods');
+ $table
+ ->changeColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>1,'null'=>false,'comment'=>'排序'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210623025611_soft_manual_btn_add_field.php b/database/migrations/20210623025611_soft_manual_btn_add_field.php
new file mode 100644
index 0000000..2e197ff
--- /dev/null
+++ b/database/migrations/20210623025611_soft_manual_btn_add_field.php
@@ -0,0 +1,36 @@
+table('soft_manual_btn');
+ $table
+ ->addColumn('file_name','string',['limit'=>128,'after'=>'url','null'=>false,'default'=>'','comment'=>'文件名称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210624081024_all_table_add_field_site_id.php b/database/migrations/20210624081024_all_table_add_field_site_id.php
new file mode 100644
index 0000000..88cbd2a
--- /dev/null
+++ b/database/migrations/20210624081024_all_table_add_field_site_id.php
@@ -0,0 +1,121 @@
+table('advertise_page');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('advertise_space');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('advertisement');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('article');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+
+ $table = $this->table('attribute');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('bulk_buy');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('comment');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+
+ $table = $this->table('coupon_subscribe');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('faq');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+
+ $table = $this->table('faq_type');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('file_type');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('goods');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+
+ $table = $this->table('goods_category');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('goods_coupon');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('navigator');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('question');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+
+ $table = $this->table('soft_manual');
+ $table
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'after'=>'language_id','default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->update();
+ }
+
+}
diff --git a/database/migrations/20210628061201_goods_buy_now_url_modify.php b/database/migrations/20210628061201_goods_buy_now_url_modify.php
new file mode 100644
index 0000000..a0c6524
--- /dev/null
+++ b/database/migrations/20210628061201_goods_buy_now_url_modify.php
@@ -0,0 +1,37 @@
+table('goods_buy_now');
+ $table
+ ->changeColumn('url','text',['comment'=>'链接地址'])
+ ->update();
+
+ }
+}
diff --git a/database/migrations/20210702083911_soft_manual_add_field_file_md5.php b/database/migrations/20210702083911_soft_manual_add_field_file_md5.php
new file mode 100644
index 0000000..224687e
--- /dev/null
+++ b/database/migrations/20210702083911_soft_manual_add_field_file_md5.php
@@ -0,0 +1,36 @@
+table('soft_manual_btn');
+ $table
+ ->addColumn('md5','string',['limit'=>32,'null'=>false,'after'=>'file_name','default'=>'','comment'=>'文件MD5值'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210809075919_advertise_page_add_fields.php b/database/migrations/20210809075919_advertise_page_add_fields.php
new file mode 100644
index 0000000..a9aab3c
--- /dev/null
+++ b/database/migrations/20210809075919_advertise_page_add_fields.php
@@ -0,0 +1,36 @@
+table('advertise_page');
+ $table
+ ->changeColumn('name', 'string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'页面名称'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210811014604_article_type_create.php b/database/migrations/20210811014604_article_type_create.php
new file mode 100644
index 0000000..01e1625
--- /dev/null
+++ b/database/migrations/20210811014604_article_type_create.php
@@ -0,0 +1,44 @@
+table('article_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'文章分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210811015327_article_add_field_create.php b/database/migrations/20210811015327_article_add_field_create.php
new file mode 100644
index 0000000..1139c81
--- /dev/null
+++ b/database/migrations/20210811015327_article_add_field_create.php
@@ -0,0 +1,39 @@
+table('article');
+ $table
+ ->addColumn('article_type_id','integer',['limit'=>10,'signed'=>false,'after'=>'site_id','default'=>0,'null'=>false,'comment'=>'文章分类ID'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'after'=>'sort','null'=>false,'comment'=>'状态,0=启动,1=禁用'])
+ ->changeColumn('detail','text',['comment'=>'文件详情'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210811095547_article_add_field.php b/database/migrations/20210811095547_article_add_field.php
new file mode 100644
index 0000000..868d0dc
--- /dev/null
+++ b/database/migrations/20210811095547_article_add_field.php
@@ -0,0 +1,40 @@
+table('article');
+ $table
+ ->addColumn('is_outer_chain','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'after'=>'status','null'=>false,'comment'=>'是否外链,0=是,1=否'])
+ ->addColumn('brief','string',['limit'=>255,'after'=>'is_outer_chain','default'=>'','null'=>false,'comment'=>'文章简介'])
+ ->addColumn('keywords','string',['limit'=>255,'after'=>'is_outer_chain','default'=>'','null'=>false,'comment'=>'关键字'])
+ ->addColumn('meta_title','string',['limit'=>255,'after'=>'is_outer_chain','default'=>'','null'=>false,'comment'=>'meta标题'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210813033230_site_add_field.php b/database/migrations/20210813033230_site_add_field.php
new file mode 100644
index 0000000..f9983fd
--- /dev/null
+++ b/database/migrations/20210813033230_site_add_field.php
@@ -0,0 +1,37 @@
+table('site');
+ $table
+ ->addColumn('app_id','string',['limit'=>32,'after'=>'status','default'=>'','null'=>false,'comment'=>'客户端APPID'])
+ ->addColumn('app_key','string',['limit'=>64,'after'=>'app_id','default'=>'','null'=>false,'comment'=>'客户端APPKEY'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210823100319_two_level_create.php b/database/migrations/20210823100319_two_level_create.php
new file mode 100644
index 0000000..5bf4b4e
--- /dev/null
+++ b/database/migrations/20210823100319_two_level_create.php
@@ -0,0 +1,39 @@
+table('area',['engine'=>'innodb','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'地区联动表'])->addIndex('id');
+ $table
+ ->addColumn('pid','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'父id'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'名称'])
+ ->addColumn('level','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'层级'])
+ ->addIndex(['pid'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210824031002_buld_buy_add_field_area_id.php b/database/migrations/20210824031002_buld_buy_add_field_area_id.php
new file mode 100644
index 0000000..f298057
--- /dev/null
+++ b/database/migrations/20210824031002_buld_buy_add_field_area_id.php
@@ -0,0 +1,36 @@
+table('bulk_buy');
+ $table
+ ->addColumn('area_id','integer',['limit'=>10,'after'=>'site_id','default'=>0,'null'=>false,'comment'=>'地区ID'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210824033049_buld_buy_add_field_phone.php b/database/migrations/20210824033049_buld_buy_add_field_phone.php
new file mode 100644
index 0000000..385be48
--- /dev/null
+++ b/database/migrations/20210824033049_buld_buy_add_field_phone.php
@@ -0,0 +1,36 @@
+table('bulk_buy');
+ $table
+ ->addColumn('phone','string',['limit'=>20,'after'=>'email','default'=>'','null'=>false,'comment'=>'联系电话'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210824054435_coupon_scribe_add_field_phone.php b/database/migrations/20210824054435_coupon_scribe_add_field_phone.php
new file mode 100644
index 0000000..ab8d7b2
--- /dev/null
+++ b/database/migrations/20210824054435_coupon_scribe_add_field_phone.php
@@ -0,0 +1,36 @@
+table('coupon_subscribe');
+ $table
+ ->addColumn('phone','string',['limit'=>20,'default'=>'','after'=>'email','null'=>false,'comment'=>'手机号'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210825095514_question_add_field_phone.php b/database/migrations/20210825095514_question_add_field_phone.php
new file mode 100644
index 0000000..09f5786
--- /dev/null
+++ b/database/migrations/20210825095514_question_add_field_phone.php
@@ -0,0 +1,36 @@
+table('question');
+ $table
+ ->addColumn('phone','string',['limit'=>20,'default'=>'','after'=>'email','null'=>false,'comment'=>'手机号'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20210923024657_images_files_create.php b/database/migrations/20210923024657_images_files_create.php
new file mode 100644
index 0000000..8c935e3
--- /dev/null
+++ b/database/migrations/20210923024657_images_files_create.php
@@ -0,0 +1,45 @@
+table('attachment',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'附件表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('path','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'相对路径'])
+ ->addColumn('local','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'本地路径'])
+ ->addColumn('hash','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'文件hash'])
+ ->addColumn('md5','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'文件md5'])
+ ->addColumn('name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文件名'])
+ ->addColumn('type','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文件类型'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20210928085406_bulk_buy_modify_field.php b/database/migrations/20210928085406_bulk_buy_modify_field.php
new file mode 100644
index 0000000..b1bb8e1
--- /dev/null
+++ b/database/migrations/20210928085406_bulk_buy_modify_field.php
@@ -0,0 +1,36 @@
+table('bulk_buy');
+ $table
+ ->addColumn('model_name','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'产品型号'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20211012060159_advertise_modify_field.php b/database/migrations/20211012060159_advertise_modify_field.php
new file mode 100644
index 0000000..01092f6
--- /dev/null
+++ b/database/migrations/20211012060159_advertise_modify_field.php
@@ -0,0 +1,36 @@
+table('advertisement');
+ $table
+ ->changeColumn('play_order','integer',['limit'=>10,'signed'=>false,'default'=>1,'null'=>false,'comment'=>'轮播顺序'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20211223033655_user_create.php b/database/migrations/20211223033655_user_create.php
new file mode 100644
index 0000000..03ca4b6
--- /dev/null
+++ b/database/migrations/20211223033655_user_create.php
@@ -0,0 +1,57 @@
+table('user',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8mb4','primary_key'=>'id','comment'=>'用户表'])->addIndex('id');
+ $table
+ ->addColumn('uc_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'用户全局维一ID'])
+ ->addColumn('admin_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'管理员ID'])
+ ->addColumn('org_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'组织ID'])
+ ->addColumn('role_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'用户角色ID'])
+ ->addColumn('dept_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'部门ID'])
+ ->addColumn('staff_code','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'用户唯一标识符'])
+ ->addColumn('nickname','string',['limit'=>64,'default'=>'','null'=>false,'comment'=>'用户昵称'])
+ ->addColumn('mobile','string',['limit'=>11,'default'=>'','null'=>false,'comment'=>'手机号'])
+ ->addColumn('email','string',['limit'=>64,'default'=>'','null'=>false,'comment'=>'邮箱'])
+ ->addColumn('avatar','string',['limit'=>120,'default'=>'','null'=>false,'comment'=>'用户头像'])
+ ->addColumn('gender','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'0为保密;1为男;2为女'])
+ ->addColumn('signin_ip','string',['limit'=>15,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'登录ip'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'0为启用;1为禁用'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'注册时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->addColumn('signin_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'登录时间'])
+ ->addIndex('nickname')
+ ->addIndex('mobile')
+ ->addIndex('admin_id')
+ ->addIndex('dept_id')
+ ->addIndex('uc_id')
+ ->create();
+ }
+}
diff --git a/database/migrations/20220321015125_investment_create.php b/database/migrations/20220321015125_investment_create.php
new file mode 100644
index 0000000..593b416
--- /dev/null
+++ b/database/migrations/20220321015125_investment_create.php
@@ -0,0 +1,53 @@
+table('investment',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'招商留言表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('country_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'国家ID'])
+ ->addColumn('province_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'省'])
+ ->addColumn('city_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'市'])
+ ->addColumn('area','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'合作区域'])
+ ->addColumn('phone','string',['limit'=>30,'default'=>'','null'=>false,'comment'=>'手机号'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'姓名'])
+ ->addColumn('email','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'邮箱'])
+ ->addColumn('wechat','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'微信'])
+ ->addColumn('qq','string',['limit'=>60,'default'=>'','null'=>false,'comment'=>'QQ'])
+ ->addColumn('desc','text',['comment'=>'留言详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('is_open','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'厂家查看:0=否,1=是'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220328015901_investment_add_field.php b/database/migrations/20220328015901_investment_add_field.php
new file mode 100644
index 0000000..33257ae
--- /dev/null
+++ b/database/migrations/20220328015901_investment_add_field.php
@@ -0,0 +1,36 @@
+table('investment');
+ $table
+ ->addColumn('from','string',['limit'=>30,'default'=>'','after'=>'area','null'=>false,'comment'=>'来源'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20220414085023_system_config_create.php b/database/migrations/20220414085023_system_config_create.php
new file mode 100644
index 0000000..ab71518
--- /dev/null
+++ b/database/migrations/20220414085023_system_config_create.php
@@ -0,0 +1,47 @@
+table('system_config',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'系统配置'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('type','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'类型1=文本,2=图片,3=富文本'])
+ ->addColumn('page','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'所属页'])
+ ->addColumn('pos','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'位置'])
+ ->addColumn('name','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'配置名'])
+ ->addColumn('value','text',['null'=>true,'default'=>null,'comment'=>'配置值'])
+ ->addColumn('image','text',['null'=>true,'default'=>null,'comment'=>'图片'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064045_resource_create.php b/database/migrations/20220419064045_resource_create.php
new file mode 100644
index 0000000..3d57112
--- /dev/null
+++ b/database/migrations/20220419064045_resource_create.php
@@ -0,0 +1,55 @@
+table('resource',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'资源中心表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('resource_type_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'资源中心分类ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文章标题'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章描述'])
+ ->addColumn('thumb','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章缩略图'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('detail','text',['comment'=>'详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('click_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'点击次数'])
+ ->addColumn('meta_title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'标题'])
+ ->addColumn('brief','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('keywords','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'关键字'])
+ ->addColumn('is_outer_chain','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'是否外链,0=是,1=否'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'状态,0=启动,1=禁用'])
+ ->addColumn('is_on_index','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'是否在首页,0=否,1=是'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064056_brand_create.php b/database/migrations/20220419064056_brand_create.php
new file mode 100644
index 0000000..64ba1b6
--- /dev/null
+++ b/database/migrations/20220419064056_brand_create.php
@@ -0,0 +1,55 @@
+table('brand',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'品牌矩阵表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('brand_type_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'品牌矩阵分类ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文章标题'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章描述'])
+ ->addColumn('thumb','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章缩略图'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('detail','text',['comment'=>'详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('click_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'点击次数'])
+ ->addColumn('meta_title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'标题'])
+ ->addColumn('brief','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('keywords','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'关键字'])
+ ->addColumn('is_outer_chain','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'是否外链,0=是,1=否'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'状态,0=启动,1=禁用'])
+ ->addColumn('is_on_index','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'是否在首页,0=否,1=是'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064216_brand_type_create.php b/database/migrations/20220419064216_brand_type_create.php
new file mode 100644
index 0000000..1f6a9cb
--- /dev/null
+++ b/database/migrations/20220419064216_brand_type_create.php
@@ -0,0 +1,44 @@
+table('brand_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'品牌矩阵分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064224_resource_type_create.php b/database/migrations/20220419064224_resource_type_create.php
new file mode 100644
index 0000000..afb3b01
--- /dev/null
+++ b/database/migrations/20220419064224_resource_type_create.php
@@ -0,0 +1,44 @@
+table('resource_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'资源中心分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064719_news_type_create.php b/database/migrations/20220419064719_news_type_create.php
new file mode 100644
index 0000000..9ede708
--- /dev/null
+++ b/database/migrations/20220419064719_news_type_create.php
@@ -0,0 +1,44 @@
+table('news_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'新闻分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419064722_news_create.php b/database/migrations/20220419064722_news_create.php
new file mode 100644
index 0000000..a1045ac
--- /dev/null
+++ b/database/migrations/20220419064722_news_create.php
@@ -0,0 +1,55 @@
+table('news',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'新闻动态表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('news_type_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'品牌矩阵分类ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文章标题'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章描述'])
+ ->addColumn('thumb','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章缩略图'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('detail','text',['comment'=>'详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('click_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'点击次数'])
+ ->addColumn('meta_title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'标题'])
+ ->addColumn('brief','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('keywords','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'关键字'])
+ ->addColumn('is_outer_chain','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'是否外链,0=是,1=否'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'状态,0=启动,1=禁用'])
+ ->addColumn('is_on_index','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'是否在首页,0=否,1=是'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419082055_join_create.php b/database/migrations/20220419082055_join_create.php
new file mode 100644
index 0000000..a964333
--- /dev/null
+++ b/database/migrations/20220419082055_join_create.php
@@ -0,0 +1,55 @@
+table('join',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'加入我们表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('language_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'语音包ID'])
+ ->addColumn('join_type_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'加入我们分类ID'])
+ ->addColumn('site_id','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'站点ID'])
+ ->addColumn('title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'文章标题'])
+ ->addColumn('desc','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章描述'])
+ ->addColumn('thumb','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'文章缩略图'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('detail','text',['comment'=>'详情'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'signed'=>false,'null'=>false,'comment'=>'排序'])
+ ->addColumn('click_num','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'点击次数'])
+ ->addColumn('meta_title','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'标题'])
+ ->addColumn('brief','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'描述'])
+ ->addColumn('keywords','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'关键字'])
+ ->addColumn('is_outer_chain','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'是否外链,0=是,1=否'])
+ ->addColumn('status','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>1,'null'=>false,'comment'=>'状态,0=启动,1=禁用'])
+ ->addColumn('is_on_index','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'是否在首页,0=否,1=是'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220419082058_join_type_create.php b/database/migrations/20220419082058_join_type_create.php
new file mode 100644
index 0000000..eb8dd9d
--- /dev/null
+++ b/database/migrations/20220419082058_join_type_create.php
@@ -0,0 +1,44 @@
+table('join_type',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'加入我们分类表'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'分类名称'])
+ ->addColumn('desc','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类描述'])
+ ->addColumn('icon','string',['limit'=>128,'default'=>'','null'=>false,'comment'=>'分类图标'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220420061448_resource_add_field.php b/database/migrations/20220420061448_resource_add_field.php
new file mode 100644
index 0000000..4f44c93
--- /dev/null
+++ b/database/migrations/20220420061448_resource_add_field.php
@@ -0,0 +1,36 @@
+table('resource',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'资源中心表'])->addIndex('id');
+ $table
+ ->addColumn('s_title','string',['limit'=>255,'default'=>'','after'=>'title','null'=>false,'comment'=>'小标题'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20220420071052_brand_add_field.php b/database/migrations/20220420071052_brand_add_field.php
new file mode 100644
index 0000000..2ff5e14
--- /dev/null
+++ b/database/migrations/20220420071052_brand_add_field.php
@@ -0,0 +1,44 @@
+table('brand',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'品牌矩阵表'])->addIndex('id');
+ $table
+ ->addColumn('website','string',['limit'=>128,'default'=>'','after'=>'brief','null'=>false,'comment'=>'网址'])
+ ->addColumn('cname','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'中文名'])
+ ->addColumn('en_name','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'英文名'])
+ ->addColumn('belong','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'所属公司'])
+ ->addColumn('turnover','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'营业额'])
+ ->addColumn('brand_cate','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'品牌类型'])
+ ->addColumn('work_address','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'办公地点'])
+ ->addColumn('founded','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'成立时间'])
+ ->addColumn('founder','string',['limit'=>255,'default'=>'','after'=>'brief','null'=>false,'comment'=>'创始人'])
+ ->update();
+ }
+}
diff --git a/database/migrations/20220513072007_video_create.php b/database/migrations/20220513072007_video_create.php
new file mode 100644
index 0000000..2ee1a7d
--- /dev/null
+++ b/database/migrations/20220513072007_video_create.php
@@ -0,0 +1,45 @@
+table('video',['engine'=>'InnoDB','auto_increment'=>true,'charset'=>'utf8','primary_key'=>'id','comment'=>'视频管理'])->addIndex('id');
+ $table
+ ->addColumn('platform_id','integer',['limit'=>10,'default'=>0,'null'=>false,'comment'=>'平台ID'])
+ ->addColumn('site_id','integer',['limit'=>MysqlAdapter::INT_TINY,'default'=>0,'null'=>false,'comment'=>'语言包ID'])
+ ->addColumn('name','string',['limit'=>32,'default'=>'','null'=>false,'comment'=>'视频名称'])
+ ->addColumn('image','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'视频图片'])
+ ->addColumn('url','string',['limit'=>255,'default'=>'','null'=>false,'comment'=>'链接'])
+ ->addColumn('sort','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'排序'])
+ ->addColumn('is_top','integer',['limit'=>MysqlAdapter::INT_TINY,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'是否置顶'])
+ ->addColumn('create_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'创建时间'])
+ ->addColumn('update_time','integer',['limit'=>10,'signed'=>false,'default'=>0,'null'=>false,'comment'=>'更新时间'])
+ ->create();
+ }
+}
diff --git a/database/migrations/20220622100342_goods_add_field_hot.php b/database/migrations/20220622100342_goods_add_field_hot.php
new file mode 100644
index 0000000..1053daa
--- /dev/null
+++ b/database/migrations/20220622100342_goods_add_field_hot.php
@@ -0,0 +1,38 @@
+table('goods');
+ $table
+ ->addColumn('is_hot','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'price','signed'=>false,'null'=>false,'default'=>1,'comment'=>'是否热门,0=是,1=否'])
+ ->addColumn('is_recommend','integer',['limit'=>MysqlAdapter::INT_TINY,'after'=>'price','signed'=>false,'null'=>false,'default'=>1,'comment'=>'是否推荐,0=是,1=否'])
+ ->update();
+ }
+}
diff --git a/database/seeds/AdminAdd.php b/database/seeds/AdminAdd.php
new file mode 100644
index 0000000..6b65a8f
--- /dev/null
+++ b/database/seeds/AdminAdd.php
@@ -0,0 +1,89 @@
+ null,
+ 'mobile' => '15207335533',
+ 'code' => 'YC001',
+ 'platform_id'=> 0,
+ 'role_id' => 1,
+ 'org_id' => 1,
+ 'dept_group_id'=> 1,
+ 'dept_id' => 1,
+ 'avatar' => 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ 'nickname' => 'admin',
+ 'username' => 'admin',
+ 'password' => 'a20dddcf28da48f605ac8412384b3e36',
+ 'create_ip' => '127.0.0.1',
+ 'create_time'=> time(),
+ 'update_time'=> time(),
+ ],[
+ 'id' => null,
+ 'mobile' => '15207335533',
+ 'code' => 'YC002',
+ 'platform_id'=> 1,
+ 'role_id' => 1,
+ 'org_id' => 1,
+ 'dept_group_id'=> 1,
+ 'dept_id' => 1,
+ 'avatar' => 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ 'nickname' => 'yottamaster',
+ 'username' => 'yottamaster',
+ 'password' => 'a20dddcf28da48f605ac8412384b3e36',
+ 'create_ip' => '127.0.0.1',
+ 'create_time'=> time(),
+ 'update_time'=> time(),
+ ],[
+ 'id' => null,
+ 'mobile' => '15207335533',
+ 'code' => 'YC003',
+ 'platform_id'=> 2,
+ 'role_id' => 1,
+ 'org_id' => 1,
+ 'dept_group_id'=> 1,
+ 'dept_id' => 1,
+ 'avatar' => 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ 'nickname' => 'idsonix',
+ 'username' => 'idsonix',
+ 'password' => 'a20dddcf28da48f605ac8412384b3e36',
+ 'create_ip' => '127.0.0.1',
+ 'create_time'=> time(),
+ 'update_time'=> time(),
+ ],[
+ 'id' => null,
+ 'mobile' => '15207335533',
+ 'code' => 'YC004',
+ 'platform_id'=> 3,
+ 'role_id' => 1,
+ 'org_id' => 1,
+ 'dept_group_id'=> 1,
+ 'dept_id' => 1,
+ 'avatar' => 'https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif',
+ 'nickname' => 'ntonpower',
+ 'username' => 'ntonpower',
+ 'password' => 'a20dddcf28da48f605ac8412384b3e36',
+ 'create_ip' => '127.0.0.1',
+ 'create_time'=> time(),
+ 'update_time'=> time(),
+ ],
+
+ ];
+
+ $table = $this->table('admin');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/AdminConfigInit.php b/database/seeds/AdminConfigInit.php
new file mode 100644
index 0000000..360d6f9
--- /dev/null
+++ b/database/seeds/AdminConfigInit.php
@@ -0,0 +1,92 @@
+ null,
+ "platform_id" => 1,
+ "language_id" => 0,
+ "site_id" => 1,
+ "type" => 2,
+ "page" => "logo",
+ "pos" => "logo",
+ "name" => "logo",
+ "value" => "",
+ "image" => "[[\"uid\" => \"1650272555373\",\"url\" => \"https => //cdn.yottamaster.com/2022/05/19/cms_165295142351423813XLYXCnNj.jpg\",\"image\" => \"2022/05/19/cms_165295142351423813XLYXCnNj.jpg\",\"md5\" => \"3795d70979842ad5706bdd4b8d367581\",\"status\" => \"success\"]]",
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 0,
+ "site_id" => 1,
+ "type" => 2,
+ "page" => "尾部-logo",
+ "pos" => "footer",
+ "name" => "logo",
+ "value" => "",
+ "image" => "[[\"uid\" => \"1650272555373\",\"url\" => \"https => //cdn.yottamaster.com/2022/05/19/cms_165295142351423813XLYXCnNj.jpg\",\"image\" => \"2022/05/19/cms_165295142351423813XLYXCnNj.jpg\",\"md5\" => \"3795d70979842ad5706bdd4b8d367581\",\"status\" => \"success\"]]",
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 0,
+ "site_id" => 1,
+ "type" => 1,
+ "page" => "尾部-版权",
+ "pos" => "footer",
+ "name" => "copyright",
+ "value" => "Copyright©2018-2028 ORICO Technologies Co.,Ltd 版权所有",
+ "image" => null,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 0,
+ "site_id" => 1,
+ "type" => 1,
+ "page" => "尾部-备案号1",
+ "pos" => "footer",
+ "name" => "beian1",
+ "value" => "粤ICP备2022066802号-1",
+ "image" => "",
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 0,
+ "site_id" => 1,
+ "type" => 1,
+ "page" => "尾部-备案号2",
+ "pos" => "footer",
+ "name" => "beian2",
+ "value" => "粤公网安备 44030702002297号",
+ "image" => null,
+ "create_time" => time(),
+ "update_time" => time()
+ ]
+ ];
+ $table = $this->table('system_config');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/CountryInit.php b/database/seeds/CountryInit.php
new file mode 100644
index 0000000..3cf074c
--- /dev/null
+++ b/database/seeds/CountryInit.php
@@ -0,0 +1,1210 @@
+ null,
+ 'code' => $item['code'],
+ 'en' => $item['en'],
+ 'locale' => $item['locale'],
+ 'zh' => $item['zh'],
+ 'tw' => $item['tw'],
+ 'icon' => '',
+ 'create_time' => time(),
+ ];
+ }
+
+ $table = $this->table('country');
+ $table->insert($result)->saveData();
+
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/CurrencyInit.php b/database/seeds/CurrencyInit.php
new file mode 100644
index 0000000..65169fd
--- /dev/null
+++ b/database/seeds/CurrencyInit.php
@@ -0,0 +1,80 @@
+ null,
+ 'name' => '人民币',
+ 'code' => 'CNY',
+ 'signal' => '¥',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '美元',
+ 'code' => 'USD',
+ 'signal' => '$',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '日元',
+ 'code' => 'JPY',
+ 'signal' => '¥',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '欧元',
+ 'code' => 'EUR',
+ 'signal' => '',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '越南盾',
+ 'code' => 'VND',
+ 'signal' => '',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '泰铢',
+ 'code' => 'THP',
+ 'signal' => 'BT.',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '盾',
+ 'code' => 'IDR',
+ 'signal' => 'Rps.',
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '巴西雷亚尔',
+ 'code' => 'BRL',
+ 'signal' => '',
+ 'status' => 0,
+ 'create_time' => time()
+ ]
+ ];
+
+ $table = $this->table('currency');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/LanguageInit.php b/database/seeds/LanguageInit.php
new file mode 100644
index 0000000..e9ea8f8
--- /dev/null
+++ b/database/seeds/LanguageInit.php
@@ -0,0 +1,132 @@
+ null,
+ 'name' => '中文',
+ 'code' => 'zh-cn',
+ 'icon' => 'zh-cn.jpg',
+ 'locale' => 'zh-cn',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '英文',
+ 'code' => 'en',
+ 'icon' => 'en.jpg',
+ 'locale' => 'en',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '日文',
+ 'code' => 'jp',
+ 'icon' => 'jp.jpg',
+ 'locale' => 'jp',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '越南语',
+ 'code' => 'VU',
+ 'icon' => 'VU.jpg',
+ 'locale' => 'VU',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '泰语',
+ 'code' => 'TH',
+ 'icon' => 'TH.jpg',
+ 'locale' => 'TH',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '印尼语',
+ 'code' => 'IN',
+ 'icon' => 'IN.jpg',
+ 'locale' => 'IN',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '韩语',
+ 'code' => 'KR',
+ 'icon' => 'kr.jpg',
+ 'locale' => 'KR',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '葡萄牙语',
+ 'code' => 'pt',
+ 'icon' => 'pt.jpg',
+ 'locale' => 'pt',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '德语',
+ 'code' => 'de',
+ 'icon' => 'de.jpg',
+ 'locale' => 'de',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '俄语',
+ 'code' => 'ru',
+ 'icon' => 'ru.jpg',
+ 'locale' => 'ru',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '法语',
+ 'code' => 'fr',
+ 'icon' => 'fr.jpg',
+ 'locale' => 'fr',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '阿拉伯语',
+ 'code' => 'al',
+ 'icon' => 'al.jpg',
+ 'locale' => 'al',
+ 'sort' => mt_rand(1,255),
+ 'status' => 0,
+ 'create_time' => time()
+ ]
+ ];
+
+ $table = $this->table('language');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/PlatformInit.php b/database/seeds/PlatformInit.php
new file mode 100644
index 0000000..70a156f
--- /dev/null
+++ b/database/seeds/PlatformInit.php
@@ -0,0 +1,39 @@
+ 1,
+ "name" => Env::get('platform_name'),
+ "vi_color1" => "#1233ab",
+ "vi_color2" => "#1231cd",
+ "vi_color3" => "#1112ef",
+ "language_id" => 1,
+ "currency_id" => 1,
+ "desc" => "",
+ "icon" => "",
+ "sort" => 1,
+ "status" => 0,
+ "create_time" => time(),
+ "update_time" => time()
+ ]
+ ];
+
+ $table = $this->table('platform');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/RoleInitAdd.php b/database/seeds/RoleInitAdd.php
new file mode 100644
index 0000000..e71e4dc
--- /dev/null
+++ b/database/seeds/RoleInitAdd.php
@@ -0,0 +1,73 @@
+ null,
+ 'name' => 'admin',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '财务',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '总经办',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '业务经理',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '业务员',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '供应链',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '产品经理',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '产品编辑',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '人力资源',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '商务/跟单',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '新媒体宣传',
+ 'create_time' => time()
+ ],[
+ 'id' => null,
+ 'name' => '后台接口测试专用',
+ 'create_time' => time()
+ ]
+ ];
+
+ $table = $this->table('role');
+ $table->insert($data)->saveData();
+
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/SiteCurrencyInit.php b/database/seeds/SiteCurrencyInit.php
new file mode 100644
index 0000000..ac0cba7
--- /dev/null
+++ b/database/seeds/SiteCurrencyInit.php
@@ -0,0 +1,86 @@
+ null,
+ "platform_id" => 1,
+ "currency_id" => 1,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 2,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 3,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 4,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 5,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 5,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 6,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 7,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "currency_id" => 8,
+ "create_time" => time(),
+ "update_time" => time()
+ ]
+ ];
+ $table = $this->table('platform_coin');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/SiteInit.php b/database/seeds/SiteInit.php
new file mode 100644
index 0000000..a467455
--- /dev/null
+++ b/database/seeds/SiteInit.php
@@ -0,0 +1,108 @@
+ 1,
+ "platform_id" => 1,
+ "language_id" => 1,
+ "currency_id" => 1,
+ "domain" => $plat_en_name.".com",
+ "status" => 0,
+ "app_id" => "4d08fcadda5c097eb8b7eb4492551cdc",
+ "app_key" => "7145cc463e91d43a17810950d3819eb2",
+ "create_time" => 1650012195,
+ "update_time" => 1652947961
+ ],
+ [
+ "id" => 2,
+ "platform_id" => 1,
+ "language_id" => 2,
+ "currency_id" => 2,
+ "domain" => $plat_en_name.".us",
+ "status" => 0,
+ "app_id" => "a97b5fe1492ae774f1f0b12bf518d604",
+ "app_key" => "268674cd38f97540d6d990d8248cc6b3",
+ "create_time" => 1650012207,
+ "update_time" => 1652947965
+ ],
+ [
+ "id" => 3,
+ "platform_id" => 1,
+ "language_id" => 3,
+ "currency_id" => 3,
+ "domain" => $plat_en_name.".jp",
+ "status" => 0,
+ "app_id" => "0093bc0066f8c9a70c4389831019863a",
+ "app_key" => "0fb6f16ea1c7a3aaa3f6540ce8d0de99",
+ "create_time" => 1650012218,
+ "update_time" => 1652947969
+ ],
+ [
+ "id" => 4,
+ "platform_id" => 1,
+ "language_id" => 4,
+ "currency_id" => 5,
+ "domain" => $plat_en_name.".vn",
+ "status" => 0,
+ "app_id" => "cf45663d54e3f6426eb597f9f3e593da",
+ "app_key" => "0b55b377c51b0e5f81a31b79527e4916",
+ "create_time" => 1650012227,
+ "update_time" => 1652947975
+ ],
+ [
+ "id" => 5,
+ "platform_id" => 1,
+ "language_id" => 5,
+ "currency_id" => 6,
+ "domain" => $plat_en_name.".th",
+ "status" => 0,
+ "app_id" => "db448953994b5eed73c975b2b695bd95",
+ "app_key" => "edb87326041984651081237f802b41cb",
+ "create_time" => 1650012243,
+ "update_time" => 1652947980
+ ],
+ [
+ "id" => 6,
+ "platform_id" => 1,
+ "language_id" => 6,
+ "currency_id" => 7,
+ "domain" => $plat_en_name.".in",
+ "status" => 0,
+ "app_id" => "627f2bddcdf911bb4cdb66ec59b4164d",
+ "app_key" => "fc4b9fbd33f53d2da6619c1ea4151c34",
+ "create_time" => 1650012258,
+ "update_time" => 1652947985
+ ],
+ [
+ "id" => 7,
+ "platform_id" => 1,
+ "language_id" => 7,
+ "currency_id" => 1,
+ "domain" => $plat_en_name.".kr",
+ "status" => 0,
+ "app_id" => "0e082a09f3049391d857946ac0397946",
+ "app_key" => "3f67328e1ab41f9c8ada33ccad5d2e1f",
+ "create_time" => 1650012281,
+ "update_time" => 1652947990
+ ]
+ ];
+ $table = $this->table('site');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/SiteLanguageInit.php b/database/seeds/SiteLanguageInit.php
new file mode 100644
index 0000000..cdc1faa
--- /dev/null
+++ b/database/seeds/SiteLanguageInit.php
@@ -0,0 +1,58 @@
+ null,
+ "platform_id" => 1,
+ "language_id" => 1,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 2,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 3,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 4,
+ "create_time" => time(),
+ "update_time" => time()
+ ],
+ [
+ "id" => null,
+ "platform_id" => 1,
+ "language_id" => 5,
+ "create_time" => time(),
+ "update_time" => time()
+ ]
+ ];
+
+ $table = $this->table('platform_language');
+ $table->insert($data)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/database/seeds/TwoLevelData.php b/database/seeds/TwoLevelData.php
new file mode 100644
index 0000000..51024de
--- /dev/null
+++ b/database/seeds/TwoLevelData.php
@@ -0,0 +1,65 @@
+ $item['code'],
+ 'pid' => 0,
+ 'name' => $item['name'],
+ 'level' => 1,
+ ];
+ if (isset($item['children'])) {
+ foreach ($item['children'] as $item1) {
+ $result[] = [
+ 'id' => $item1['code'],
+ 'pid' => $item['code'],
+ 'name' => $item1['name'],
+ 'level' => 2
+ ];
+ }
+ if (isset($item1['children'])) {
+ foreach ($item1['children'] as $item2) {
+ $result[] = [
+ 'id' => $item2['code'],
+ 'pid' => $item1['code'],
+ 'name' => $item2['name'],
+ 'level' => 3
+ ];
+ }
+ if (isset($item2['children'])) {
+ foreach ($item2['children'] as $item3) {
+ $result[] = [
+ 'id' => $item3['code'],
+ 'pid' => $item2['code'],
+ 'name' => $item3['name'],
+ 'level' => 4
+ ];
+ }
+ }
+ }
+ }
+ }
+
+ $table = $this->table('area');
+ $table->insert($result)->saveData();
+ }
+}
\ No newline at end of file
diff --git a/env.sample b/env.sample
new file mode 100644
index 0000000..8ec03a8
--- /dev/null
+++ b/env.sample
@@ -0,0 +1,52 @@
+APP_DEBUG=trueIdsonix
+PLATFORM_NAME="合金桌面"
+PLATFORM_EN_NAME="setmspace"
+
+[APP]
+DEFAULT_TIMEZONE=Asia/Shanghai
+
+[DATABASE]
+TYPE = mysql
+HOSTNAME = 127.0.0.1
+DATABASE = setmspace
+USERNAME = root
+PASSWORD = 123456
+HOSTPORT = 3306
+CHARSET = utf8
+PREFIX = s_
+DEBUG = true
+
+[REDIS]
+HOST=127.0.0.1
+PORT=6379
+PASS=orico@f2b211
+SELECT=0
+
+[JWT_CONFIG]
+ISS=setmspace
+EXP=604801
+
+[LANG]
+default_lang=zh-cn
+
+[QINIU]
+cdn=https://cdn.yottamaster.com/
+
+[EMAIL]
+MAIL_MAILER=smtp
+MAIL_HOST=smtp.qiye.aliyun.com
+MAIL_PORT=465
+MAIL_USERNAME=services@orico.com.cn
+MAIL_PASSWORD=
+MAIL_ENCRYPTION=null
+MAIL_FROM_ADDRESS=services@orico.com.cn
+MAIL_FROM_NAME=ORICO
+#MAIL_TO_ADDRESS=supports@yottamaster.com
+MAIL_TO_ADDRESS=yulinzhihou@163.com
+
+[SSO]
+UC_URL=https://dev.uc.f2b211.com
+UC_API_VERSION=v1
+
+[CDN]
+URL=https://cdn.yottamaster.com/
diff --git a/extend/apiRes/Api.php b/extend/apiRes/Api.php
new file mode 100644
index 0000000..4ee34aa
--- /dev/null
+++ b/extend/apiRes/Api.php
@@ -0,0 +1,101 @@
+ [
+ 'errno' => 0,
+ 'errmsg' => '操作成功!',
+ 'data' => []
+ ],
+ 'error' => [
+ 'errno' => 2001,
+ 'errmsg' => '操作错误!',
+ 'data' => []
+ ],
+ 'NoData' => [
+ 'errno' => 2002,
+ 'errmsg' => '没有数据!',
+ 'data' => []
+ ],
+ 'NotLoggedIn' => [
+ 'errno' => 2003,
+ 'errmsg' => '未登录',
+ 'data' => []
+ ]
+ ];
+
+ private function __construct($erro)
+ {
+ isset($erro) || die('请确认返回类型!');
+ $this->state = $this->default_states[$erro];
+ return $this;
+ }
+
+ // 单例
+ public static function result($erro)
+ {
+ if (!self::$response) {
+ self::$response = new self($erro);
+ }
+ return self::$response;
+ }
+
+ // 返回错误
+ public static function error($msg='', $data=[], $to_array=false)
+ {
+ $ins = self::result('error');
+ if ($msg) {
+ $ins = $ins->message($msg);
+ }
+
+ return $ins->response($data, $to_array);
+ }
+
+ // 返回成功
+ public static function success($msg='', $data=[], $to_array=false)
+ {
+ $ins = self::result('success');
+ if ($msg) {
+ $ins = $ins->message($msg);
+ }
+
+ return $ins->response($data, $to_array);
+ }
+
+ // 写入返回信息
+ public function message($message='')
+ {
+ $message ? $this->state['errmsg'] = $message : '';
+ return $this;
+ }
+
+ // 返回结果
+ public function response($data=[], $to_array=false)
+ {
+ if (!empty($data)) {
+ $this->state['data'] = $data;
+ }
+ if (request()->isJson() || $to_array) {
+ $output = $this->state;
+ } else {
+ $output = json_encode($this->state, JSON_UNESCAPED_UNICODE);
+ }
+ return $output;
+ }
+
+ /**
+ * 转成数组
+ */
+ public function toArray()
+ {
+ if (is_array($this->state)) {
+ return $this->state;
+ }
+ return json_decode($this->state, true);
+ }
+}
diff --git a/extend/encryption/Rsa.php b/extend/encryption/Rsa.php
new file mode 100644
index 0000000..2e2dac0
--- /dev/null
+++ b/extend/encryption/Rsa.php
@@ -0,0 +1,292 @@
+public_key = $this->getPublicKey($config['public']);
+ } else {
+ $this->public_key = openssl_pkey_get_public($config['public']);
+ if (!$this->public_key) {
+ die('请检查公钥是否正确');
+ }
+ }
+
+ if (is_file($config['private'])) {
+ $this->private_key = $this->getPrivateKey($config['private']);
+ } else {
+ $this->private_key = openssl_pkey_get_private($config['private']);
+ if (!$this->private_key) {
+ die('请检查私钥是否正确');
+ }
+ }
+ }
+ if ($config['cert_save_path']) $this->cert_save_path = $config['cert_save_path'];
+ }
+
+ /**
+ * 单例获取对象实例
+ */
+ public static function instance($config=array())
+ {
+ if (!self::$rsa) {
+ if (empty($config)) {
+ $config = [
+ 'public' => '',
+ 'private' => '',
+ 'cert_save_path' => ''
+ ];
+ }
+ self::$rsa = new self($config);
+ }
+ return self::$rsa;
+ }
+
+ /**
+ * 读取文件
+ */
+ private function fileGet($file)
+ {
+ if (!file_exists($file)) {
+ die($file . "不是文件");
+ }
+ return file_get_contents($file);
+ }
+
+ /**
+ * 获取公钥
+ */
+ private function getPublicKey($path)
+ {
+ $pubKey = $this->fileGet($path);
+ if (!$pubKey) {
+ die('请检查公钥路径是否正确');
+ }
+ return openssl_pkey_get_public($pubKey);
+ }
+
+ /**
+ * 获取私钥
+ */
+ private function getPrivateKey($path)
+ {
+ $priKey = $this->fileGet($path);
+ if (!$priKey) {
+ die('请检查私钥路径是否正确');
+ }
+ return openssl_pkey_get_private($priKey);
+ }
+
+ /**
+ * 使用私钥生成签名
+ * @param string 用于生成签名的字符串
+ * @return string 签名后的值
+ */
+ public function signPrivate($data)
+ {
+ $signature = false;
+ if (openssl_sign($data, $signature, $this->private_key)) {
+ $signature = base64_encode($signature);
+ }
+ return $signature;
+ }
+
+ /**
+ * 使用公钥验签
+ * @param $data = array('data'='','signature'='')
+ * @return bool
+ */
+ public function verifyPublic($data)
+ {
+ $bool = false;
+ if (!$data['data'] || !$data['signature']) {
+ die('数据源或签名值为出错!');
+ }
+ $result = base64_decode($data['signature']);
+ switch (openssl_verify($data['data'], $result, $this->public_key)) {
+ case 1:
+ $bool = true;
+ break;
+ case 0:
+ case -1:
+ $bool = false;
+ break;
+ default:
+ $bool = false;
+ }
+ return $bool;
+ }
+
+ /**
+ * 使用公钥加密
+ */
+ public function encryptPublic($data)
+ {
+ $crypted = false;
+ if (is_array($data)) {
+ $data = json_encode($data);
+ }
+ $cryp = strrev($data); // 将数据前后反转再加密
+ if (openssl_public_encrypt($cryp, $crypted, $this->public_key, OPENSSL_PKCS1_PADDING)) {
+ $crypted = base64_encode($crypted);
+ }
+ return $crypted;
+ }
+
+ /**
+ * 使用公钥分块加密
+ */
+ public function chunkEncryptPublic($data, $limit = 117)
+ {
+ if (is_array($data)) {
+ $data = json_encode($data);
+ }
+ $datas = str_split($data, $limit);
+
+ $crypteds = [];
+ foreach ($datas as $key => $val) {
+ $crypteds[$key] = $this->encryptPublic($val);
+ }
+ return $crypteds;
+ }
+
+ /**
+ * 使用私钥解密
+ */
+ public function decryptPrivate($encrypted)
+ {
+ $decrypted = '';
+ $data = base64_decode($encrypted);
+ if (openssl_private_decrypt($data, $decrypted, $this->private_key, OPENSSL_PKCS1_PADDING)) {
+ $decrypted = rtrim(strrev($decrypted), '\0');
+ }
+ return $decrypted;
+ }
+
+ /**
+ * 使用私钥分块解密
+ */
+ public function chunkDecryptPrivate($encrypteds)
+ {
+ $decrypted = '';
+ $encrypteds = htmlspecialchars_decode($encrypteds);
+ if (!is_array($encrypteds)) {
+ $arr = explode(',', $encrypteds);
+ if ($arr) {
+ $encrypteds = $arr;
+ } else {
+ return json_decode($this->decryptPrivate($encrypteds));
+ }
+ }
+
+ foreach ($encrypteds as $key => $val) {
+ $decrypted .= $this->decryptPrivate($val);
+ }
+
+ $res = json_decode($decrypted, true);
+ if (is_array($res)) return $res;
+ return json_decode($res, true);
+ }
+
+ /**
+ * 生成公私钥
+ */
+ public function createRsa($writeFile=false)
+ {
+ $config = array("config" => $this->openssl_cnf_path);
+
+ // 生成公私钥
+ $privkey = openssl_pkey_new($config);
+ openssl_pkey_export($privkey, $private_key, null, $config); // 导出私钥$private_key
+ $public_key = openssl_pkey_get_details($privkey); // 导出公钥$public_key
+
+ if (!$writeFile) {
+ return array('private_key' => $private_key, 'public_key' => $public_key['key']);
+ }
+
+ $publicPath = $this->cert_save_path . "rsa_public_key.pem"; // 生成公钥路径
+ $privatePath = $this->cert_save_path . "rsa_private_key.pem"; // 私钥文件路径
+
+ // 生成公钥文件
+ if (!is_writeable($publicPath)) {
+ chmod($publicPath, 0755);
+ }
+ $fp = fopen($publicPath, "w");
+ fwrite($fp, $public_key['key']);
+ fclose($fp);
+ // 生成私钥文件
+ if (!is_writeable($privatePath)) {
+ chmod($privatePath, 0755);
+ }
+ $fp = fopen($privatePath, "w");
+ fwrite($fp, $private_key);
+ fclose($fp);
+ }
+
+ /**
+ * 生成证书和密钥
+ */
+ public function createCsr($writeFile=false)
+ {
+ $dn = array(
+ "countryName" => 'CN', // 所在国家名称
+ "stateOrProvinceName" => 'Hunan', // 所在省份名称
+ "localityName" => 'Changsha', // 所在城市名称
+ "organizationName" => 'opd', // 注册人姓名
+ "organizationalUnitName" => 'orico_opd', // 组织名称
+ "commonName" => 'orico_opd', // 公共名称
+ "emailAddress" => '735273025@qq.com' // 邮箱
+ );
+
+ $privkeypass = self::SIGN_CERT_PWD; //私钥密码
+ $config = array(
+ "config" => $this->openssl_cnf_path,
+ "digest_alg" => "sha1",
+ "private_key_bits" => 2048,
+ "private_key_type" => OPENSSL_KEYTYPE_DSA,
+ "encrypt_key" => false
+ );
+
+ $privkey = openssl_pkey_new($config);
+ $csr = openssl_csr_new($dn, $privkey, $config);
+ $sscert = openssl_csr_sign($csr, null, $privkey, 365, $config);
+ openssl_x509_export($sscert, $csrkey); // 导出证书$csrkey
+ openssl_pkcs12_export($sscert, $private_key, $privkey, $privkeypass); // 导出密钥$private_key
+
+ if (!$writeFile) {
+ return array('csrkey' => $csrkey, 'private_key_pfx' => $private_key);
+ }
+
+ $cerpath = $this->cert_save_path . "csrkey.cer"; // 生成证书路径
+ $pfxpath = $this->cert_save_path . "private_key.pfx"; // 密钥文件路径
+
+ // 生成证书文件
+ if (!is_writeable($cerpath)) {
+ chmod($cerpath, 0755);
+ }
+ $fp = fopen($cerpath, "w");
+ fwrite($fp, $csrkey);
+ fclose($fp);
+ // 生成密钥文件
+ if (!is_writeable($pfxpath)) {
+ chmod($pfxpath, 0755);
+ }
+ $fp = fopen($pfxpath, "w");
+ fwrite($fp, $private_key);
+ fclose($fp);
+ }
+}
diff --git a/extend/encryption/cert/csrkey.cer b/extend/encryption/cert/csrkey.cer
new file mode 100644
index 0000000..e69de29
diff --git a/extend/encryption/cert/private_key.pfx b/extend/encryption/cert/private_key.pfx
new file mode 100644
index 0000000..e69de29
diff --git a/extend/encryption/cert/rsa_private_key.pem b/extend/encryption/cert/rsa_private_key.pem
new file mode 100644
index 0000000..14e4cc6
--- /dev/null
+++ b/extend/encryption/cert/rsa_private_key.pem
@@ -0,0 +1,3 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCb4X1wN9ret271gWrsXlSymFinlheMUz2kIsyKREtlfE7ajH6Bm5bEFxe/HnCDxh37ekUJq4JMeU1awJgYA4mlvaQ67DSf4/AZWk2Dg8TLQaE7VeBJoPadDyciIwuFhcWB2lfD62KRlbXqgjfji7IjZE4ysVB99DofpJ9c9xd0NtzzuBNjgxh+f6BsegsIkqLIpKGIONePrY9cCj+vOMaRdUgWczQOftWXtJXiRz5kUxwV6CSQQbbPFEySStlW2WMBF15FyeOTXERvpgOoP4O+j/0GMW3R+4dKUxFY+SPrmMMB6HmJgySgCIVuwlUJyLlmhZuaIumryyJ19Yc+jB0ZAgMBAAECggEAA82hoN5MAckZ9PV+ZVv71wuuhhA8bNkPFPUgZnM6H7TDu8NXxtPD/u7NToVwm1Z3Hs6h5pV/rVv8Ti2KyHM1pYyV+DYRJqGKFyRD5eSOJaNpSqhSu5koyzY2bzfJrS1RX1SzdX1Fv2WWta0NrgiXhROKcOQwoZIW5PTASqVgth4iztEmseuU9pgh/dnMOXCLGmGB26Z2HTnuV0tHC4/goMmsi0eGOy40VEBxPL0JJegWM+teRSbSWGzOfTu95wnpIr66FT0aOVdHVuhMTYYHUfbEh/lnCZExfqjNfEVuSLB+jHBeLfFXdg3TY/svVizXJ4SvzI1EzM6Y145zMTdk8QKBgQDPKT1BQHWIPyXs3IzqDpmP9koBOm03rZZ46CneGLFj9vRAeK9awAto6aqH/WHLb48fSK5LQteWf+rvRiqoPjansoFvzh1dgk+0FON1jUNk4LlwOVEL38WhD98cJ/SwOVdwsYfYySb2pwcZ3K4gdTmax264XFRNGU8Ar4l17NHVtQKBgQDAoVcyWHtpJ6Pk4CuOSWt1S5y1km1dAudJfRAyYlk+9G6Qq1zSoScio/1T/TAS58KHcoSV0SmGu9heF2p02ov4MzsFr//cnBh2Y3aiTnvnyxehp5V0M9CLy524gHDANHO3BxCjlV6tMFqvUuhJfurN36KarYvLJjGU3MoWLPiIVQKBgQCfuWozP2HfdODm6X30kOExsHGK1OOUxFB6VHbDeUJ8ktHsS6DYVa32bANB6slWM2OkeUN5X8Ydke8wIWeOZLl7PxSxgbf+exS9AkYGQq6tvt77ehXVE+mqrzQU33G31d5nU1oseZuDHXFKLW5MNFX/0ri5iOaus07Ido+Dzt5S6QKBgQCef+MEnQOmyaQ0vjN4l3bhA79FM9/i6XGv6UT7gCsY/v0+8pGlCk7uVOssQadd1u8cjiEEOR+nKkdlXHUPA4iqSFUnX+Ly/kmumDbUZCnV1ylxrTfvbncJoBf96UldDYutLRYG0/AcJy5nFpvlZZYEoh/kkCn3lUy0xVtPFd/GJQKBgQCDfPkSHDxyeSZQ2xlj+4xqIGfGLbK/ijO9AuC7rSnWE2bYD1cseItVK6O0nZ0Gw4vmmvHDF9Z6yxCobIzyf6fUExvVRm3oMwjSrjVWfycTKaUUb7CHAU6JH8zQ1DPsTQ+F+W+q1RZZCj1qUBO9cHe9xIPWoK6PN829/UmZAzJeyg==
+-----END PRIVATE KEY-----
diff --git a/extend/encryption/cert/rsa_public_key.pem b/extend/encryption/cert/rsa_public_key.pem
new file mode 100644
index 0000000..8942179
--- /dev/null
+++ b/extend/encryption/cert/rsa_public_key.pem
@@ -0,0 +1,3 @@
+-----BEGIN PUBLIC KEY-----
+MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAm+F9cDfa3rdu9YFq7F5UsphYp5YXjFM9pCLMikRLZXxO2ox+gZuWxBcXvx5wg8Yd+3pFCauCTHlNWsCYGAOJpb2kOuw0n+PwGVpNg4PEy0GhO1XgSaD2nQ8nIiMLhYXFgdpXw+tikZW16oI344uyI2ROMrFQffQ6H6SfXPcXdDbc87gTY4MYfn+gbHoLCJKiyKShiDjXj62PXAo/rzjGkXVIFnM0Dn7Vl7SV4kc+ZFMcFegkkEG2zxRMkkrZVtljARdeRcnjk1xEb6YDqD+Dvo/9BjFt0fuHSlMRWPkj65jDAeh5iYMkoAiFbsJVCci5ZoWbmiLpq8sidfWHPowdGQIDAQAB
+-----END PUBLIC KEY-----
diff --git a/extend/sitemap/sitemap.config.php b/extend/sitemap/sitemap.config.php
new file mode 100644
index 0000000..fc07ce3
--- /dev/null
+++ b/extend/sitemap/sitemap.config.php
@@ -0,0 +1,89 @@
+
+';
+
+// Optionally configure debug options
+$debug = array(
+ "add" => true,
+ "reject" => false,
+ "warn" => false
+);
+
+
+//Modify only if configuration version is broken
+$version_config = 2;
diff --git a/extend/sitemap/sitemap.functions.php b/extend/sitemap/sitemap.functions.php
new file mode 100644
index 0000000..385c4c3
--- /dev/null
+++ b/extend/sitemap/sitemap.functions.php
@@ -0,0 +1,426 @@
+ https://somewebsite.com/directory/
+// https://somewebsite.com/directory/subdir/ => https://somewebsite.com/directory/subdir/
+function get_path($path)
+{
+ $path_depth = explode("/", $path);
+ $len = strlen($path_depth[count($path_depth) - 1]);
+ return (substr($path, 0, strlen($path) - $len));
+}
+
+//Get the root of the domain
+function domain_root($href)
+{
+ $url_parts = explode('/', $href);
+ return $url_parts[0] . '//' . $url_parts[2] . '/';
+}
+
+//The curl client is create outside of the function to avoid re-creating it for performance reasons
+$curl_client = curl_init();
+function get_data($url)
+{
+ global $curl_validate_certificate, $curl_client, $index_pdf, $crawler_user_agent, $enable_modified;
+
+ //Set URL
+ curl_setopt($curl_client, CURLOPT_URL, $url);
+ //Follow redirects and get new url
+ curl_setopt($curl_client, CURLOPT_RETURNTRANSFER, 1);
+ //Get headers
+ curl_setopt($curl_client, CURLOPT_HEADER, 1);
+ //Optionally avoid validating SSL
+ curl_setopt($curl_client, CURLOPT_SSL_VERIFYPEER, $curl_validate_certificate);
+ //Set user agent
+ curl_setopt($curl_client, CURLOPT_USERAGENT, $crawler_user_agent);
+
+ //Get data
+ $data = curl_exec($curl_client);
+ $content_type = curl_getinfo($curl_client, CURLINFO_CONTENT_TYPE);
+ $http_code = curl_getinfo($curl_client, CURLINFO_HTTP_CODE);
+ $redirect_url = curl_getinfo($curl_client, CURLINFO_REDIRECT_URL);
+
+ //Scan new url, if redirect
+ if ($redirect_url) {
+ logger("URL is a redirect.", 1);
+ if (strpos($redirect_url, '?') !== false) {
+ $redirect_url = explode($redirect_url, "?")[0];
+ }
+ unset($url, $data);
+
+ if (!check_blacklist($redirect_url)) {
+ echo logger("Redirected URL is in blacklist", 1);
+
+ } else {
+ scan_url($redirect_url);
+ }
+ }
+
+ //If content acceptable, return it. If not, `false`
+ $html = ($http_code != 200 || (!stripos($content_type, "html"))) ? false : $data;
+
+ //Additional data
+ if ($enable_modified){
+ curl_setopt($curl_client, CURLOPT_FILETIME, true);
+ $timestamp = curl_getinfo($curl_client, CURLINFO_FILETIME);
+ $modified = ($timestamp != -1) ? date('c', $timestamp) : null;
+ }
+ else $modified = null;
+
+ if (stripos($content_type, "application/pdf") !== false && $index_pdf) {
+ $html = "This is a PDF";
+ }
+ //Return it as an array
+ return array($html, $modified, (stripos($content_type, "image/") && $index_img));
+}
+
+//Try to match string against blacklist
+function check_blacklist($string)
+{
+ global $blacklist;
+ if (is_array($blacklist)) {
+ foreach ($blacklist as $illegal) {
+ if (fnmatch($illegal, $string)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+//Extract array of URLs from html document inside of `href`s
+function get_links($html, $parent_url, $regexp)
+{
+ if (preg_match_all("/$regexp/siU", $html, $matches)) {
+ if ($matches[2]) {
+ $found = array_map(function ($href) use (&$parent_url) {
+ global $real_site, $ignore_arguments;
+
+ logger("Checking $href", 2);
+
+ if (strpos($href, "#") !== false) {
+ logger("Dropping pound.", 2);
+ $href = preg_replace('/\#.*/', '', $href);
+ }
+
+ //Seperate $href from $query_string
+ $query_string = '';
+ if (strpos($href, '?') !== false) {
+ list($href, $query_string) = explode('?', $href);
+
+ //Parse & to not break curl client. See issue #23
+ $query_string = str_replace('&', '&', $query_string);
+ }
+ if ($ignore_arguments) {
+ $query_string = '';
+ }
+ if (strpos($href, '?') !== false) {
+ echo "EFEASDEFSED";
+ }
+
+ if ((substr($href, 0, 7) != "http://") && (substr($href, 0, 8) != "https://")) {
+ // Link does not call (potentially) external page
+ if (strpos($href, ":")) {
+ logger("URL is an invalid protocol", 1);
+ return false;
+ }
+ if ($href == '/') {
+ logger("$href is domain root", 2);
+ $href = $real_site;
+ } elseif (substr($href, 0, 1) == '/') {
+ logger("$href is relative to root, convert to absolute", 2);
+ $href = domain_root($real_site) . substr($href, 1);
+ } else {
+ logger("$href is relative, convert to absolute", 2);
+ $href = get_path($parent_url) . $href;
+ }
+ }
+ logger("Result: $href", 2);
+ if (!filter_var($href, FILTER_VALIDATE_URL)) {
+ logger("URL is not valid. Rejecting.", 1);
+ return false;
+ }
+ if (substr($href, 0, strlen($real_site)) != $real_site) {
+ logger("URL is not part of the target domain. Rejecting.", 1);
+ return false;
+ }
+ if (is_scanned($href . ($query_string ? '?' . $query_string : ''))) {
+ //logger("URL has already been scanned. Rejecting.", 1);
+ return false;
+ }
+ if (!check_blacklist($href)) {
+ logger("URL is blacklisted. Rejecting.", 1);
+ return false;
+ }
+ return flatten_url($href . ($query_string ? '?' . $query_string : ''));
+ }, $matches[2]);
+ return $found;
+ }
+ }
+ logger("Found nothing", 2);
+ return array();
+}
+
+function scan_url($url)
+{
+ global $scanned, $deferredLinks, $file_stream, $freq, $priority, $enable_priority, $enable_frequency, $max_depth, $depth, $real_site, $indexed;
+ $depth++;
+
+ logger("Scanning $url", 2);
+ if (is_scanned($url)) {
+ logger("URL has already been scanned. Rejecting.", 1);
+ return $depth--;
+ }
+ if (substr($url, 0, strlen($real_site)) != $real_site) {
+ logger("URL is not part of the target domain. Rejecting.", 1);
+ return $depth--;
+ }
+ if (!($depth <= $max_depth || $max_depth == 0)) {
+ logger("Maximum depth exceeded. Rejecting.", 1);
+ return $depth--;
+ }
+
+ //Note that URL has been scanned
+ $scanned[$url] = 1;
+
+ //Send cURL request
+ list($html, $modified, $is_image) = get_data($url);
+
+ if ($is_image) {
+ //Url is an image
+ }
+
+ if (!$html) {
+ logger("Invalid Document. Rejecting.", 1);
+ return $depth--;
+ }
+
+ if (strpos($url, "&") && strpos($url, ";") === false) {
+ $url = str_replace("&", "&", $url);
+ }
+
+ $map_row = "\n";
+ $map_row .= "$url \n";
+ if ($enable_frequency) {
+ $map_row .= "$freq \n";
+ }
+ if ($enable_priority) {
+ $map_row .= "$priority \n";
+ }
+ if ($modified) {
+ $map_row .= " $modified \n";
+ }
+ $map_row .= " \n";
+ fwrite($file_stream, $map_row);
+ $indexed++;
+ logger("Added: " . $url . (($modified) ? " [Modified: " . $modified . "]" : ''), 0);
+ unset($is_image, $map_row);
+
+ // Extract urls from
+ $ahrefs = get_links($html, $url, "]*href=(\"|'??)([^\" >]*?)\\1[^>]*>(.*)<\/a>");
+
+ // Extract urls from
+ $framesrc = get_links($html, $url, "]*src=(\"|'??)([^\" >]*?)\\1[^>]*>");
+
+ $links = array_filter(array_merge($ahrefs, $framesrc), function ($item) use (&$deferredLinks) {
+ return $item && !isset($deferredLinks[$item]);
+ });
+ unset($html, $url, $ahrefs, $framesrc);
+
+ logger("Found urls: " . join(", ", $links), 2);
+
+ //Note that URL has been deferred
+ foreach ($links as $href) {
+ if ($href) {
+ $deferredLinks[$href] = 1;
+ }
+ }
+
+ foreach ($links as $href) {
+ if ($href) {
+ scan_url($href);
+ }
+ }
+ $depth--;
+}
+
+// fnmatch() filler for non-POSIX systems
+
+if (!function_exists('fnmatch')) {
+ function fnmatch($pattern, $string)
+ {
+ return preg_match("#^" . strtr(preg_quote($pattern, '#'), array('\*' => '.*', '\?' => '.')) . "$#i", $string);
+ } // end
+} // end if
+
+$version_functions = 2;
diff --git a/extend/sitemap/sitemap.php b/extend/sitemap/sitemap.php
new file mode 100644
index 0000000..9b4a13f
--- /dev/null
+++ b/extend/sitemap/sitemap.php
@@ -0,0 +1,128 @@
+\n");
+fclose($file_stream);
+
+// Pretty-print sitemap
+ if ((PHP_OS == 'WINNT') ? `where xmllint` : `which xmllint`) {
+ logger("Found xmllint, pretty-printing sitemap", 0);
+ $responsevalue = exec('xmllint --format ' . $tempfile . ' -o ' . $tempfile . ' 2>&1', $discardedoutputvalue, $returnvalue);
+ if ($returnvalue) {
+ die("Error: " . $responsevalue . "\n");
+ }
+}
+
+// Generate and print out statistics
+$time_elapsed_secs = round(microtime(true) - $start, 2);
+logger("Sitemap has been generated in " . $time_elapsed_secs . " second" . (($time_elapsed_secs >= 1 ? 's' : '') . "and saved to $file"), 0);
+$size = sizeof($scanned);
+logger("Scanned a total of $size pages and indexed $indexed pages.", 0);
+
+// Rename partial file to the real file name. `rename()` overwrites any existing files
+rename($tempfile, $file);
+
+// Apply permissions
+chmod($file, $permissions);
+
+// Declare that the script has finished executing and exit
+logger("Operation Completed", 0);
diff --git a/extend/sso/SSOClient.php b/extend/sso/SSOClient.php
new file mode 100644
index 0000000..0c4719e
--- /dev/null
+++ b/extend/sso/SSOClient.php
@@ -0,0 +1,115 @@
+sso_url = config('sso.sso_url');
+// if (config('sso.app_id')) $this->app_id = config('sso.app_id');
+// if (config('sso.app_secret')) $this->app_secret = config('sso.app_secret');
+// if (config('sso.public_key')) $this->public_ssl_key = config('sso.public_key');
+// if (config('sso.private_key')) $this->private_ssl_key = config('sso.private_key');
+
+ $this->app_id = $data['app_id'];
+ $this->sso_url = $data['sso_url'];
+ $this->app_secret = $data['app_secret'];
+ $this->public_ssl_key = $data['public_key'];
+ $this->private_ssl_key = $data['private_key'];
+ }
+
+ /**
+ * 校验code,返回access_token
+ */
+ public function getAccessToken($code)
+ {
+ if (empty($code)) {
+ return Api::error('参数code不能为空', [], true);
+ }
+ $data = [
+ 'app_id' => $this->app_id,
+ 'app_secret' => $this->app_secret,
+ 'code' => $code
+ ];
+ return $this->http('authorize/access_token', $data, true, ['cookie'=>'PHPSESSID=' . Session::getId()]);
+ }
+
+ /**
+ * 刷新access_token
+ */
+ public function refreshToken($refresh_token, $sessid='')
+ {
+ if (empty($refresh_token)) {
+ return Api::error('参数refresh_token不能为空', [], true);
+ }
+ $data = [
+ 'app_id' => $this->app_id,
+ 'app_secret' => $this->app_secret,
+ 'refresh_token' => $refresh_token
+ ];
+ return $this->http('authorize/refresh_token', $data, true, ['cookie'=>'PHPSESSID=' . $sessid]);
+ }
+
+ /**
+ * 通知sso退出登录
+ */
+ public function notifySSOServerSigninOut($access_token, $sessid='')
+ {
+ if (empty($access_token)) {
+ return Api::error('参数access_token不能为空', [], true);
+ }
+ $data = [
+ 'app_id' => $this->app_id,
+ 'app_secret' => $this->app_secret,
+ 'access_token' => $access_token,
+ ];
+ if (empty($sessid)) {
+ $sessid = Session::getId();
+ }
+ return $this->http('authorize/signin_out', $data, true, ['cookie'=>'PHPSESSID=' . $sessid]);
+ }
+
+ /**
+ * 请求数据
+ */
+ private function http($url, $data, $is_post=false, $options=[])
+ {
+ $data = json_encode($data);
+ $headerArray = [
+ 'Content-type: application/json;charset=utf-8',
+ 'Accept: application/json'
+ ];
+ $url = $this->sso_url . $url;
+ $curl = curl_init();
+ curl_setopt($curl, CURLOPT_URL, $url);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
+ curl_setopt($curl, CURLOPT_SSL_VERIFYHOST,FALSE);
+ if ($is_post) {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
+ }
+ curl_setopt($curl,CURLOPT_HTTPHEADER,$headerArray);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
+ if (!empty($options['cookie'])) {
+ curl_setopt($curl, CURLOPT_COOKIE, $options['cookie']);
+ }
+ $output = curl_exec($curl);
+ $http_status = curl_errno($curl);
+ $http_msg = curl_error($curl);
+ curl_close($curl);
+ if ($http_status == 0) {
+ return json_decode($output, true);
+ } else {
+ return ['errno' => $http_status, 'errmsg' => $http_msg, 'data' => []];
+ }
+ }
+}
\ No newline at end of file
diff --git a/extend/storage/LocalUploader.php b/extend/storage/LocalUploader.php
new file mode 100644
index 0000000..4af4752
--- /dev/null
+++ b/extend/storage/LocalUploader.php
@@ -0,0 +1,204 @@
+config = [
+ 'disks' => [
+ 'local' => [
+ 'driver' => LocalDriver::class, //上传类
+ 'save_dir' => app()->getRootPath() . 'public/attachment', //上传保存路径
+ 'file_path' => '/attachment', //上传保存路径
+ 'tmp_dir' => root_path('runtime' . DIRECTORY_SEPARATOR . 'uploadtmp'),//临时目录
+ 'slice_first' => 0, //从第几片开始
+ ],
+ //继续添加其它仓库
+ ],
+ 'default' => [
+ 'disk' => 'local', //默认磁盘
+ 'extensions' => 'jpg,png,mp4', //后缀
+ 'mimeTypes' => 'image/*,video/*', //类型
+ 'middlewares' => [], //中间件数组
+ 'maxSize' => 1 * 1024 * 1024, //单包最大上传大小 2M
+ ]
+ ];
+
+ }
+
+
+ /**文件上传
+ * @param $data
+ * @param $file
+ * @return array
+ */
+ public function uploadFile($data, $file)
+ {
+
+ if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
+ exit; // finish preflight CORS requests here
+ }
+
+ try {
+ //处理部分数据
+ $data['size'] = $file->getSize();
+ $data['name'] = $file->getOriginalName();
+ $data['ext'] = $file->extension();
+ //检测文件大小
+ if (!$this->checkSize($data['size'])) {
+ $this->_error = "超出文件上传大小限制";
+ return ['code' => -1, 'data' => []];
+ }
+ $config = $this->config;
+ $uploadManager = new UploadManager($config);
+ $fileInfo = new FileInfo();
+ $fileInfo->identifier = $data['hash'];
+ $fileInfo->filename = $data['name'];
+
+ $fileInfo->chunkNumber = $data['chunk'] ?? 0;;
+ $fileInfo->chunkNumber = intval($fileInfo->chunkNumber ?? 0);
+
+ //未设置分片数量 则默认总数为1 当前为0
+ $fileInfo->totalChunks = $data['chunks'] ?? 1;
+ $fileInfo->totalChunks = intval($fileInfo->totalChunks ?? 1);
+ $fileInfo->totalChunks = ($fileInfo->totalChunks > 0) ? $fileInfo->totalChunks : 1;
+ $fileInfo->totalSize = $data['size'];
+ //获取后缀
+
+ $fileInfo->ext = $data['ext'];
+ if (!$this->checkFileType($fileInfo->ext)) {
+ $this->_error = "禁止上传的文件类型";
+ return ['code' => -1, 'data' => []];
+ }
+
+ $upload = $uploadManager->uploadFile($fileInfo);
+ //如果文件较小 直接上传完成
+ if (isset($upload['savepath']) && $upload['code'] == 0) {
+ $upload = $this->buildFileUrl($upload);
+ return ['code' => 1, 'data' => $upload, 'msg' => '成功'];
+ }
+ $check = $uploadManager->checkFile($fileInfo);
+ //如果上传完成
+ if (isset($check['savepath']) && $check['code'] == 0) {
+ $check = $this->buildFileUrl($check);
+ return ['code' => 1, 'data' => $check];
+ } else {
+ $this->_error = "文件包不完整";
+ return ['code' => 0, 'data' => $check];
+ }
+ } catch (\Exception $e) {
+ $this->_error = $e->getMessage();
+ return ['code' => -1, 'data' => $e->getMessage()];
+ }
+ }
+
+
+ /**
+ * 处理文件
+ * 扩展包存在问题 ,考虑后续更新 尽量不更改扩展包,在这里做文件的处理
+ */
+ public function buildFileUrl($data)
+ {
+
+ if (isset($data['savepath']) && $data['savepath'] != '') {
+
+ $conf = $this->config;
+ //获取除域名外的文件路径
+ $save_dir = $conf['disks'][$conf['default']['disk']]['save_dir'];
+ $file_path = str_replace($save_dir, '', $data['savepath']);
+ //拼接域名
+ $data['save_path'] = $conf['disks'][$conf['default']['disk']]['file_path'] . $file_path;
+ $data['file_path'] = $this->domain . $data['save_path'];
+ //删除多余的信息
+ unset($data['savepath']);
+ unset($data['code']);
+ }
+ return $data;
+ }
+
+ //检测文件上传大小
+ public function checkSize($file_size)
+ {
+
+ if ($file_size > $this->config['default']['maxSize']) {
+ return false;
+ }
+ return true;
+ }
+
+
+ /**检测文件类型
+ * @param $file_ext
+ * @return array|bool
+ */
+ public function checkFileType($file_ext)
+ { //获取配置信息
+ $extensions = $this->config['default']['extensions'];
+
+ //为空或者为 * 表示不过滤
+ if ($extensions == "" || $extensions == '*') {
+ return true;
+ }
+ //字符转换成数组
+ $exts = explode(',', $extensions);
+ if (in_array($file_ext, $exts)) {
+ $this->_error = "禁止上传该类型文件";
+ return ['code' => 0, 'data' => ''];
+ }
+ return true;
+ }
+
+
+ /**
+ * 检测文件分片情况
+ */
+ public function checkFile($hash,$count){
+
+ $filePath = $this->config['disks'][$this->config['default']['disk']]['tmp_dir'] . $hash; //临时分片文件路径
+
+// dump($filePath);
+ //检查分片是否存在
+ $chunkExists = [];
+ for ($index = 0; $index < $count; $index++) {
+ if (file_exists("{$filePath}_{$index}")) {
+ array_push($chunkExists, $index);
+ }
+ }
+ //分片有缺失,返回已存在的分片
+ $res['uploaded'] = $chunkExists;
+ return $res;
+ }
+
+
+ /**
+ * 删除文件
+ * @param $path
+ */
+ public function deleteFile($path){
+ $path = app()->getRootPath() . 'public'.$path;
+ if (file_exists($path)){
+ @unlink($path);
+ }
+ return true;
+ }
+
+ /**
+ * 返回报错
+ * @return string
+ */
+ public function getError()
+ {
+ return $this->_error;
+ }
+
+}
diff --git a/extend/storage/QiniuUploader.php b/extend/storage/QiniuUploader.php
new file mode 100644
index 0000000..9409d02
--- /dev/null
+++ b/extend/storage/QiniuUploader.php
@@ -0,0 +1,160 @@
+ 1024 * 1024 * 5, // 默认最大上传5M
+ 'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
+ 'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
+ ];
+
+ private $dir = true;
+ private $originalName = false;
+ private $pathPrefix = '';
+ private $fileNamePrefix = 'orico';
+
+ static public $domain = 'http://opdfile.f2b211.com/';
+
+ public function __construct($conf = [])
+ {
+ if (!empty($conf['bucket'])) {
+ $this->bucket = $conf['bucket'];
+ }
+ if (!empty($conf['accessKey'])) {
+ $this->accessKey = $conf['accessKey'];
+ }
+ if (!empty($conf['secretKey'])) {
+ $this->secretKey = $conf['secretKey'];
+ }
+ if (!empty($conf['pathPrefix'])) {
+ $this->pathPrefix = trim($conf['pathPrefix'], '/');
+ }
+ }
+
+ /**
+ * 生成随机字符串
+ */
+ private function random($length, $type = "string", $convert = "0")
+ {
+ $conf = [
+ 'number' => '0123456789',
+ 'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
+ ];
+ $string = $conf[$type];
+ if (!$string) {
+ $string = $conf['string'];
+ }
+ $strlen = strlen($string) - 1;
+ $char = '';
+ for ($i = 0; $i < $length; $i++) {
+ $char .= $string[mt_rand(0, $strlen)];
+ }
+ if ($convert > 0) {
+ $res = strtoupper($char);
+ } elseif ($convert == 0) {
+ $res = $char;
+ } elseif ($convert < 0) {
+ $res = strtolower($char);
+ }
+ return $res;
+ }
+
+ /**
+ * 组装文件名
+ */
+ private function buildFileName()
+ {
+ return $this->fileNamePrefix . time() . substr(time(), -5) . substr(microtime(), 2, 3) . $this->random(8);
+ }
+
+ /**
+ * 上传验证规则
+ */
+ public function validate($rule)
+ {
+ $this->rule = $rule;
+ }
+
+ /**
+ * 上传文件到七牛云
+ */
+ public function uploadFile($name)
+ {
+ // 构建鉴权对象
+ $auth = new Auth($this->accessKey, $this->secretKey);
+
+ // 生成上传 Token
+ $token = $auth->uploadToken($this->bucket);
+
+ // 初始化 UploadManager 对象并进行文件的上传。
+ $uploadMgr = new UploadManager();
+
+ $file = request()->file($name);
+
+ $aspectRatio = [];
+ if (!empty($this->rule['aspectRatio'])) {
+ $aspectRatio = $this->rule['aspectRatio'];
+ unset($this->rule['aspectRatio']);
+ }
+ $validate = validate([$name => $this->rule]);
+ if (!$validate->check([$name => $file])) {
+ throw new \Exception($validate->getError());
+ }
+
+ $fileName = $file->getOriginalName(); // 文件原名
+ if (!$this->originalName) {
+ $fileName = $this->buildFileName() . '.' . $file->extension();
+ if (!$this->dir && !empty($this->pathPrefix)) {
+ $fileName = $this->pathPrefix . '/' . $fileName;
+ }
+ }
+ if ($this->dir) {
+ $fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
+ if (!empty($this->pathPrefix)) {
+ $fileName = $this->pathPrefix . '/' . $fileName;
+ }
+ }
+ $filePath = $file->getPathname(); // 临时路径
+ if (!empty($aspectRatio)) { // 验证图片宽高
+ list($width, $height, $type, $attr) = getimagesize($file);
+ if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
+ throw new \Exception('图片宽高不符合');
+ }
+ }
+ $fileType = $file->getOriginalMime();
+ list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
+
+ if ($err !== null) {
+ throw new \Exception($err);
+ } else {
+ return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => self::$domain . $ret['key']];
+ }
+ }
+
+
+ /**
+ * 上传文件到七牛云
+ */
+ public function deleteFile($name)
+ {
+ // 构建鉴权对象
+ $auth = new Auth($this->accessKey, $this->secretKey);
+ // 初始化 BucketManager 对象并进行文件的删除。
+ $bucketManager = new BucketManager($auth);
+ $ret = $bucketManager->delete($this->bucket, $name);
+ return $ret;
+ }
+
+
+}
diff --git a/extend/utils/BusinessDaysCalculator.php b/extend/utils/BusinessDaysCalculator.php
new file mode 100644
index 0000000..05669de
--- /dev/null
+++ b/extend/utils/BusinessDaysCalculator.php
@@ -0,0 +1,78 @@
+date = $startDate;
+ $this->holidays=[];
+ foreach($holidays as $holiday){
+ array_push($this->holidays,new DateTime($holiday));
+ }
+ $this->nonBusinessDays = $nonBusinessDays;
+ $this->specialBusinessDay = $specialBusinessDay;
+ }
+
+ /**
+ * 指几个工作日后
+ */
+ public function addBusinessDays($howManyDays) {
+ $i = 0;
+ while ($i < $howManyDays) {
+ $this->date->modify("+1 day");
+ if ($this->isBusinessDay($this->date)) {
+ $i++;
+ }
+ }
+ }
+
+ public function getDate() {
+ return $this->date->format('Y-m-d');
+ }
+
+ private function isBusinessDay(DateTime $date) {
+ if(in_array($date->format('Y-m-d') , $this->specialBusinessDay)) return true; // 判断当前日期是否是因法定节假日调休而上班的周末,这种情况也算工作日
+
+ if (in_array((int)$date->format('N'), $this->nonBusinessDays)) {
+ return false; // 当前日期是周末
+ }
+
+ foreach ($this->holidays as $day) {
+ if ($date->format('Y-m-d') == $day->format('Y-m-d')) {
+ return false; // 当前日期是法定节假日
+ }
+ }
+
+ return true;
+ }
+
+}
+
+$holidays=["2017-01-27","2017-01-28","2017-01-29","2017-01-30","2017-01-31","2017-02-01","2017-02-02"]; // 从聚合数据接口获得
+$specialBusinessDay=["2017-01-22"]; // 因法定节假日调休而上班的周末,这种情况也算工作日.因为这种情况少,可以通过手动配置
+$calculator = new BusinessDaysCalculator(
+ new DateTime(), // 当前时间
+ $holidays,
+ [BusinessDaysCalculator::SATURDAY, BusinessDaysCalculator::SUNDAY],
+ $specialBusinessDay
+);
+
+$calculator->addBusinessDays(2); // 2个工作日后的时间
+
+$afterBusinessDay=$calculator->getDate();
+echo $afterBusinessDay;
\ No newline at end of file
diff --git a/extend/utils/FileLog.php b/extend/utils/FileLog.php
new file mode 100644
index 0000000..45272ff
--- /dev/null
+++ b/extend/utils/FileLog.php
@@ -0,0 +1,48 @@
+time = date('Y-m-d H:i:s');
+ $this->filepath = $filepath;
+ $this->filename = $filename;
+ $this->init();
+ }
+
+ public function init()
+ {
+ if (!is_dir($this->filepath))
+ {
+ mkdir($this->filepath, 0777, true);
+ }
+ }
+
+ public function write($content, $type='err')
+ {
+ $str = $type . '=====';
+ $str .= '当前时间为: ' . $this->time;
+ $str .= '=====';
+ $str .= $content . PHP_EOL;
+
+ if (substr($this->filepath, -1) == '/')
+ {
+ $file = $this->filepath . $this->filename;
+ }
+ else
+ {
+ $file = $this->filepath . '/' . $this->filename;
+ }
+
+ return file_put_contents($file, $str, FILE_APPEND);
+ }
+
+}
\ No newline at end of file
diff --git a/extend/utils/Jwt.php b/extend/utils/Jwt.php
new file mode 100644
index 0000000..a2d15e5
--- /dev/null
+++ b/extend/utils/Jwt.php
@@ -0,0 +1,168 @@
+config = $config;
+ $this->init();
+ }
+
+ private function init()
+ {
+ $this->iss = $this->config['iss'];
+ $this->exp = $this->config['exp'];
+ $this->iat = time();
+ }
+
+ /**
+ * 获取token
+ * @param array $user_info
+ * @return string
+ */
+ public function getToken(array $user_info):string
+ {
+ //头信息
+ $header = [
+ 'typ' => $this->typ,
+ 'alg' => $this->alg
+ ];
+ $base64_header = base64_encode(json_encode($header));
+
+ //有效载荷
+ $payload = [
+ 'iss' => $this->iss,
+ 'exp' => $this->exp,
+ 'iat' => $this->iat,
+ 'user_info' => $user_info,
+ ];
+ $base64_payload = base64_encode(json_encode($payload));
+
+ //签名信息
+ $this->secret = $this->getSecret($user_info);
+ $signature = $base64_header . $base64_payload . $this->secret;
+ $base64_signature = $this->enc($this->alg, $signature);
+
+ $jwt_token = $base64_header . '.' . $base64_payload . '.' . $base64_signature;
+ return $jwt_token;
+ }
+
+ /**
+ * 校验token
+ * @param $jwt_token
+ * @return int
+ */
+ public function checkToken($jwt_token)
+ {
+ $arr = explode('.', $jwt_token);
+ if (count($arr) < 3) {
+ return -1;
+ }
+
+ $base64_header = $arr[0];
+ $base64_payload = $arr[1];
+ $base64_signature = $arr[2];
+
+ $payload = json_decode(base64_decode($base64_payload), true);
+ if (!is_array($payload) || !isset($payload['exp']) || !isset($payload['iat']) || !isset($payload['user_info'])) {
+ return -2;
+ }
+
+ //生成签名,比较
+ $this->secret = $this->getSecret($payload['user_info']);
+ $tmp_signature = $base64_header . $base64_payload . $this->secret;
+ $tmp_base64_signature = $this->enc($this->alg, $tmp_signature);
+
+ if ($base64_signature !== $tmp_base64_signature) {
+ return -3;
+ }
+
+ // 是否过期
+ if ($payload['exp'] + $payload['iat'] - time() < 0) {
+ // token过期了
+ return -4;
+ } else {
+ // token没有过期
+ if ($payload['exp'] + $payload['iat'] - time() - $this->timeout < 0) {
+ return 201;
+ }
+
+ return 200;
+ }
+ }
+
+ /**
+ * 获取用户信息
+ * @param $jwt_token
+ * @return array|mixed
+ */
+ public function getUserInfo($jwt_token)
+ {
+ $arr = explode('.', $jwt_token);
+ if (count($arr) < 3) {
+ return [];
+ }
+
+ $base64_payload = $arr[1];
+
+ $payload = json_decode(base64_decode($base64_payload), true);
+ if (!is_array($payload) || !isset($payload['user_info'])) {
+ return [];
+ }
+
+ return $payload['user_info'];
+ }
+
+
+ /**
+ * 获取secret,保证每个用户的secret都不同
+ * @param $user_info
+ * @return string
+ */
+ private function getSecret($user_info)
+ {
+ return md5($this->key . json_encode($user_info));
+ }
+
+ /**
+ * 加密
+ * @param $enc_type
+ * @param $content
+ * @return string
+ */
+ private function enc($enc_type, $content)
+ {
+ if ($enc_type == 'HS256')
+ {
+ return hash('sha256', $content);
+ }
+ }
+
+}
diff --git a/extend/utils/Mailer.php b/extend/utils/Mailer.php
new file mode 100644
index 0000000..15c3fdd
--- /dev/null
+++ b/extend/utils/Mailer.php
@@ -0,0 +1,87 @@
+subject = $subject;
+ return $this;
+ }
+
+ /**
+ * 设置内容
+ * @param string $body
+ */
+ public function setBody($body)
+ {
+ $this->body = $body;
+ return $this;
+ }
+
+ /**
+ * 设置不支持html时的内容
+ * @param string $string 内容
+ */
+ public function setAltBody($string)
+ {
+ $this->altBody = $string;
+ return $this;
+ }
+
+ /**
+ * 发送
+ */
+ public function send()
+ {
+ $success = false;
+ $mail = new PHPMailer(true);
+ try {
+ $mail->CharSet = self::CHARTSET; //设定邮件编码
+ $mail->SMTPDebug = 0; // 调试模式输出
+ $mail->isSMTP(); // 使用SMTP
+ $mail->Host = self::HOST; // SMTP服务器
+ $mail->SMTPAuth = true; // 允许 SMTP 认证
+ $mail->Username = $this->username; // SMTP 用户名 即邮箱的用户名
+ $mail->Password = $this->password; // SMTP 密码 部分邮箱是授权码(例如163邮箱)
+ $mail->SMTPSecure = 'ssl'; // 允许 TLS 或者ssl协议
+ $mail->Port = 465; // 服务器端口 25 或者 465 具体要看邮箱服务器支持
+
+ $mail->setFrom($this->fromAccount, $this->fromName); //发件人
+ $mail->addAddress($this->toAccount, $this->toName); // 收件人
+ $mail->isHTML(true);
+ $mail->Subject = $this->subject;
+ $mail->Body = $this->body;
+ $mail->AltBody = $this->altBody;
+
+ $success = $mail->send();
+ } catch (\Exception $error) {
+ exit($mail->ErrorInfo);
+ }
+ return $success;
+ }
+}
\ No newline at end of file
diff --git a/extend/utils/OrederStatusSync4Redis.php b/extend/utils/OrederStatusSync4Redis.php
new file mode 100644
index 0000000..e09b22d
--- /dev/null
+++ b/extend/utils/OrederStatusSync4Redis.php
@@ -0,0 +1,148 @@
+key = Config::get('redis.erp.order_sync_stream.key');
+ if (empty($this->key)) {
+ throw new \Exception('未配置默认STREAM标识key');
+ }
+ $this->group = Config::get('redis.erp.order_sync_stream.group');
+ if (empty($this->group)) {
+ throw new \Exception('未配置默认STREAM消费者组');
+ }
+ $this->consumer = Config::get('redis.erp.order_sync_stream.consumer');
+ if (empty($this->consumer)) {
+ throw new \Exception('未配置默认STREAM消费者');
+ }
+ if (empty($config)) {
+ $config = Config::get('redis.erp.conf');
+ }
+ $this->client = new Redis($config);
+ }
+
+ /**
+ * @param string $key 设置stream标识key
+ */
+ public function streamKey($key)
+ {
+ if (empty($key)) {
+ return false;
+ }
+ $this->key = $key;
+ }
+
+ /**
+ * @param string $group 设置消费者组
+ */
+ public function streamGroup($group)
+ {
+ if (empty($group)) {
+ return false;
+ }
+ $this->group = $group;
+ }
+
+ /**
+ * @param string $consumer 设置消费者
+ */
+ public function streamConsumer($consumer)
+ {
+ if (empty($consumer)) {
+ return false;
+ }
+ $this->consumer = $consumer;
+ }
+
+ /**
+ * 检查是否存在消息组
+ * @param string $streamGroup 消费者组
+ * @return bool
+ */
+ public function hasGroup($streamGroup='')
+ {
+ $groups = $this->client->xInfo('GROUPS', $this->key);
+ if (empty($groups)) {
+ return false;
+ }
+ if (empty($streamGroup)) {
+ $streamGroup = $this->group; // 使用配置的消费组
+ }
+ if (!in_array($streamGroup, array_column($groups, 'name'))) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * 创建消息组
+ * @param string $streamGroup 消费者组
+ * @param string $msgID 0为查看所有消息,$为查看最新消息
+ */
+ public function createGroup($streamGroup='', $msgID='0')
+ {
+ if (empty($streamGroup)) {
+ $streamGroup = $this->group; // 使用配置的消费组
+ }
+ $this->client->xGroup('CREATE', $this->key, $streamGroup, $msgID);
+ }
+
+ /**
+ * 获取新消息
+ * @param int $count 获取条数
+ * @param int $block 是否阻塞:0为永久阻塞,null为不阻塞,1000为阻塞1秒
+ * @return array
+ */
+ public function fetchMessage($count=null, $block=null)
+ {
+ $keys[$this->key] = '>'; // 获取新消息
+ $messages = $this->client->xReadGroup($this->group, $this->consumer, $keys, $count, $block);
+ return !empty($messages) ? $messages[$this->key] : [];
+ }
+
+ /**
+ * 获取未处理消费
+ * @param int $count 获取条数
+ * @param int $block 是否阻塞:0为永久阻塞,null为不阻塞,1000为阻塞1秒
+ * @return array
+ */
+ public function fetchMessage4UnAck($count=null, $block=null)
+ {
+ $keys[$this->key] = '0'; // 获取未处理的
+ $messages = $this->client->xReadGroup($this->group, $this->consumer, $keys, $count, $block);
+ return !empty($messages) ? $messages[$this->key] : [];
+ }
+
+ /**
+ * 获取处理PENDING中消息
+ * @param int $count 获取条数
+ * @return array
+ */
+ public function fetchMessage4Pending($count = 10)
+ {
+ $messages = $this->client->xPending($this->key, $this->group, '-', '+', $count, $this->consumer);
+ return !empty($messages) ? $messages : [];
+ }
+
+ /**
+ * 根据消息ID设为消息已处理
+ * @param array|string 消息ID
+ * @param int 处理系数
+ */
+ public function ack($messagesID)
+ {
+ if (!is_array($messagesID)) {
+ $messagesID = [$messagesID];
+ }
+ return $this->client->xAck($this->key, $this->group, $messagesID);
+ }
+}
\ No newline at end of file
diff --git a/extend/utils/QiniuUploader.php b/extend/utils/QiniuUploader.php
new file mode 100644
index 0000000..b4aa363
--- /dev/null
+++ b/extend/utils/QiniuUploader.php
@@ -0,0 +1,200 @@
+ 1024 * 1024 * 5, // 默认最大上传5M
+ 'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
+ 'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
+ ];
+
+ protected $dir = true;
+ protected $originalName = false;
+ protected $pathPrefix = '';
+ protected $fileNamePrefix = 'cms_';
+
+ protected $domain = '';
+
+ public function __construct($conf = [])
+ {
+ $this->domain = Env::get("QINIU.cdn");
+ if (!empty($conf['bucket'])) {
+ $this->bucket = $conf['bucket'];
+ }
+ if (!empty($conf['accessKey'])) {
+ $this->accessKey = $conf['accessKey'];
+ }
+ if (!empty($conf['secretKey'])) {
+ $this->secretKey = $conf['secretKey'];
+ }
+ if (!empty($conf['pathPrefix'])) {
+ $this->pathPrefix = trim($conf['pathPrefix'], '/');
+ }
+ }
+
+ /**
+ * 生成随机字符串
+ */
+ private function random($length, $type="string", $convert="0")
+ {
+ $conf = [
+ 'number' => '0123456789',
+ 'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
+ 'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
+ ];
+ $string = $conf[$type];
+ if(!$string) {
+ $string = $conf['string'];
+ }
+ $strlen = strlen($string) - 1;
+ $char = '';
+ for($i=0; $i<$length; $i++) {
+ $char .= $string[mt_rand(0, $strlen)];
+ }
+ if($convert > 0) {
+ $res = strtoupper($char);
+ } elseif ($convert == 0) {
+ $res = $char;
+ } elseif ($convert < 0) {
+ $res = strtolower($char);
+ }
+ return $res;
+ }
+
+ /**
+ * 组装文件名
+ */
+ private function buildFileName()
+ {
+ return $this->fileNamePrefix . time().substr(time(),-5).substr(microtime(),2,3) . $this->random(8);
+ }
+
+ /**
+ * 上传验证规则
+ */
+ public function validate($rule)
+ {
+ $this->rule = $rule;
+ }
+
+ /**
+ * 上传文件到七牛云
+ * @param $name
+ * @param bool $multi 多文件模式
+ * @param int $num 多文件模式文件数量
+ * @return array
+ * @throws \Exception
+ */
+ public function uploadFile($name,$multi=false,$num = 1)
+ {
+ // 构建鉴权对象
+ $auth = new Auth($this->accessKey, $this->secretKey);
+
+ // 生成上传 Token
+ $token = $auth->uploadToken($this->bucket);
+
+ // 初始化 UploadManager 对象并进行文件的上传。
+ $uploadMgr = new UploadManager();
+
+ $data = [];
+ if (false === $multi) {
+ $file = request()->file($name);
+ $data = $this->doFileToQn($file, $uploadMgr, $token);
+ } else {
+ for ($i = 0; $i < $num; $i++) {
+ $file = request()->file($name)[$i];
+ $data[] = $this->doFileToQn($file, $uploadMgr, $token);
+ }
+ }
+ return $data;
+
+
+ }
+
+
+ /**
+ * 七牛云上传本地文件,并且本地相对路由和七牛云路径完全一致
+ * @param string $fullName 文件名称带全路径。/www/wwwroot/test.yulinzhihou.com/public/ueditor/php/upload/file/20210424/1619232876970230.png
+ * @param string $relativePath 相对路径,注意:前面不能以斜杠开头 如:ueditor/php/upload/file/20210424/1619232876970230.png
+ * @return array
+ * @throws \Exception
+ */
+ public function uploadLocalFile($fullName,$relativePath)
+ {
+ // 构建鉴权对象
+ $auth = new Auth($this->accessKey, $this->secretKey);
+ // 生成上传 Token
+ $token = $auth->uploadToken($this->bucket);
+ // 初始化 UploadManager 对象并进行文件的上传。
+ $uploadMgr = new UploadManager();
+ $file = ltrim($relativePath,'\/');
+ list($ret, $err) = $uploadMgr->putFile($token,$file,$fullName);
+ if ($err !== null) {
+ throw new \Exception($err);
+ } else {
+ return ['hash'=>$ret['hash'], 'filename'=>$ret['key'], 'remote_url'=>$this->domain . $ret['key']];
+ }
+
+ }
+
+ /**
+ * @param $file
+ * @param UploadManager $uploadMgr
+ * @param string $token
+ * @return array
+ * @throws \Exception
+ */
+ private function doFileToQn($file, UploadManager $uploadMgr, string $token): array
+ {
+ $aspectRatio = [];
+ if (!empty($this->rule['aspectRatio'])) {
+ $aspectRatio = $this->rule['aspectRatio'];
+ unset($this->rule['aspectRatio']);
+ }
+
+ $fileName = $file->getOriginalName(); // 文件原名
+
+ if (!$this->originalName) {
+ $fileName = $this->buildFileName() . '.' . $file->extension();
+ if (!$this->dir && !empty($this->pathPrefix)) {
+ $fileName = $this->pathPrefix . '/' . $fileName;
+ }
+ }
+
+ if ($this->dir) {
+ $fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
+ if (!empty($this->pathPrefix)) {
+ $fileName = $this->pathPrefix . '/' . $fileName;
+ }
+ }
+
+ $filePath = $file->getPathname(); // 临时路径
+ if (!empty($aspectRatio)) { // 验证图片宽高
+ list($width, $height, $type, $attr) = getimagesize($file);
+ if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
+ throw new \Exception('图片宽高不符合');
+ }
+ }
+ $fileType = $file->getOriginalMime();
+ list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
+ if ($err !== null) {
+ throw new \Exception($err);
+ } else {
+ return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => $this->domain . $ret['key']];
+ }
+ }
+}
\ No newline at end of file
diff --git a/extend/utils/UEUploader.php b/extend/utils/UEUploader.php
new file mode 100644
index 0000000..08ef9ab
--- /dev/null
+++ b/extend/utils/UEUploader.php
@@ -0,0 +1,371 @@
+ "临时文件错误",
+ "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
+ "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
+ "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
+ "ERROR_CREATE_DIR" => "目录创建失败",
+ "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
+ "ERROR_FILE_MOVE" => "文件保存时出错",
+ "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
+ "ERROR_WRITE_CONTENT" => "写入文件内容错误",
+ "ERROR_UNKNOWN" => "未知错误",
+ "ERROR_DEAD_LINK" => "链接不可用",
+ "ERROR_HTTP_LINK" => "链接不是http链接",
+ "ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确",
+ "INVALID_URL" => "非法 URL",
+ "INVALID_IP" => "非法 IP"
+ );
+
+ /**
+ * 构造函数
+ * @param string $fileField 表单名称
+ * @param array $config 配置项
+ * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
+ */
+ public function __construct($fileField, $config, $type = "upload")
+ {
+ $this->fileField = $fileField;
+ $this->config = $config;
+ $this->type = $type;
+ if ($type == "remote") {
+ $this->saveRemote();
+ } else if($type == "base64") {
+ $this->upBase64();
+ } else {
+ $this->upFile();
+ }
+ }
+
+ /**
+ * 上传文件的主处理方法
+ * @return mixed
+ */
+ private function upFile()
+ {
+ $file = $this->file = $_FILES[$this->fileField];
+ if (!$file) {
+ $this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
+ return;
+ }
+ if ($this->file['error']) {
+ $this->stateInfo = $this->getStateInfo($file['error']);
+ return;
+ } else if (!file_exists($file['tmp_name'])) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
+ return;
+ } else if (!is_uploaded_file($file['tmp_name'])) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
+ return;
+ }
+
+ $this->oriName = $file['name'];
+ $this->fileSize = $file['size'];
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //检查是否不允许的文件格式
+ if (!$this->checkType()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) {
+ //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");
+ } else {
+ //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+ }
+
+ /**
+ * 处理base64编码的图片上传
+ * @return mixed
+ */
+ private function upBase64()
+ {
+ $base64Data = $_POST[$this->fileField];
+ $img = base64_decode($base64Data);
+
+ $this->oriName = $this->config['oriName'];
+ $this->fileSize = strlen($img);
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
+ } else { //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+
+ }
+
+ /**
+ * 拉取远程图片
+ * @return mixed
+ */
+ private function saveRemote()
+ {
+ $imgUrl = htmlspecialchars($this->fileField);
+ $imgUrl = str_replace("&", "&", $imgUrl);
+
+ //http开头验证
+ if (strpos($imgUrl, "http") !== 0) {
+ $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
+ return;
+ }
+
+ preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
+ $host_with_protocol = count($matches) > 1 ? $matches[1] : '';
+
+ // 判断是否是合法 url
+ if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
+ $this->stateInfo = $this->getStateInfo("INVALID_URL");
+ return;
+ }
+
+ preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
+ $host_without_protocol = count($matches) > 1 ? $matches[1] : '';
+
+ // 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
+ $ip = gethostbyname($host_without_protocol);
+ // 判断是否是私有 ip
+ if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
+ $this->stateInfo = $this->getStateInfo("INVALID_IP");
+ return;
+ }
+
+ //获取请求头并检测死链
+ $heads = get_headers($imgUrl, 1);
+ if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
+ return;
+ }
+ //格式验证(扩展名验证和Content-Type验证)
+ $fileType = strtolower(strrchr($imgUrl, '.'));
+ if (!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")) {
+ $this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
+ return;
+ }
+
+ //打开输出缓冲区并获取远程图片
+ ob_start();
+ $context = stream_context_create(
+ array('http' => array(
+ 'follow_location' => false // don't follow redirects
+ ))
+ );
+ readfile($imgUrl, false, $context);
+ $img = ob_get_contents();
+ ob_end_clean();
+ preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
+
+ $this->oriName = $m ? $m[1]:"";
+ $this->fileSize = strlen($img);
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
+ } else { //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+
+ }
+
+ /**
+ * 上传错误检查
+ * @param $errCode
+ * @return string
+ */
+ private function getStateInfo($errCode)
+ {
+ return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
+ }
+
+ /**
+ * 获取文件扩展名
+ * @return string
+ */
+ private function getFileExt()
+ {
+ return strtolower(strrchr($this->oriName, '.'));
+ }
+
+ /**
+ * 重命名文件
+ * @return string
+ */
+ private function getFullName()
+ {
+ //替换日期事件
+ $t = time();
+ $d = explode('-', date("Y-y-m-d-H-i-s"));
+ $format = $this->config["pathFormat"];
+ $format = str_replace("{yyyy}", $d[0], $format);
+ $format = str_replace("{yy}", $d[1], $format);
+ $format = str_replace("{mm}", $d[2], $format);
+ $format = str_replace("{dd}", $d[3], $format);
+ $format = str_replace("{hh}", $d[4], $format);
+ $format = str_replace("{ii}", $d[5], $format);
+ $format = str_replace("{ss}", $d[6], $format);
+ $format = str_replace("{time}", $t, $format);
+
+ //过滤文件名的非法自负,并替换文件名
+ $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));
+ $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
+ $format = str_replace("{filename}", $oriName, $format);
+
+ //替换随机字符串
+ $randNum = rand(1, 10000000000) . rand(1, 10000000000);
+ if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
+ $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
+ }
+
+ $ext = $this->getFileExt();
+ return $format . $ext;
+ }
+
+ /**
+ * 获取文件名
+ * @return string
+ */
+ private function getFileName () {
+ return substr($this->filePath, strrpos($this->filePath, '/') + 1);
+ }
+
+ /**
+ * 获取文件完整路径
+ * @return string
+ */
+ private function getFilePath()
+ {
+ $fullname = $this->fullName;
+ $rootPath = $_SERVER['DOCUMENT_ROOT'];
+
+ if (substr($fullname, 0, 1) != '/') {
+ $fullname = '/' . $fullname;
+ }
+ return $rootPath . $fullname;
+ }
+
+ /**
+ * 文件类型检测
+ * @return bool
+ */
+ private function checkType()
+ {
+ return in_array($this->getFileExt(), $this->config["allowFiles"]);
+ }
+
+ /**
+ * 文件大小检测
+ * @return bool
+ */
+ private function checkSize()
+ {
+ return $this->fileSize <= ($this->config["maxSize"]);
+ }
+
+ /**
+ * 获取当前上传成功文件的各项信息
+ * @return array
+ */
+ public function getFileInfo()
+ {
+ return array(
+ "state" => $this->stateInfo,
+ "url" => $this->fullName,
+ "title" => $this->fileName,
+ "original" => $this->oriName,
+ "type" => $this->fileType,
+ "size" => $this->fileSize
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/extend/utils/UnionpayB2C.php b/extend/utils/UnionpayB2C.php
new file mode 100644
index 0000000..c2ff8e5
--- /dev/null
+++ b/extend/utils/UnionpayB2C.php
@@ -0,0 +1,146 @@
+ '156'
+ ];
+
+ protected $currencyCode;
+
+ #交易子类型列表,支付接口专用
+ protected $txnSubType_list = [
+ 'zizhu' => '01',
+ 'fenqi' => '03',
+ ];
+
+ protected $txnSubType;
+
+ #接入类型
+ protected $accessType = '0'; //商户直连
+
+ #签名算法
+ protected $signMethod;
+
+ #渠道类型列表
+ protected $channelType_list = [
+ 'pc' => '07',
+ 'mobile' => '08'
+ ];
+
+ protected $channelType;
+
+ #商户号
+ // protected $merId = '777290058181532'; //test
+ protected $merId = '802310057320534'; //线上
+
+ #接口url列表
+ protected $dev_url_list = [
+ 'pay' => 'https://gateway.test.95516.com/gateway/api/frontTransReq.do',
+ 'query' => 'https://gateway.test.95516.com/gateway/api/queryTrans.do',
+ ];
+
+ protected $prod_url_list = [
+ 'pay' => 'https://gateway.95516.com/gateway/api/frontTransReq.do',
+ 'query' => 'https://gateway.95516.com/gateway/api/queryTrans.do',
+ ];
+
+ protected $url_list;
+
+ private $logger;
+
+ public function __construct()
+ {
+ parent::__construct();
+ $this->init();
+ }
+
+ /**
+ * 初始化部分参数
+ */
+ private function init()
+ {
+ require_once app()->getRootPath() . '/extend/payment/unionpay/sdk/AcpService.php';
+ $this->version = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->version;
+ $this->front_url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->frontUrl;
+ $this->back_url = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->backUrl;
+ $this->signMethod = com\unionpay\acp\sdk\SDKConfig::getSDKConfig()->signMethod;
+ // $this->url_list = $this->dev_url_list;
+ $this->url_list = $this->prod_url_list;
+
+ $date = explode('-', date('Y-m-d'));
+ $filepath = APP_PATH . 'Lib/pay/log/' . $date[0] . '-' . $date[1] . '/' . $date[2];
+ $filename = $this->pay_type . '.log';
+ import('ORG.Util.FileLog');
+ $this->logger = new FileLog($filepath, $filename);
+ }
+
+ /**
+ * 查询支付状态
+ * @param $pay_log === pay_log表记录
+ */
+ public function query($pay_log)
+ {
+ $out_trade_no = $pay_log['out_trade_no'];
+ $txnTime = date('YmdHis', strtotime($pay_log['create_time']));
+ $this->bizType = $this->bizType_list['query'][$pay_log['pay_type']];
+ $this->channelType = $this->channelType_list[$pay_log['source']];
+ $params = [
+ 'version' => $this->version, //版本号
+ 'encoding' => $this->encoding, //编码方式
+ 'signMethod' => $this->signMethod, //签名方法
+ 'txnType' => '00', //交易类型
+ 'txnSubType' => '00', //交易子类
+ 'bizType' => '000000', //业务类型
+ 'accessType' => $this->accessType, //接入类型
+ 'channelType' => $this->channelType, //渠道类型
+
+ 'orderId' => $out_trade_no, //请修改被查询的交易的订单号,8-32位数字字母,不能含“-”或“_”,此处默认取demo演示页面传递的参数
+ 'merId' => $this->merId, //商户代码,请改自己的测试商户号,此处默认取demo演示页面传递的参数
+ 'txnTime' => $txnTime, //请修改被查询的交易的订单发送时间,格式为YYYYMMDDhhmmss,此处默认取demo演示页面传递的参数
+ ];
+
+ com\unionpay\acp\sdk\AcpService::sign ( $params ); // 签名
+ $url = $this->url_list['query'];
+
+ $this->logger->write('查询请求参数: ' . json_encode($params) . '=====url: ' . $url, 'suc');
+ $result_arr = com\unionpay\acp\sdk\AcpService::post ( $params, $url);
+
+ if (count($result_arr) > 0 &&
+ com\unionpay\acp\sdk\AcpService::validate ($result_arr) &&
+ $result_arr["respCode"] == "00" &&
+ $result_arr["origRespCode"] == "00"
+ )
+ {
+ $this->logger->write('查询完成,交易成功,交易单号: ' . $out_trade_no, 'suc');
+ return $result_arr;
+ }
+
+ $this->logger->write('查询完成,交易失败,交易单号: ' . $out_trade_no);
+ return false;
+ }
+
+ private function http_success()
+ {
+ header("HTTP/1.1 200 OK");
+ exit;
+ }
+
+ private function http_fail()
+ {
+ header("HTTP/1.1 500 ERROR");
+ exit;
+ }
+}
+
diff --git a/extend/utils/WorkingDay.php b/extend/utils/WorkingDay.php
new file mode 100644
index 0000000..917be47
--- /dev/null
+++ b/extend/utils/WorkingDay.php
@@ -0,0 +1,68 @@
+time = time();
+ }
+
+ /**
+ * 获取当前年度的节假日
+ */
+ private function getHolidays()
+ {
+ $data = Db::name('holiday')->where('year', '=', date('Y'))->column('data');
+ if (empty($data)) {
+ $this->holidays = [];
+ }
+ $this->holidays = $data;
+ }
+
+ /**
+ * 获取工作日
+ */
+ public function getDates($adays)
+ {
+ // 获取节假日
+ $this->getHolidays();
+
+ // 组装工作日
+ $ctime = $this->time;
+ $days = [];
+ $i = 1;
+ while($adays>0) {
+ $day = strtotime("+ $i day", $ctime);
+ $week = date('w', $day);
+ // 剔除周六周日与假日
+ if (0 != $week && 6 != $week && !in_array(date('Y-m-d', $day), $this->holidays)) {
+ $adays-=1;
+ $days[] = date('Y-m-d H:i:s', $day);
+ }
+ $i+=1;
+ }
+ return $days;
+ }
+
+ /**
+ * 获取几个工作日后日期
+ */
+ public function getDate($adays, $ctime = 0)
+ {
+ if (!empty($ctime)) {
+ $this->time = $ctime;
+ }
+ $days = $this->getDates($adays);
+ rsort($days);
+ return $days[0];
+ }
+}
+
diff --git a/extend/utils/ueditor_config.json b/extend/utils/ueditor_config.json
new file mode 100644
index 0000000..93fde49
--- /dev/null
+++ b/extend/utils/ueditor_config.json
@@ -0,0 +1,94 @@
+/* 前后端通信相关的配置,注释只允许使用多行方式 */
+{
+ /* 上传图片配置项 */
+ "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
+ "imageFieldName": "upfile", /* 提交的图片表单名称 */
+ "imageMaxSize": 20480000, /* 上传大小限制,单位B */
+ "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
+ "imageCompressEnable": true, /* 是否压缩图片,默认是true */
+ "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
+ "imageInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageUrlPrefix": "", /* 图片访问路径前缀 */
+ "imagePathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+ /* {time} 会替换成时间戳 */
+ /* {yyyy} 会替换成四位年份 */
+ /* {yy} 会替换成两位年份 */
+ /* {mm} 会替换成两位月份 */
+ /* {dd} 会替换成两位日期 */
+ /* {hh} 会替换成两位小时 */
+ /* {ii} 会替换成两位分钟 */
+ /* {ss} 会替换成两位秒 */
+ /* 非法字符 \ : * ? " < > | */
+ /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
+
+ /* 涂鸦图片上传配置项 */
+ "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
+ "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
+ "scrawlPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "scrawlMaxSize": 20480000, /* 上传大小限制,单位B */
+ "scrawlUrlPrefix": "", /* 图片访问路径前缀 */
+ "scrawlInsertAlign": "none",
+
+ /* 截图工具上传 */
+ "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
+ "snapscreenPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "snapscreenUrlPrefix": "", /* 图片访问路径前缀 */
+ "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
+
+ /* 抓取远程图片配置 */
+ "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
+ "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
+ "catcherFieldName": "source", /* 提交的图片列表表单名称 */
+ "catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "catcherUrlPrefix": "", /* 图片访问路径前缀 */
+ "catcherMaxSize": 20480000, /* 上传大小限制,单位B */
+ "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
+
+ /* 上传视频配置 */
+ "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
+ "videoFieldName": "upfile", /* 提交的视频表单名称 */
+ "videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "videoUrlPrefix": "", /* 视频访问路径前缀 */
+ "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
+ "videoAllowFiles": [
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
+
+ /* 上传文件配置 */
+ "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
+ "fileFieldName": "upfile", /* 提交的文件表单名称 */
+ "filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "fileUrlPrefix": "", /* 文件访问路径前缀 */
+ "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
+ "fileAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ], /* 上传文件格式显示 */
+
+ /* 列出指定目录下的图片 */
+ "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
+ "imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
+ "imageManagerListSize": 20, /* 每次列出文件数量 */
+ "imageManagerUrlPrefix": "", /* 图片访问路径前缀 */
+ "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
+
+ /* 列出指定目录下的文件 */
+ "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
+ "fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
+ "fileManagerUrlPrefix": "", /* 文件访问路径前缀 */
+ "fileManagerListSize": 20, /* 每次列出文件数量 */
+ "fileManagerAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ] /* 列出的文件类型 */
+
+}
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..72f7b77
--- /dev/null
+++ b/index.html
@@ -0,0 +1,24 @@
+
+
+
+
+恭喜,站点创建成功!
+
+
+
+
+
+
+
+
+ 恭喜, 站点创建成功!
+
+ 站点创建成功,本页面由系统自动生成。
+ 本页面在FTP根目录下的index.html
+ 您可以删除或覆盖本页面
+ FTP相关信息,请到宝塔后台查看
+ 我们为您提供了完善的数据备份功能,请到后台进行相关设置21
+
+
+
+
\ No newline at end of file
diff --git a/public/.htaccess b/public/.htaccess
new file mode 100644
index 0000000..0519ecb
--- /dev/null
+++ b/public/.htaccess
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/404.html b/public/404.html
new file mode 100644
index 0000000..99ff94f
--- /dev/null
+++ b/public/404.html
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+404
+
+
+
+
+404,您请求的文件不存在!
+
+
diff --git a/public/assets/css/jquery.bxslider.css b/public/assets/css/jquery.bxslider.css
new file mode 100644
index 0000000..05a05a1
--- /dev/null
+++ b/public/assets/css/jquery.bxslider.css
@@ -0,0 +1,197 @@
+.bx-wrapper {
+ position: relative;
+ margin: 0 auto 15px;
+ padding: 0;
+ *zoom: 1;
+ overflow: hidden;
+}
+
+.bx-wrapper img {
+ max-width: 100%;
+ display: block;
+}
+
+/** THEME
+===================================*/
+
+.bx-wrapper .bx-viewport {
+ /*fix other elements on the page moving (on Chrome)*/
+ -webkit-transform: translatez(0);
+ -moz-transform: translatez(0);
+ -ms-transform: translatez(0);
+ -o-transform: translatez(0);
+ transform: translatez(0);
+}
+
+.bx-wrapper .bx-pager,
+.bx-wrapper .bx-controls-auto {
+ position: absolute;
+ bottom: 15px;
+ width: 100%;
+}
+
+/* LOADER */
+
+.bx-wrapper .bx-loading {
+ min-height: 50px;
+ background: url(../images/bx_loader.gif) center center no-repeat #fff;
+ height: 100%;
+ width: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 2000;
+}
+
+/* PAGER */
+
+.bx-wrapper .bx-pager {
+ text-align: center;
+ font-size: 0.85em;
+ font-family: Arial;
+ font-weight: bold;
+ color: #666;
+ padding-top: 20px;
+}
+
+.bx-wrapper .bx-pager .bx-pager-item,
+.bx-wrapper .bx-controls-auto .bx-controls-auto-item {
+ display: inline-block;
+ *zoom: 1;
+ *display: inline;
+}
+
+.bx-wrapper .bx-pager.bx-default-pager a {
+ background: rgba(255, 255, 255, 0.8);
+ text-indent: -9999px;
+ display: block;
+ width: 16px;
+ height: 16px;
+ margin: 0 5px;
+ outline: 0;
+ border-radius: 8px;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ -ms-border-radius: 8px;
+ -o-border-radius: 8px;
+}
+
+.bx-wrapper .bx-pager.bx-default-pager a:hover,
+.bx-wrapper .bx-pager.bx-default-pager a.active {
+ background: #fff;
+ width: 32px;
+}
+
+@media only screen and (max-width: 575px) {
+ .bx-wrapper .bx-pager.bx-default-pager a {
+ width: 10px;
+ height: 10px;
+ }
+ .bx-wrapper .bx-pager.bx-default-pager a:hover,
+ .bx-wrapper .bx-pager.bx-default-pager a.active {
+ width: 20px;
+ }
+ .bx-wrapper .bx-pager,
+ .bx-wrapper .bx-controls-auto {
+ bottom: 5px;
+ }
+}
+/* DIRECTION CONTROLS (NEXT / PREV) */
+
+.bx-wrapper .bx-prev {
+ left: 10px;
+}
+
+.bx-wrapper .bx-next {
+ right: 10px;
+}
+
+.bx-wrapper .bx-prev:hover {
+ background-position: 0 0;
+}
+
+.bx-wrapper .bx-next:hover {
+ background-position: -43px 0;
+}
+
+.bx-wrapper .bx-controls-direction a {
+ position: absolute;
+ top: 50%;
+ margin-top: -16px;
+ outline: 0;
+ width: 32px;
+ height: 32px;
+ text-indent: -9999px;
+ z-index: 9999;
+}
+
+.bx-wrapper .bx-controls-direction a.disabled {
+ display: none;
+}
+
+/* AUTO CONTROLS (START / STOP) */
+
+.bx-wrapper .bx-controls-auto {
+ text-align: center;
+}
+
+.bx-wrapper .bx-controls-auto .bx-start {
+ display: block;
+ text-indent: -9999px;
+ width: 10px;
+ height: 11px;
+ outline: 0;
+ background: url(../images/controls.png) -86px -11px no-repeat;
+ margin: 0 3px;
+}
+
+.bx-wrapper .bx-controls-auto .bx-start:hover,
+.bx-wrapper .bx-controls-auto .bx-start.active {
+ background-position: -86px 0;
+}
+
+.bx-wrapper .bx-controls-auto .bx-stop {
+ display: block;
+ text-indent: -9999px;
+ width: 9px;
+ height: 11px;
+ outline: 0;
+ background: url(../images/controls.png) -86px -44px no-repeat;
+ margin: 0 3px;
+}
+
+.bx-wrapper .bx-controls-auto .bx-stop:hover,
+.bx-wrapper .bx-controls-auto .bx-stop.active {
+ background-position: -86px -33px;
+}
+
+/* PAGER WITH AUTO-CONTROLS HYBRID LAYOUT */
+
+.bx-wrapper .bx-controls.bx-has-controls-auto.bx-has-pager .bx-pager {
+ text-align: left;
+ width: 80%;
+}
+
+.bx-wrapper .bx-controls.bx-has-controls-auto.bx-has-pager .bx-controls-auto {
+ right: 0;
+ width: 35px;
+}
+
+/* IMAGE CAPTIONS */
+
+.bx-wrapper .bx-caption {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ background: #666\9;
+ background: rgba(80, 80, 80, 0.75);
+ width: 100%;
+}
+
+.bx-wrapper .bx-caption span {
+ color: #fff;
+ font-family: Arial;
+ display: block;
+ font-size: 0.85em;
+ padding: 10px;
+}
diff --git a/public/assets/css/plugins/images/ui-icons_444444_256x240.png b/public/assets/css/plugins/images/ui-icons_444444_256x240.png
new file mode 100644
index 0000000..c2daae1
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_444444_256x240.png differ
diff --git a/public/assets/css/plugins/images/ui-icons_555555_256x240.png b/public/assets/css/plugins/images/ui-icons_555555_256x240.png
new file mode 100644
index 0000000..4784928
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_555555_256x240.png differ
diff --git a/public/assets/css/plugins/images/ui-icons_777620_256x240.png b/public/assets/css/plugins/images/ui-icons_777620_256x240.png
new file mode 100644
index 0000000..d2f58d2
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_777620_256x240.png differ
diff --git a/public/assets/css/plugins/images/ui-icons_777777_256x240.png b/public/assets/css/plugins/images/ui-icons_777777_256x240.png
new file mode 100644
index 0000000..1d53258
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_777777_256x240.png differ
diff --git a/public/assets/css/plugins/images/ui-icons_cc0000_256x240.png b/public/assets/css/plugins/images/ui-icons_cc0000_256x240.png
new file mode 100644
index 0000000..2825f20
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_cc0000_256x240.png differ
diff --git a/public/assets/css/plugins/images/ui-icons_ffffff_256x240.png b/public/assets/css/plugins/images/ui-icons_ffffff_256x240.png
new file mode 100644
index 0000000..136a4f9
Binary files /dev/null and b/public/assets/css/plugins/images/ui-icons_ffffff_256x240.png differ
diff --git a/public/assets/css/plugins/plugins.min.css b/public/assets/css/plugins/plugins.min.css
new file mode 100644
index 0000000..6fc5834
--- /dev/null
+++ b/public/assets/css/plugins/plugins.min.css
@@ -0,0 +1,6976 @@
+@charset "UTF-8"; /*!
+ * animate.css - https://animate.style/
+ * Version - 4.1.1
+ * Licensed under the MIT license - http://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2021 Animate.css
+ */
+:root {
+ --animate-duration: 1s;
+ --animate-delay: 1s;
+ --animate-repeat: 1;
+}
+.animate__animated {
+ -webkit-animation-duration: 1s;
+ animation-duration: 1s;
+ -webkit-animation-duration: var(--animate-duration);
+ animation-duration: var(--animate-duration);
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+}
+.animate__animated.animate__infinite {
+ -webkit-animation-iteration-count: infinite;
+ animation-iteration-count: infinite;
+}
+.animate__animated.animate__repeat-1 {
+ -webkit-animation-iteration-count: 1;
+ animation-iteration-count: 1;
+ -webkit-animation-iteration-count: var(--animate-repeat);
+ animation-iteration-count: var(--animate-repeat);
+}
+.animate__animated.animate__repeat-2 {
+ -webkit-animation-iteration-count: 2;
+ animation-iteration-count: 2;
+ -webkit-animation-iteration-count: calc(var(--animate-repeat) * 2);
+ animation-iteration-count: calc(var(--animate-repeat) * 2);
+}
+.animate__animated.animate__repeat-3 {
+ -webkit-animation-iteration-count: 3;
+ animation-iteration-count: 3;
+ -webkit-animation-iteration-count: calc(var(--animate-repeat) * 3);
+ animation-iteration-count: calc(var(--animate-repeat) * 3);
+}
+.animate__animated.animate__delay-1s {
+ -webkit-animation-delay: 1s;
+ animation-delay: 1s;
+ -webkit-animation-delay: var(--animate-delay);
+ animation-delay: var(--animate-delay);
+}
+.animate__animated.animate__delay-2s {
+ -webkit-animation-delay: 2s;
+ animation-delay: 2s;
+ -webkit-animation-delay: calc(var(--animate-delay) * 2);
+ animation-delay: calc(var(--animate-delay) * 2);
+}
+.animate__animated.animate__delay-3s {
+ -webkit-animation-delay: 3s;
+ animation-delay: 3s;
+ -webkit-animation-delay: calc(var(--animate-delay) * 3);
+ animation-delay: calc(var(--animate-delay) * 3);
+}
+.animate__animated.animate__delay-4s {
+ -webkit-animation-delay: 4s;
+ animation-delay: 4s;
+ -webkit-animation-delay: calc(var(--animate-delay) * 4);
+ animation-delay: calc(var(--animate-delay) * 4);
+}
+.animate__animated.animate__delay-5s {
+ -webkit-animation-delay: 5s;
+ animation-delay: 5s;
+ -webkit-animation-delay: calc(var(--animate-delay) * 5);
+ animation-delay: calc(var(--animate-delay) * 5);
+}
+.animate__animated.animate__faster {
+ -webkit-animation-duration: 0.5s;
+ animation-duration: 0.5s;
+ -webkit-animation-duration: calc(var(--animate-duration) / 2);
+ animation-duration: calc(var(--animate-duration) / 2);
+}
+.animate__animated.animate__fast {
+ -webkit-animation-duration: 0.8s;
+ animation-duration: 0.8s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 0.8);
+ animation-duration: calc(var(--animate-duration) * 0.8);
+}
+.animate__animated.animate__slow {
+ -webkit-animation-duration: 2s;
+ animation-duration: 2s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 2);
+ animation-duration: calc(var(--animate-duration) * 2);
+}
+.animate__animated.animate__slower {
+ -webkit-animation-duration: 3s;
+ animation-duration: 3s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 3);
+ animation-duration: calc(var(--animate-duration) * 3);
+}
+@media (prefers-reduced-motion: reduce), print {
+ .animate__animated {
+ -webkit-animation-duration: 1ms !important;
+ animation-duration: 1ms !important;
+ -webkit-transition-duration: 1ms !important;
+ transition-duration: 1ms !important;
+ -webkit-animation-iteration-count: 1 !important;
+ animation-iteration-count: 1 !important;
+ }
+ .animate__animated[class*='Out'] {
+ opacity: 0;
+ }
+}
+@-webkit-keyframes bounce {
+ 0%,
+ 20%,
+ 53%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 40%,
+ 43% {
+ -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ -webkit-transform: translate3d(0, -30px, 0) scaleY(1.1);
+ transform: translate3d(0, -30px, 0) scaleY(1.1);
+ }
+ 70% {
+ -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ -webkit-transform: translate3d(0, -15px, 0) scaleY(1.05);
+ transform: translate3d(0, -15px, 0) scaleY(1.05);
+ }
+ 80% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ -webkit-transform: translateZ(0) scaleY(0.95);
+ transform: translateZ(0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, -4px, 0) scaleY(1.02);
+ transform: translate3d(0, -4px, 0) scaleY(1.02);
+ }
+}
+@keyframes bounce {
+ 0%,
+ 20%,
+ 53%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 40%,
+ 43% {
+ -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ -webkit-transform: translate3d(0, -30px, 0) scaleY(1.1);
+ transform: translate3d(0, -30px, 0) scaleY(1.1);
+ }
+ 70% {
+ -webkit-animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+ -webkit-transform: translate3d(0, -15px, 0) scaleY(1.05);
+ transform: translate3d(0, -15px, 0) scaleY(1.05);
+ }
+ 80% {
+ -webkit-transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ transition-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ -webkit-transform: translateZ(0) scaleY(0.95);
+ transform: translateZ(0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, -4px, 0) scaleY(1.02);
+ transform: translate3d(0, -4px, 0) scaleY(1.02);
+ }
+}
+.animate__bounce {
+ -webkit-animation-name: bounce;
+ animation-name: bounce;
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+}
+@-webkit-keyframes flash {
+ 0%,
+ 50%,
+ to {
+ opacity: 1;
+ }
+ 25%,
+ 75% {
+ opacity: 0;
+ }
+}
+@keyframes flash {
+ 0%,
+ 50%,
+ to {
+ opacity: 1;
+ }
+ 25%,
+ 75% {
+ opacity: 0;
+ }
+}
+.animate__flash {
+ -webkit-animation-name: flash;
+ animation-name: flash;
+}
+@-webkit-keyframes pulse {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 50% {
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
+ transform: scale3d(1.05, 1.05, 1.05);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+@keyframes pulse {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 50% {
+ -webkit-transform: scale3d(1.05, 1.05, 1.05);
+ transform: scale3d(1.05, 1.05, 1.05);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+.animate__pulse {
+ -webkit-animation-name: pulse;
+ animation-name: pulse;
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+}
+@-webkit-keyframes rubberBand {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 30% {
+ -webkit-transform: scale3d(1.25, 0.75, 1);
+ transform: scale3d(1.25, 0.75, 1);
+ }
+ 40% {
+ -webkit-transform: scale3d(0.75, 1.25, 1);
+ transform: scale3d(0.75, 1.25, 1);
+ }
+ 50% {
+ -webkit-transform: scale3d(1.15, 0.85, 1);
+ transform: scale3d(1.15, 0.85, 1);
+ }
+ 65% {
+ -webkit-transform: scale3d(0.95, 1.05, 1);
+ transform: scale3d(0.95, 1.05, 1);
+ }
+ 75% {
+ -webkit-transform: scale3d(1.05, 0.95, 1);
+ transform: scale3d(1.05, 0.95, 1);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+@keyframes rubberBand {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 30% {
+ -webkit-transform: scale3d(1.25, 0.75, 1);
+ transform: scale3d(1.25, 0.75, 1);
+ }
+ 40% {
+ -webkit-transform: scale3d(0.75, 1.25, 1);
+ transform: scale3d(0.75, 1.25, 1);
+ }
+ 50% {
+ -webkit-transform: scale3d(1.15, 0.85, 1);
+ transform: scale3d(1.15, 0.85, 1);
+ }
+ 65% {
+ -webkit-transform: scale3d(0.95, 1.05, 1);
+ transform: scale3d(0.95, 1.05, 1);
+ }
+ 75% {
+ -webkit-transform: scale3d(1.05, 0.95, 1);
+ transform: scale3d(1.05, 0.95, 1);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+.animate__rubberBand {
+ -webkit-animation-name: rubberBand;
+ animation-name: rubberBand;
+}
+@-webkit-keyframes shakeX {
+ 0%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 10%,
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+ 20%,
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+}
+@keyframes shakeX {
+ 0%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 10%,
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: translate3d(-10px, 0, 0);
+ transform: translate3d(-10px, 0, 0);
+ }
+ 20%,
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: translate3d(10px, 0, 0);
+ transform: translate3d(10px, 0, 0);
+ }
+}
+.animate__shakeX {
+ -webkit-animation-name: shakeX;
+ animation-name: shakeX;
+}
+@-webkit-keyframes shakeY {
+ 0%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 10%,
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+ 20%,
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+}
+@keyframes shakeY {
+ 0%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 10%,
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: translate3d(0, -10px, 0);
+ transform: translate3d(0, -10px, 0);
+ }
+ 20%,
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: translate3d(0, 10px, 0);
+ transform: translate3d(0, 10px, 0);
+ }
+}
+.animate__shakeY {
+ -webkit-animation-name: shakeY;
+ animation-name: shakeY;
+}
+@-webkit-keyframes headShake {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+ 6.5% {
+ -webkit-transform: translateX(-6px) rotateY(-9deg);
+ transform: translateX(-6px) rotateY(-9deg);
+ }
+ 18.5% {
+ -webkit-transform: translateX(5px) rotateY(7deg);
+ transform: translateX(5px) rotateY(7deg);
+ }
+ 31.5% {
+ -webkit-transform: translateX(-3px) rotateY(-5deg);
+ transform: translateX(-3px) rotateY(-5deg);
+ }
+ 43.5% {
+ -webkit-transform: translateX(2px) rotateY(3deg);
+ transform: translateX(2px) rotateY(3deg);
+ }
+ 50% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+@keyframes headShake {
+ 0% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+ 6.5% {
+ -webkit-transform: translateX(-6px) rotateY(-9deg);
+ transform: translateX(-6px) rotateY(-9deg);
+ }
+ 18.5% {
+ -webkit-transform: translateX(5px) rotateY(7deg);
+ transform: translateX(5px) rotateY(7deg);
+ }
+ 31.5% {
+ -webkit-transform: translateX(-3px) rotateY(-5deg);
+ transform: translateX(-3px) rotateY(-5deg);
+ }
+ 43.5% {
+ -webkit-transform: translateX(2px) rotateY(3deg);
+ transform: translateX(2px) rotateY(3deg);
+ }
+ 50% {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+ }
+}
+.animate__headShake {
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ -webkit-animation-name: headShake;
+ animation-name: headShake;
+}
+@-webkit-keyframes swing {
+ 20% {
+ -webkit-transform: rotate(15deg);
+ transform: rotate(15deg);
+ }
+ 40% {
+ -webkit-transform: rotate(-10deg);
+ transform: rotate(-10deg);
+ }
+ 60% {
+ -webkit-transform: rotate(5deg);
+ transform: rotate(5deg);
+ }
+ 80% {
+ -webkit-transform: rotate(-5deg);
+ transform: rotate(-5deg);
+ }
+ to {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+}
+@keyframes swing {
+ 20% {
+ -webkit-transform: rotate(15deg);
+ transform: rotate(15deg);
+ }
+ 40% {
+ -webkit-transform: rotate(-10deg);
+ transform: rotate(-10deg);
+ }
+ 60% {
+ -webkit-transform: rotate(5deg);
+ transform: rotate(5deg);
+ }
+ 80% {
+ -webkit-transform: rotate(-5deg);
+ transform: rotate(-5deg);
+ }
+ to {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+}
+.animate__swing {
+ -webkit-transform-origin: top center;
+ transform-origin: top center;
+ -webkit-animation-name: swing;
+ animation-name: swing;
+}
+@-webkit-keyframes tada {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 10%,
+ 20% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate(-3deg);
+ transform: scale3d(0.9, 0.9, 0.9) rotate(-3deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate(3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate(3deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate(-3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate(-3deg);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+@keyframes tada {
+ 0% {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+ 10%,
+ 20% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9) rotate(-3deg);
+ transform: scale3d(0.9, 0.9, 0.9) rotate(-3deg);
+ }
+ 30%,
+ 50%,
+ 70%,
+ 90% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate(3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate(3deg);
+ }
+ 40%,
+ 60%,
+ 80% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1) rotate(-3deg);
+ transform: scale3d(1.1, 1.1, 1.1) rotate(-3deg);
+ }
+ to {
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+.animate__tada {
+ -webkit-animation-name: tada;
+ animation-name: tada;
+}
+@-webkit-keyframes wobble {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 15% {
+ -webkit-transform: translate3d(-25%, 0, 0) rotate(-5deg);
+ transform: translate3d(-25%, 0, 0) rotate(-5deg);
+ }
+ 30% {
+ -webkit-transform: translate3d(20%, 0, 0) rotate(3deg);
+ transform: translate3d(20%, 0, 0) rotate(3deg);
+ }
+ 45% {
+ -webkit-transform: translate3d(-15%, 0, 0) rotate(-3deg);
+ transform: translate3d(-15%, 0, 0) rotate(-3deg);
+ }
+ 60% {
+ -webkit-transform: translate3d(10%, 0, 0) rotate(2deg);
+ transform: translate3d(10%, 0, 0) rotate(2deg);
+ }
+ 75% {
+ -webkit-transform: translate3d(-5%, 0, 0) rotate(-1deg);
+ transform: translate3d(-5%, 0, 0) rotate(-1deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes wobble {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 15% {
+ -webkit-transform: translate3d(-25%, 0, 0) rotate(-5deg);
+ transform: translate3d(-25%, 0, 0) rotate(-5deg);
+ }
+ 30% {
+ -webkit-transform: translate3d(20%, 0, 0) rotate(3deg);
+ transform: translate3d(20%, 0, 0) rotate(3deg);
+ }
+ 45% {
+ -webkit-transform: translate3d(-15%, 0, 0) rotate(-3deg);
+ transform: translate3d(-15%, 0, 0) rotate(-3deg);
+ }
+ 60% {
+ -webkit-transform: translate3d(10%, 0, 0) rotate(2deg);
+ transform: translate3d(10%, 0, 0) rotate(2deg);
+ }
+ 75% {
+ -webkit-transform: translate3d(-5%, 0, 0) rotate(-1deg);
+ transform: translate3d(-5%, 0, 0) rotate(-1deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__wobble {
+ -webkit-animation-name: wobble;
+ animation-name: wobble;
+}
+@-webkit-keyframes jello {
+ 0%,
+ 11.1%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 22.2% {
+ -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);
+ transform: skewX(-12.5deg) skewY(-12.5deg);
+ }
+ 33.3% {
+ -webkit-transform: skewX(6.25deg) skewY(6.25deg);
+ transform: skewX(6.25deg) skewY(6.25deg);
+ }
+ 44.4% {
+ -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);
+ transform: skewX(-3.125deg) skewY(-3.125deg);
+ }
+ 55.5% {
+ -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);
+ transform: skewX(1.5625deg) skewY(1.5625deg);
+ }
+ 66.6% {
+ -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);
+ transform: skewX(-0.78125deg) skewY(-0.78125deg);
+ }
+ 77.7% {
+ -webkit-transform: skewX(0.390625deg) skewY(0.390625deg);
+ transform: skewX(0.390625deg) skewY(0.390625deg);
+ }
+ 88.8% {
+ -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg);
+ transform: skewX(-0.1953125deg) skewY(-0.1953125deg);
+ }
+}
+@keyframes jello {
+ 0%,
+ 11.1%,
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ 22.2% {
+ -webkit-transform: skewX(-12.5deg) skewY(-12.5deg);
+ transform: skewX(-12.5deg) skewY(-12.5deg);
+ }
+ 33.3% {
+ -webkit-transform: skewX(6.25deg) skewY(6.25deg);
+ transform: skewX(6.25deg) skewY(6.25deg);
+ }
+ 44.4% {
+ -webkit-transform: skewX(-3.125deg) skewY(-3.125deg);
+ transform: skewX(-3.125deg) skewY(-3.125deg);
+ }
+ 55.5% {
+ -webkit-transform: skewX(1.5625deg) skewY(1.5625deg);
+ transform: skewX(1.5625deg) skewY(1.5625deg);
+ }
+ 66.6% {
+ -webkit-transform: skewX(-0.78125deg) skewY(-0.78125deg);
+ transform: skewX(-0.78125deg) skewY(-0.78125deg);
+ }
+ 77.7% {
+ -webkit-transform: skewX(0.390625deg) skewY(0.390625deg);
+ transform: skewX(0.390625deg) skewY(0.390625deg);
+ }
+ 88.8% {
+ -webkit-transform: skewX(-0.1953125deg) skewY(-0.1953125deg);
+ transform: skewX(-0.1953125deg) skewY(-0.1953125deg);
+ }
+}
+.animate__jello {
+ -webkit-animation-name: jello;
+ animation-name: jello;
+ -webkit-transform-origin: center;
+ transform-origin: center;
+}
+@-webkit-keyframes heartBeat {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+ 14% {
+ -webkit-transform: scale(1.3);
+ transform: scale(1.3);
+ }
+ 28% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+ 42% {
+ -webkit-transform: scale(1.3);
+ transform: scale(1.3);
+ }
+ 70% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes heartBeat {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+ 14% {
+ -webkit-transform: scale(1.3);
+ transform: scale(1.3);
+ }
+ 28% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+ 42% {
+ -webkit-transform: scale(1.3);
+ transform: scale(1.3);
+ }
+ 70% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.animate__heartBeat {
+ -webkit-animation-name: heartBeat;
+ animation-name: heartBeat;
+ -webkit-animation-duration: 1.3s;
+ animation-duration: 1.3s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 1.3);
+ animation-duration: calc(var(--animate-duration) * 1.3);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+}
+@-webkit-keyframes backInDown {
+ 0% {
+ -webkit-transform: translateY(-1200px) scale(0.7);
+ transform: translateY(-1200px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+@keyframes backInDown {
+ 0% {
+ -webkit-transform: translateY(-1200px) scale(0.7);
+ transform: translateY(-1200px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+.animate__backInDown {
+ -webkit-animation-name: backInDown;
+ animation-name: backInDown;
+}
+@-webkit-keyframes backInLeft {
+ 0% {
+ -webkit-transform: translateX(-2000px) scale(0.7);
+ transform: translateX(-2000px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+@keyframes backInLeft {
+ 0% {
+ -webkit-transform: translateX(-2000px) scale(0.7);
+ transform: translateX(-2000px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+.animate__backInLeft {
+ -webkit-animation-name: backInLeft;
+ animation-name: backInLeft;
+}
+@-webkit-keyframes backInRight {
+ 0% {
+ -webkit-transform: translateX(2000px) scale(0.7);
+ transform: translateX(2000px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+@keyframes backInRight {
+ 0% {
+ -webkit-transform: translateX(2000px) scale(0.7);
+ transform: translateX(2000px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+.animate__backInRight {
+ -webkit-animation-name: backInRight;
+ animation-name: backInRight;
+}
+@-webkit-keyframes backInUp {
+ 0% {
+ -webkit-transform: translateY(1200px) scale(0.7);
+ transform: translateY(1200px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+@keyframes backInUp {
+ 0% {
+ -webkit-transform: translateY(1200px) scale(0.7);
+ transform: translateY(1200px) scale(0.7);
+ opacity: 0.7;
+ }
+ 80% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+}
+.animate__backInUp {
+ -webkit-animation-name: backInUp;
+ animation-name: backInUp;
+}
+@-webkit-keyframes backOutDown {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateY(700px) scale(0.7);
+ transform: translateY(700px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+@keyframes backOutDown {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateY(700px) scale(0.7);
+ transform: translateY(700px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+.animate__backOutDown {
+ -webkit-animation-name: backOutDown;
+ animation-name: backOutDown;
+}
+@-webkit-keyframes backOutLeft {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateX(-2000px) scale(0.7);
+ transform: translateX(-2000px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+@keyframes backOutLeft {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateX(-2000px) scale(0.7);
+ transform: translateX(-2000px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+.animate__backOutLeft {
+ -webkit-animation-name: backOutLeft;
+ animation-name: backOutLeft;
+}
+@-webkit-keyframes backOutRight {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateX(2000px) scale(0.7);
+ transform: translateX(2000px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+@keyframes backOutRight {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateX(0) scale(0.7);
+ transform: translateX(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateX(2000px) scale(0.7);
+ transform: translateX(2000px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+.animate__backOutRight {
+ -webkit-animation-name: backOutRight;
+ animation-name: backOutRight;
+}
+@-webkit-keyframes backOutUp {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateY(-700px) scale(0.7);
+ transform: translateY(-700px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+@keyframes backOutUp {
+ 0% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 1;
+ }
+ 20% {
+ -webkit-transform: translateY(0) scale(0.7);
+ transform: translateY(0) scale(0.7);
+ opacity: 0.7;
+ }
+ to {
+ -webkit-transform: translateY(-700px) scale(0.7);
+ transform: translateY(-700px) scale(0.7);
+ opacity: 0.7;
+ }
+}
+.animate__backOutUp {
+ -webkit-animation-name: backOutUp;
+ animation-name: backOutUp;
+}
+@-webkit-keyframes bounceIn {
+ 0%,
+ 20%,
+ 40%,
+ 60%,
+ 80%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ 20% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+ 40% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9);
+ transform: scale3d(0.9, 0.9, 0.9);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
+ transform: scale3d(1.03, 1.03, 1.03);
+ }
+ 80% {
+ -webkit-transform: scale3d(0.97, 0.97, 0.97);
+ transform: scale3d(0.97, 0.97, 0.97);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+@keyframes bounceIn {
+ 0%,
+ 20%,
+ 40%,
+ 60%,
+ 80%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ 20% {
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+ 40% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9);
+ transform: scale3d(0.9, 0.9, 0.9);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.03, 1.03, 1.03);
+ transform: scale3d(1.03, 1.03, 1.03);
+ }
+ 80% {
+ -webkit-transform: scale3d(0.97, 0.97, 0.97);
+ transform: scale3d(0.97, 0.97, 0.97);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: scaleX(1);
+ transform: scaleX(1);
+ }
+}
+.animate__bounceIn {
+ -webkit-animation-duration: 0.75s;
+ animation-duration: 0.75s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 0.75);
+ animation-duration: calc(var(--animate-duration) * 0.75);
+ -webkit-animation-name: bounceIn;
+ animation-name: bounceIn;
+}
+@-webkit-keyframes bounceInDown {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -3000px, 0) scaleY(3);
+ transform: translate3d(0, -3000px, 0) scaleY(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 25px, 0) scaleY(0.9);
+ transform: translate3d(0, 25px, 0) scaleY(0.9);
+ }
+ 75% {
+ -webkit-transform: translate3d(0, -10px, 0) scaleY(0.95);
+ transform: translate3d(0, -10px, 0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, 5px, 0) scaleY(0.985);
+ transform: translate3d(0, 5px, 0) scaleY(0.985);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes bounceInDown {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -3000px, 0) scaleY(3);
+ transform: translate3d(0, -3000px, 0) scaleY(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 25px, 0) scaleY(0.9);
+ transform: translate3d(0, 25px, 0) scaleY(0.9);
+ }
+ 75% {
+ -webkit-transform: translate3d(0, -10px, 0) scaleY(0.95);
+ transform: translate3d(0, -10px, 0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, 5px, 0) scaleY(0.985);
+ transform: translate3d(0, 5px, 0) scaleY(0.985);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__bounceInDown {
+ -webkit-animation-name: bounceInDown;
+ animation-name: bounceInDown;
+}
+@-webkit-keyframes bounceInLeft {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-3000px, 0, 0) scaleX(3);
+ transform: translate3d(-3000px, 0, 0) scaleX(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(25px, 0, 0) scaleX(1);
+ transform: translate3d(25px, 0, 0) scaleX(1);
+ }
+ 75% {
+ -webkit-transform: translate3d(-10px, 0, 0) scaleX(0.98);
+ transform: translate3d(-10px, 0, 0) scaleX(0.98);
+ }
+ 90% {
+ -webkit-transform: translate3d(5px, 0, 0) scaleX(0.995);
+ transform: translate3d(5px, 0, 0) scaleX(0.995);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes bounceInLeft {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-3000px, 0, 0) scaleX(3);
+ transform: translate3d(-3000px, 0, 0) scaleX(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(25px, 0, 0) scaleX(1);
+ transform: translate3d(25px, 0, 0) scaleX(1);
+ }
+ 75% {
+ -webkit-transform: translate3d(-10px, 0, 0) scaleX(0.98);
+ transform: translate3d(-10px, 0, 0) scaleX(0.98);
+ }
+ 90% {
+ -webkit-transform: translate3d(5px, 0, 0) scaleX(0.995);
+ transform: translate3d(5px, 0, 0) scaleX(0.995);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__bounceInLeft {
+ -webkit-animation-name: bounceInLeft;
+ animation-name: bounceInLeft;
+}
+@-webkit-keyframes bounceInRight {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(3000px, 0, 0) scaleX(3);
+ transform: translate3d(3000px, 0, 0) scaleX(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(-25px, 0, 0) scaleX(1);
+ transform: translate3d(-25px, 0, 0) scaleX(1);
+ }
+ 75% {
+ -webkit-transform: translate3d(10px, 0, 0) scaleX(0.98);
+ transform: translate3d(10px, 0, 0) scaleX(0.98);
+ }
+ 90% {
+ -webkit-transform: translate3d(-5px, 0, 0) scaleX(0.995);
+ transform: translate3d(-5px, 0, 0) scaleX(0.995);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes bounceInRight {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(3000px, 0, 0) scaleX(3);
+ transform: translate3d(3000px, 0, 0) scaleX(3);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(-25px, 0, 0) scaleX(1);
+ transform: translate3d(-25px, 0, 0) scaleX(1);
+ }
+ 75% {
+ -webkit-transform: translate3d(10px, 0, 0) scaleX(0.98);
+ transform: translate3d(10px, 0, 0) scaleX(0.98);
+ }
+ 90% {
+ -webkit-transform: translate3d(-5px, 0, 0) scaleX(0.995);
+ transform: translate3d(-5px, 0, 0) scaleX(0.995);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__bounceInRight {
+ -webkit-animation-name: bounceInRight;
+ animation-name: bounceInRight;
+}
+@-webkit-keyframes bounceInUp {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 3000px, 0) scaleY(5);
+ transform: translate3d(0, 3000px, 0) scaleY(5);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0) scaleY(0.9);
+ transform: translate3d(0, -20px, 0) scaleY(0.9);
+ }
+ 75% {
+ -webkit-transform: translate3d(0, 10px, 0) scaleY(0.95);
+ transform: translate3d(0, 10px, 0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, -5px, 0) scaleY(0.985);
+ transform: translate3d(0, -5px, 0) scaleY(0.985);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes bounceInUp {
+ 0%,
+ 60%,
+ 75%,
+ 90%,
+ to {
+ -webkit-animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
+ }
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 3000px, 0) scaleY(5);
+ transform: translate3d(0, 3000px, 0) scaleY(5);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0) scaleY(0.9);
+ transform: translate3d(0, -20px, 0) scaleY(0.9);
+ }
+ 75% {
+ -webkit-transform: translate3d(0, 10px, 0) scaleY(0.95);
+ transform: translate3d(0, 10px, 0) scaleY(0.95);
+ }
+ 90% {
+ -webkit-transform: translate3d(0, -5px, 0) scaleY(0.985);
+ transform: translate3d(0, -5px, 0) scaleY(0.985);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__bounceInUp {
+ -webkit-animation-name: bounceInUp;
+ animation-name: bounceInUp;
+}
+@-webkit-keyframes bounceOut {
+ 20% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9);
+ transform: scale3d(0.9, 0.9, 0.9);
+ }
+ 50%,
+ 55% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+}
+@keyframes bounceOut {
+ 20% {
+ -webkit-transform: scale3d(0.9, 0.9, 0.9);
+ transform: scale3d(0.9, 0.9, 0.9);
+ }
+ 50%,
+ 55% {
+ opacity: 1;
+ -webkit-transform: scale3d(1.1, 1.1, 1.1);
+ transform: scale3d(1.1, 1.1, 1.1);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+}
+.animate__bounceOut {
+ -webkit-animation-duration: 0.75s;
+ animation-duration: 0.75s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 0.75);
+ animation-duration: calc(var(--animate-duration) * 0.75);
+ -webkit-animation-name: bounceOut;
+ animation-name: bounceOut;
+}
+@-webkit-keyframes bounceOutDown {
+ 20% {
+ -webkit-transform: translate3d(0, 10px, 0) scaleY(0.985);
+ transform: translate3d(0, 10px, 0) scaleY(0.985);
+ }
+ 40%,
+ 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0) scaleY(0.9);
+ transform: translate3d(0, -20px, 0) scaleY(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0) scaleY(3);
+ transform: translate3d(0, 2000px, 0) scaleY(3);
+ }
+}
+@keyframes bounceOutDown {
+ 20% {
+ -webkit-transform: translate3d(0, 10px, 0) scaleY(0.985);
+ transform: translate3d(0, 10px, 0) scaleY(0.985);
+ }
+ 40%,
+ 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, -20px, 0) scaleY(0.9);
+ transform: translate3d(0, -20px, 0) scaleY(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0) scaleY(3);
+ transform: translate3d(0, 2000px, 0) scaleY(3);
+ }
+}
+.animate__bounceOutDown {
+ -webkit-animation-name: bounceOutDown;
+ animation-name: bounceOutDown;
+}
+@-webkit-keyframes bounceOutLeft {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(20px, 0, 0) scaleX(0.9);
+ transform: translate3d(20px, 0, 0) scaleX(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0) scaleX(2);
+ transform: translate3d(-2000px, 0, 0) scaleX(2);
+ }
+}
+@keyframes bounceOutLeft {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(20px, 0, 0) scaleX(0.9);
+ transform: translate3d(20px, 0, 0) scaleX(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0) scaleX(2);
+ transform: translate3d(-2000px, 0, 0) scaleX(2);
+ }
+}
+.animate__bounceOutLeft {
+ -webkit-animation-name: bounceOutLeft;
+ animation-name: bounceOutLeft;
+}
+@-webkit-keyframes bounceOutRight {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(-20px, 0, 0) scaleX(0.9);
+ transform: translate3d(-20px, 0, 0) scaleX(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0) scaleX(2);
+ transform: translate3d(2000px, 0, 0) scaleX(2);
+ }
+}
+@keyframes bounceOutRight {
+ 20% {
+ opacity: 1;
+ -webkit-transform: translate3d(-20px, 0, 0) scaleX(0.9);
+ transform: translate3d(-20px, 0, 0) scaleX(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0) scaleX(2);
+ transform: translate3d(2000px, 0, 0) scaleX(2);
+ }
+}
+.animate__bounceOutRight {
+ -webkit-animation-name: bounceOutRight;
+ animation-name: bounceOutRight;
+}
+@-webkit-keyframes bounceOutUp {
+ 20% {
+ -webkit-transform: translate3d(0, -10px, 0) scaleY(0.985);
+ transform: translate3d(0, -10px, 0) scaleY(0.985);
+ }
+ 40%,
+ 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 20px, 0) scaleY(0.9);
+ transform: translate3d(0, 20px, 0) scaleY(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0) scaleY(3);
+ transform: translate3d(0, -2000px, 0) scaleY(3);
+ }
+}
+@keyframes bounceOutUp {
+ 20% {
+ -webkit-transform: translate3d(0, -10px, 0) scaleY(0.985);
+ transform: translate3d(0, -10px, 0) scaleY(0.985);
+ }
+ 40%,
+ 45% {
+ opacity: 1;
+ -webkit-transform: translate3d(0, 20px, 0) scaleY(0.9);
+ transform: translate3d(0, 20px, 0) scaleY(0.9);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0) scaleY(3);
+ transform: translate3d(0, -2000px, 0) scaleY(3);
+ }
+}
+.animate__bounceOutUp {
+ -webkit-animation-name: bounceOutUp;
+ animation-name: bounceOutUp;
+}
+@-webkit-keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+@keyframes fadeIn {
+ 0% {
+ opacity: 0;
+ }
+ to {
+ opacity: 1;
+ }
+}
+.animate__fadeIn {
+ -webkit-animation-name: fadeIn;
+ animation-name: fadeIn;
+}
+@-webkit-keyframes fadeInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInDown {
+ -webkit-animation-name: fadeInDown;
+ animation-name: fadeInDown;
+}
+@-webkit-keyframes fadeInDownBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInDownBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInDownBig {
+ -webkit-animation-name: fadeInDownBig;
+ animation-name: fadeInDownBig;
+}
+@-webkit-keyframes fadeInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInLeft {
+ -webkit-animation-name: fadeInLeft;
+ animation-name: fadeInLeft;
+}
+@-webkit-keyframes fadeInLeftBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInLeftBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInLeftBig {
+ -webkit-animation-name: fadeInLeftBig;
+ animation-name: fadeInLeftBig;
+}
+@-webkit-keyframes fadeInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInRight {
+ -webkit-animation-name: fadeInRight;
+ animation-name: fadeInRight;
+}
+@-webkit-keyframes fadeInRightBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInRightBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInRightBig {
+ -webkit-animation-name: fadeInRightBig;
+ animation-name: fadeInRightBig;
+}
+@-webkit-keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInUp {
+ -webkit-animation-name: fadeInUp;
+ animation-name: fadeInUp;
+}
+@-webkit-keyframes fadeInUpBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInUpBig {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInUpBig {
+ -webkit-animation-name: fadeInUpBig;
+ animation-name: fadeInUpBig;
+}
+@-webkit-keyframes fadeInTopLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, -100%, 0);
+ transform: translate3d(-100%, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInTopLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, -100%, 0);
+ transform: translate3d(-100%, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInTopLeft {
+ -webkit-animation-name: fadeInTopLeft;
+ animation-name: fadeInTopLeft;
+}
+@-webkit-keyframes fadeInTopRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, -100%, 0);
+ transform: translate3d(100%, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInTopRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, -100%, 0);
+ transform: translate3d(100%, -100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInTopRight {
+ -webkit-animation-name: fadeInTopRight;
+ animation-name: fadeInTopRight;
+}
+@-webkit-keyframes fadeInBottomLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 100%, 0);
+ transform: translate3d(-100%, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInBottomLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 100%, 0);
+ transform: translate3d(-100%, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInBottomLeft {
+ -webkit-animation-name: fadeInBottomLeft;
+ animation-name: fadeInBottomLeft;
+}
+@-webkit-keyframes fadeInBottomRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 100%, 0);
+ transform: translate3d(100%, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes fadeInBottomRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 100%, 0);
+ transform: translate3d(100%, 100%, 0);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__fadeInBottomRight {
+ -webkit-animation-name: fadeInBottomRight;
+ animation-name: fadeInBottomRight;
+}
+@-webkit-keyframes fadeOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+@keyframes fadeOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ }
+}
+.animate__fadeOut {
+ -webkit-animation-name: fadeOut;
+ animation-name: fadeOut;
+}
+@-webkit-keyframes fadeOutDown {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+@keyframes fadeOutDown {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+.animate__fadeOutDown {
+ -webkit-animation-name: fadeOutDown;
+ animation-name: fadeOutDown;
+}
+@-webkit-keyframes fadeOutDownBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+@keyframes fadeOutDownBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, 2000px, 0);
+ transform: translate3d(0, 2000px, 0);
+ }
+}
+.animate__fadeOutDownBig {
+ -webkit-animation-name: fadeOutDownBig;
+ animation-name: fadeOutDownBig;
+}
+@-webkit-keyframes fadeOutLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+@keyframes fadeOutLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+.animate__fadeOutLeft {
+ -webkit-animation-name: fadeOutLeft;
+ animation-name: fadeOutLeft;
+}
+@-webkit-keyframes fadeOutLeftBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+@keyframes fadeOutLeftBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-2000px, 0, 0);
+ transform: translate3d(-2000px, 0, 0);
+ }
+}
+.animate__fadeOutLeftBig {
+ -webkit-animation-name: fadeOutLeftBig;
+ animation-name: fadeOutLeftBig;
+}
+@-webkit-keyframes fadeOutRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+@keyframes fadeOutRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+.animate__fadeOutRight {
+ -webkit-animation-name: fadeOutRight;
+ animation-name: fadeOutRight;
+}
+@-webkit-keyframes fadeOutRightBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+@keyframes fadeOutRightBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(2000px, 0, 0);
+ transform: translate3d(2000px, 0, 0);
+ }
+}
+.animate__fadeOutRightBig {
+ -webkit-animation-name: fadeOutRightBig;
+ animation-name: fadeOutRightBig;
+}
+@-webkit-keyframes fadeOutUp {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+@keyframes fadeOutUp {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+.animate__fadeOutUp {
+ -webkit-animation-name: fadeOutUp;
+ animation-name: fadeOutUp;
+}
+@-webkit-keyframes fadeOutUpBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+@keyframes fadeOutUpBig {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(0, -2000px, 0);
+ transform: translate3d(0, -2000px, 0);
+ }
+}
+.animate__fadeOutUpBig {
+ -webkit-animation-name: fadeOutUpBig;
+ animation-name: fadeOutUpBig;
+}
+@-webkit-keyframes fadeOutTopLeft {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, -100%, 0);
+ transform: translate3d(-100%, -100%, 0);
+ }
+}
+@keyframes fadeOutTopLeft {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, -100%, 0);
+ transform: translate3d(-100%, -100%, 0);
+ }
+}
+.animate__fadeOutTopLeft {
+ -webkit-animation-name: fadeOutTopLeft;
+ animation-name: fadeOutTopLeft;
+}
+@-webkit-keyframes fadeOutTopRight {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, -100%, 0);
+ transform: translate3d(100%, -100%, 0);
+ }
+}
+@keyframes fadeOutTopRight {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, -100%, 0);
+ transform: translate3d(100%, -100%, 0);
+ }
+}
+.animate__fadeOutTopRight {
+ -webkit-animation-name: fadeOutTopRight;
+ animation-name: fadeOutTopRight;
+}
+@-webkit-keyframes fadeOutBottomRight {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 100%, 0);
+ transform: translate3d(100%, 100%, 0);
+ }
+}
+@keyframes fadeOutBottomRight {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 100%, 0);
+ transform: translate3d(100%, 100%, 0);
+ }
+}
+.animate__fadeOutBottomRight {
+ -webkit-animation-name: fadeOutBottomRight;
+ animation-name: fadeOutBottomRight;
+}
+@-webkit-keyframes fadeOutBottomLeft {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 100%, 0);
+ transform: translate3d(-100%, 100%, 0);
+ }
+}
+@keyframes fadeOutBottomLeft {
+ 0% {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 100%, 0);
+ transform: translate3d(-100%, 100%, 0);
+ }
+}
+.animate__fadeOutBottomLeft {
+ -webkit-animation-name: fadeOutBottomLeft;
+ animation-name: fadeOutBottomLeft;
+}
+@-webkit-keyframes flip {
+ 0% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
+ transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
+ transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+ 50% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
+ transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translateZ(0) rotateY(0deg);
+ transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translateZ(0) rotateY(0deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ to {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
+ transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+}
+@keyframes flip {
+ 0% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
+ transform: perspective(400px) scaleX(1) translateZ(0) rotateY(-1turn);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
+ transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-190deg);
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+ }
+ 50% {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
+ transform: perspective(400px) scaleX(1) translateZ(150px) rotateY(-170deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translateZ(0) rotateY(0deg);
+ transform: perspective(400px) scale3d(0.95, 0.95, 0.95) translateZ(0) rotateY(0deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ to {
+ -webkit-transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
+ transform: perspective(400px) scaleX(1) translateZ(0) rotateY(0deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+}
+.animate__animated.animate__flip {
+ -webkit-backface-visibility: visible;
+ backface-visibility: visible;
+ -webkit-animation-name: flip;
+ animation-name: flip;
+}
+@-webkit-keyframes flipInX {
+ 0% {
+ -webkit-transform: perspective(400px) rotateX(90deg);
+ transform: perspective(400px) rotateX(90deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ opacity: 0;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) rotateX(-20deg);
+ transform: perspective(400px) rotateX(-20deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 60% {
+ -webkit-transform: perspective(400px) rotateX(10deg);
+ transform: perspective(400px) rotateX(10deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) rotateX(-5deg);
+ transform: perspective(400px) rotateX(-5deg);
+ }
+ to {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+@keyframes flipInX {
+ 0% {
+ -webkit-transform: perspective(400px) rotateX(90deg);
+ transform: perspective(400px) rotateX(90deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ opacity: 0;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) rotateX(-20deg);
+ transform: perspective(400px) rotateX(-20deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 60% {
+ -webkit-transform: perspective(400px) rotateX(10deg);
+ transform: perspective(400px) rotateX(10deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) rotateX(-5deg);
+ transform: perspective(400px) rotateX(-5deg);
+ }
+ to {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+.animate__flipInX {
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipInX;
+ animation-name: flipInX;
+}
+@-webkit-keyframes flipInY {
+ 0% {
+ -webkit-transform: perspective(400px) rotateY(90deg);
+ transform: perspective(400px) rotateY(90deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ opacity: 0;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) rotateY(-20deg);
+ transform: perspective(400px) rotateY(-20deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 60% {
+ -webkit-transform: perspective(400px) rotateY(10deg);
+ transform: perspective(400px) rotateY(10deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) rotateY(-5deg);
+ transform: perspective(400px) rotateY(-5deg);
+ }
+ to {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+@keyframes flipInY {
+ 0% {
+ -webkit-transform: perspective(400px) rotateY(90deg);
+ transform: perspective(400px) rotateY(90deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ opacity: 0;
+ }
+ 40% {
+ -webkit-transform: perspective(400px) rotateY(-20deg);
+ transform: perspective(400px) rotateY(-20deg);
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+ }
+ 60% {
+ -webkit-transform: perspective(400px) rotateY(10deg);
+ transform: perspective(400px) rotateY(10deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: perspective(400px) rotateY(-5deg);
+ transform: perspective(400px) rotateY(-5deg);
+ }
+ to {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+}
+.animate__flipInY {
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipInY;
+ animation-name: flipInY;
+}
+@-webkit-keyframes flipOutX {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+ 30% {
+ -webkit-transform: perspective(400px) rotateX(-20deg);
+ transform: perspective(400px) rotateX(-20deg);
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: perspective(400px) rotateX(90deg);
+ transform: perspective(400px) rotateX(90deg);
+ opacity: 0;
+ }
+}
+@keyframes flipOutX {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+ 30% {
+ -webkit-transform: perspective(400px) rotateX(-20deg);
+ transform: perspective(400px) rotateX(-20deg);
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: perspective(400px) rotateX(90deg);
+ transform: perspective(400px) rotateX(90deg);
+ opacity: 0;
+ }
+}
+.animate__flipOutX {
+ -webkit-animation-duration: 0.75s;
+ animation-duration: 0.75s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 0.75);
+ animation-duration: calc(var(--animate-duration) * 0.75);
+ -webkit-animation-name: flipOutX;
+ animation-name: flipOutX;
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+}
+@-webkit-keyframes flipOutY {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+ 30% {
+ -webkit-transform: perspective(400px) rotateY(-15deg);
+ transform: perspective(400px) rotateY(-15deg);
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: perspective(400px) rotateY(90deg);
+ transform: perspective(400px) rotateY(90deg);
+ opacity: 0;
+ }
+}
+@keyframes flipOutY {
+ 0% {
+ -webkit-transform: perspective(400px);
+ transform: perspective(400px);
+ }
+ 30% {
+ -webkit-transform: perspective(400px) rotateY(-15deg);
+ transform: perspective(400px) rotateY(-15deg);
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: perspective(400px) rotateY(90deg);
+ transform: perspective(400px) rotateY(90deg);
+ opacity: 0;
+ }
+}
+.animate__flipOutY {
+ -webkit-animation-duration: 0.75s;
+ animation-duration: 0.75s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 0.75);
+ animation-duration: calc(var(--animate-duration) * 0.75);
+ -webkit-backface-visibility: visible !important;
+ backface-visibility: visible !important;
+ -webkit-animation-name: flipOutY;
+ animation-name: flipOutY;
+}
+@-webkit-keyframes lightSpeedInRight {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+ 60% {
+ -webkit-transform: skewX(20deg);
+ transform: skewX(20deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: skewX(-5deg);
+ transform: skewX(-5deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes lightSpeedInRight {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(-30deg);
+ transform: translate3d(100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+ 60% {
+ -webkit-transform: skewX(20deg);
+ transform: skewX(20deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: skewX(-5deg);
+ transform: skewX(-5deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__lightSpeedInRight {
+ -webkit-animation-name: lightSpeedInRight;
+ animation-name: lightSpeedInRight;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+}
+@-webkit-keyframes lightSpeedInLeft {
+ 0% {
+ -webkit-transform: translate3d(-100%, 0, 0) skewX(30deg);
+ transform: translate3d(-100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+ 60% {
+ -webkit-transform: skewX(-20deg);
+ transform: skewX(-20deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: skewX(5deg);
+ transform: skewX(5deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes lightSpeedInLeft {
+ 0% {
+ -webkit-transform: translate3d(-100%, 0, 0) skewX(30deg);
+ transform: translate3d(-100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+ 60% {
+ -webkit-transform: skewX(-20deg);
+ transform: skewX(-20deg);
+ opacity: 1;
+ }
+ 80% {
+ -webkit-transform: skewX(5deg);
+ transform: skewX(5deg);
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__lightSpeedInLeft {
+ -webkit-animation-name: lightSpeedInLeft;
+ animation-name: lightSpeedInLeft;
+ -webkit-animation-timing-function: ease-out;
+ animation-timing-function: ease-out;
+}
+@-webkit-keyframes lightSpeedOutRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+ transform: translate3d(100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+}
+@keyframes lightSpeedOutRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(100%, 0, 0) skewX(30deg);
+ transform: translate3d(100%, 0, 0) skewX(30deg);
+ opacity: 0;
+ }
+}
+.animate__lightSpeedOutRight {
+ -webkit-animation-name: lightSpeedOutRight;
+ animation-name: lightSpeedOutRight;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+}
+@-webkit-keyframes lightSpeedOutLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(-100%, 0, 0) skewX(-30deg);
+ transform: translate3d(-100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+}
+@keyframes lightSpeedOutLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(-100%, 0, 0) skewX(-30deg);
+ transform: translate3d(-100%, 0, 0) skewX(-30deg);
+ opacity: 0;
+ }
+}
+.animate__lightSpeedOutLeft {
+ -webkit-animation-name: lightSpeedOutLeft;
+ animation-name: lightSpeedOutLeft;
+ -webkit-animation-timing-function: ease-in;
+ animation-timing-function: ease-in;
+}
+@-webkit-keyframes rotateIn {
+ 0% {
+ -webkit-transform: rotate(-200deg);
+ transform: rotate(-200deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+@keyframes rotateIn {
+ 0% {
+ -webkit-transform: rotate(-200deg);
+ transform: rotate(-200deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+.animate__rotateIn {
+ -webkit-animation-name: rotateIn;
+ animation-name: rotateIn;
+ -webkit-transform-origin: center;
+ transform-origin: center;
+}
+@-webkit-keyframes rotateInDownLeft {
+ 0% {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+@keyframes rotateInDownLeft {
+ 0% {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+.animate__rotateInDownLeft {
+ -webkit-animation-name: rotateInDownLeft;
+ animation-name: rotateInDownLeft;
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+}
+@-webkit-keyframes rotateInDownRight {
+ 0% {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+@keyframes rotateInDownRight {
+ 0% {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+.animate__rotateInDownRight {
+ -webkit-animation-name: rotateInDownRight;
+ animation-name: rotateInDownRight;
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+}
+@-webkit-keyframes rotateInUpLeft {
+ 0% {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+@keyframes rotateInUpLeft {
+ 0% {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+.animate__rotateInUpLeft {
+ -webkit-animation-name: rotateInUpLeft;
+ animation-name: rotateInUpLeft;
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+}
+@-webkit-keyframes rotateInUpRight {
+ 0% {
+ -webkit-transform: rotate(-90deg);
+ transform: rotate(-90deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+@keyframes rotateInUpRight {
+ 0% {
+ -webkit-transform: rotate(-90deg);
+ transform: rotate(-90deg);
+ opacity: 0;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ opacity: 1;
+ }
+}
+.animate__rotateInUpRight {
+ -webkit-animation-name: rotateInUpRight;
+ animation-name: rotateInUpRight;
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+}
+@-webkit-keyframes rotateOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(200deg);
+ transform: rotate(200deg);
+ opacity: 0;
+ }
+}
+@keyframes rotateOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(200deg);
+ transform: rotate(200deg);
+ opacity: 0;
+ }
+}
+.animate__rotateOut {
+ -webkit-animation-name: rotateOut;
+ animation-name: rotateOut;
+ -webkit-transform-origin: center;
+ transform-origin: center;
+}
+@-webkit-keyframes rotateOutDownLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+}
+@keyframes rotateOutDownLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ opacity: 0;
+ }
+}
+.animate__rotateOutDownLeft {
+ -webkit-animation-name: rotateOutDownLeft;
+ animation-name: rotateOutDownLeft;
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+}
+@-webkit-keyframes rotateOutDownRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+}
+@keyframes rotateOutDownRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+}
+.animate__rotateOutDownRight {
+ -webkit-animation-name: rotateOutDownRight;
+ animation-name: rotateOutDownRight;
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+}
+@-webkit-keyframes rotateOutUpLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+}
+@keyframes rotateOutUpLeft {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ opacity: 0;
+ }
+}
+.animate__rotateOutUpLeft {
+ -webkit-animation-name: rotateOutUpLeft;
+ animation-name: rotateOutUpLeft;
+ -webkit-transform-origin: left bottom;
+ transform-origin: left bottom;
+}
+@-webkit-keyframes rotateOutUpRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(90deg);
+ transform: rotate(90deg);
+ opacity: 0;
+ }
+}
+@keyframes rotateOutUpRight {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: rotate(90deg);
+ transform: rotate(90deg);
+ opacity: 0;
+ }
+}
+.animate__rotateOutUpRight {
+ -webkit-animation-name: rotateOutUpRight;
+ animation-name: rotateOutUpRight;
+ -webkit-transform-origin: right bottom;
+ transform-origin: right bottom;
+}
+@-webkit-keyframes hinge {
+ 0% {
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+ 20%,
+ 60% {
+ -webkit-transform: rotate(80deg);
+ transform: rotate(80deg);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+ 40%,
+ 80% {
+ -webkit-transform: rotate(60deg);
+ transform: rotate(60deg);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(0, 700px, 0);
+ transform: translate3d(0, 700px, 0);
+ opacity: 0;
+ }
+}
+@keyframes hinge {
+ 0% {
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+ 20%,
+ 60% {
+ -webkit-transform: rotate(80deg);
+ transform: rotate(80deg);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ }
+ 40%,
+ 80% {
+ -webkit-transform: rotate(60deg);
+ transform: rotate(60deg);
+ -webkit-animation-timing-function: ease-in-out;
+ animation-timing-function: ease-in-out;
+ opacity: 1;
+ }
+ to {
+ -webkit-transform: translate3d(0, 700px, 0);
+ transform: translate3d(0, 700px, 0);
+ opacity: 0;
+ }
+}
+.animate__hinge {
+ -webkit-animation-duration: 2s;
+ animation-duration: 2s;
+ -webkit-animation-duration: calc(var(--animate-duration) * 2);
+ animation-duration: calc(var(--animate-duration) * 2);
+ -webkit-animation-name: hinge;
+ animation-name: hinge;
+ -webkit-transform-origin: top left;
+ transform-origin: top left;
+}
+@-webkit-keyframes jackInTheBox {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.1) rotate(30deg);
+ transform: scale(0.1) rotate(30deg);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ }
+ 50% {
+ -webkit-transform: rotate(-10deg);
+ transform: rotate(-10deg);
+ }
+ 70% {
+ -webkit-transform: rotate(3deg);
+ transform: rotate(3deg);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes jackInTheBox {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.1) rotate(30deg);
+ transform: scale(0.1) rotate(30deg);
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+ }
+ 50% {
+ -webkit-transform: rotate(-10deg);
+ transform: rotate(-10deg);
+ }
+ 70% {
+ -webkit-transform: rotate(3deg);
+ transform: rotate(3deg);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.animate__jackInTheBox {
+ -webkit-animation-name: jackInTheBox;
+ animation-name: jackInTheBox;
+}
+@-webkit-keyframes rollIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0) rotate(-120deg);
+ transform: translate3d(-100%, 0, 0) rotate(-120deg);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes rollIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: translate3d(-100%, 0, 0) rotate(-120deg);
+ transform: translate3d(-100%, 0, 0) rotate(-120deg);
+ }
+ to {
+ opacity: 1;
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__rollIn {
+ -webkit-animation-name: rollIn;
+ animation-name: rollIn;
+}
+@-webkit-keyframes rollOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0) rotate(120deg);
+ transform: translate3d(100%, 0, 0) rotate(120deg);
+ }
+}
+@keyframes rollOut {
+ 0% {
+ opacity: 1;
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: translate3d(100%, 0, 0) rotate(120deg);
+ transform: translate3d(100%, 0, 0) rotate(120deg);
+ }
+}
+.animate__rollOut {
+ -webkit-animation-name: rollOut;
+ animation-name: rollOut;
+}
+@-webkit-keyframes zoomIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ 50% {
+ opacity: 1;
+ }
+}
+@keyframes zoomIn {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ 50% {
+ opacity: 1;
+ }
+}
+.animate__zoomIn {
+ -webkit-animation-name: zoomIn;
+ animation-name: zoomIn;
+}
+@-webkit-keyframes zoomInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomInDown {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomInDown {
+ -webkit-animation-name: zoomInDown;
+ animation-name: zoomInDown;
+}
+@-webkit-keyframes zoomInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomInLeft {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(-1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomInLeft {
+ -webkit-animation-name: zoomInLeft;
+ animation-name: zoomInLeft;
+}
+@-webkit-keyframes zoomInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomInRight {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(1000px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(-10px, 0, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomInRight {
+ -webkit-animation-name: zoomInRight;
+ animation-name: zoomInRight;
+}
+@-webkit-keyframes zoomInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomInUp {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 1000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomInUp {
+ -webkit-animation-name: zoomInUp;
+ animation-name: zoomInUp;
+}
+@-webkit-keyframes zoomOut {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ to {
+ opacity: 0;
+ }
+}
+@keyframes zoomOut {
+ 0% {
+ opacity: 1;
+ }
+ 50% {
+ opacity: 0;
+ -webkit-transform: scale3d(0.3, 0.3, 0.3);
+ transform: scale3d(0.3, 0.3, 0.3);
+ }
+ to {
+ opacity: 0;
+ }
+}
+.animate__zoomOut {
+ -webkit-animation-name: zoomOut;
+ animation-name: zoomOut;
+}
+@-webkit-keyframes zoomOutDown {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomOutDown {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, -60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, 2000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomOutDown {
+ -webkit-animation-name: zoomOutDown;
+ animation-name: zoomOutDown;
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+}
+@-webkit-keyframes zoomOutLeft {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0);
+ transform: scale(0.1) translate3d(-2000px, 0, 0);
+ }
+}
+@keyframes zoomOutLeft {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(42px, 0, 0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale(0.1) translate3d(-2000px, 0, 0);
+ transform: scale(0.1) translate3d(-2000px, 0, 0);
+ }
+}
+.animate__zoomOutLeft {
+ -webkit-animation-name: zoomOutLeft;
+ animation-name: zoomOutLeft;
+ -webkit-transform-origin: left center;
+ transform-origin: left center;
+}
+@-webkit-keyframes zoomOutRight {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale(0.1) translate3d(2000px, 0, 0);
+ transform: scale(0.1) translate3d(2000px, 0, 0);
+ }
+}
+@keyframes zoomOutRight {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(-42px, 0, 0);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale(0.1) translate3d(2000px, 0, 0);
+ transform: scale(0.1) translate3d(2000px, 0, 0);
+ }
+}
+.animate__zoomOutRight {
+ -webkit-animation-name: zoomOutRight;
+ animation-name: zoomOutRight;
+ -webkit-transform-origin: right center;
+ transform-origin: right center;
+}
+@-webkit-keyframes zoomOutUp {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+@keyframes zoomOutUp {
+ 40% {
+ opacity: 1;
+ -webkit-transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ transform: scale3d(0.475, 0.475, 0.475) translate3d(0, 60px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ animation-timing-function: cubic-bezier(0.55, 0.055, 0.675, 0.19);
+ }
+ to {
+ opacity: 0;
+ -webkit-transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+ transform: scale3d(0.1, 0.1, 0.1) translate3d(0, -2000px, 0);
+ -webkit-animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ animation-timing-function: cubic-bezier(0.175, 0.885, 0.32, 1);
+ }
+}
+.animate__zoomOutUp {
+ -webkit-animation-name: zoomOutUp;
+ animation-name: zoomOutUp;
+ -webkit-transform-origin: center bottom;
+ transform-origin: center bottom;
+}
+@-webkit-keyframes slideInDown {
+ 0% {
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes slideInDown {
+ 0% {
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__slideInDown {
+ -webkit-animation-name: slideInDown;
+ animation-name: slideInDown;
+}
+@-webkit-keyframes slideInLeft {
+ 0% {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes slideInLeft {
+ 0% {
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__slideInLeft {
+ -webkit-animation-name: slideInLeft;
+ animation-name: slideInLeft;
+}
+@-webkit-keyframes slideInRight {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes slideInRight {
+ 0% {
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__slideInRight {
+ -webkit-animation-name: slideInRight;
+ animation-name: slideInRight;
+}
+@-webkit-keyframes slideInUp {
+ 0% {
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+@keyframes slideInUp {
+ 0% {
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ visibility: visible;
+ }
+ to {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+}
+.animate__slideInUp {
+ -webkit-animation-name: slideInUp;
+ animation-name: slideInUp;
+}
+@-webkit-keyframes slideOutDown {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+@keyframes slideOutDown {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(0, 100%, 0);
+ transform: translate3d(0, 100%, 0);
+ }
+}
+.animate__slideOutDown {
+ -webkit-animation-name: slideOutDown;
+ animation-name: slideOutDown;
+}
+@-webkit-keyframes slideOutLeft {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+@keyframes slideOutLeft {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(-100%, 0, 0);
+ transform: translate3d(-100%, 0, 0);
+ }
+}
+.animate__slideOutLeft {
+ -webkit-animation-name: slideOutLeft;
+ animation-name: slideOutLeft;
+}
+@-webkit-keyframes slideOutRight {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+@keyframes slideOutRight {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(100%, 0, 0);
+ transform: translate3d(100%, 0, 0);
+ }
+}
+.animate__slideOutRight {
+ -webkit-animation-name: slideOutRight;
+ animation-name: slideOutRight;
+}
+@-webkit-keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+@keyframes slideOutUp {
+ 0% {
+ -webkit-transform: translateZ(0);
+ transform: translateZ(0);
+ }
+ to {
+ visibility: hidden;
+ -webkit-transform: translate3d(0, -100%, 0);
+ transform: translate3d(0, -100%, 0);
+ }
+}
+.animate__slideOutUp {
+ -webkit-animation-name: slideOutUp;
+ animation-name: slideOutUp;
+}
+.ui-helper-hidden {
+ display: none;
+}
+.ui-helper-hidden-accessible {
+ border: 0;
+ clip: rect(0 0 0 0);
+ height: 1px;
+ margin: -1px;
+ overflow: hidden;
+ padding: 0;
+ position: absolute;
+ width: 1px;
+}
+.ui-helper-reset {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ outline: 0;
+ line-height: 1.3;
+ text-decoration: none;
+ font-size: 100%;
+ list-style: none;
+}
+.ui-helper-clearfix:after,
+.ui-helper-clearfix:before {
+ content: '';
+ display: table;
+ border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+ clear: both;
+}
+.ui-helper-zfix {
+ width: 100%;
+ height: 100%;
+ top: 0;
+ left: 0;
+ position: absolute;
+ opacity: 0;
+ filter: Alpha(Opacity=0);
+}
+.ui-front {
+ z-index: 100;
+}
+.ui-state-disabled {
+ cursor: default !important;
+ pointer-events: none;
+}
+.ui-icon {
+ display: inline-block;
+ vertical-align: middle;
+ margin-top: -0.25em;
+ position: relative;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+}
+.ui-widget-icon-block {
+ left: 50%;
+ margin-left: -8px;
+ display: block;
+}
+.ui-widget-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+.ui-accordion .ui-accordion-header {
+ display: block;
+ cursor: pointer;
+ position: relative;
+ margin: 2px 0 0 0;
+ padding: 0.5em 0.5em 0.5em 0.7em;
+ font-size: 100%;
+}
+.ui-accordion .ui-accordion-content {
+ padding: 1em 2.2em;
+ border-top: 0;
+ overflow: auto;
+}
+.ui-autocomplete {
+ position: absolute;
+ top: 0;
+ left: 0;
+ cursor: default;
+}
+.ui-menu {
+ list-style: none;
+ padding: 0;
+ margin: 0;
+ display: block;
+ outline: 0;
+}
+.ui-menu .ui-menu {
+ position: absolute;
+}
+.ui-menu .ui-menu-item {
+ margin: 0;
+ cursor: pointer;
+ list-style-image: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+}
+.ui-menu .ui-menu-item-wrapper {
+ position: relative;
+ padding: 3px 1em 3px 0.4em;
+}
+.ui-menu .ui-menu-divider {
+ margin: 5px 0;
+ height: 0;
+ font-size: 0;
+ line-height: 0;
+ border-width: 1px 0 0 0;
+}
+.ui-menu .ui-state-active,
+.ui-menu .ui-state-focus {
+ margin: -1px;
+}
+.ui-menu-icons {
+ position: relative;
+}
+.ui-menu-icons .ui-menu-item-wrapper {
+ padding-left: 2em;
+}
+.ui-menu .ui-icon {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 0.2em;
+ margin: auto 0;
+}
+.ui-menu .ui-menu-icon {
+ left: auto;
+ right: 0;
+}
+.ui-button {
+ padding: 0.4em 1em;
+ display: inline-block;
+ position: relative;
+ line-height: normal;
+ margin-right: 0.1em;
+ cursor: pointer;
+ vertical-align: middle;
+ text-align: center;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ overflow: visible;
+}
+.ui-button,
+.ui-button:active,
+.ui-button:hover,
+.ui-button:link,
+.ui-button:visited {
+ text-decoration: none;
+}
+.ui-button-icon-only {
+ width: 2em;
+ box-sizing: border-box;
+ text-indent: -9999px;
+ white-space: nowrap;
+}
+input.ui-button.ui-button-icon-only {
+ text-indent: 0;
+}
+.ui-button-icon-only .ui-icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ margin-top: -8px;
+ margin-left: -8px;
+}
+.ui-button.ui-icon-notext .ui-icon {
+ padding: 0;
+ width: 2.1em;
+ height: 2.1em;
+ text-indent: -9999px;
+ white-space: nowrap;
+}
+input.ui-button.ui-icon-notext .ui-icon {
+ width: auto;
+ height: auto;
+ text-indent: 0;
+ white-space: normal;
+ padding: 0.4em 1em;
+}
+button.ui-button::-moz-focus-inner,
+input.ui-button::-moz-focus-inner {
+ border: 0;
+ padding: 0;
+}
+.ui-controlgroup {
+ vertical-align: middle;
+ display: inline-block;
+}
+.ui-controlgroup > .ui-controlgroup-item {
+ float: left;
+ margin-left: 0;
+ margin-right: 0;
+}
+.ui-controlgroup > .ui-controlgroup-item.ui-visual-focus,
+.ui-controlgroup > .ui-controlgroup-item:focus {
+ z-index: 9999;
+}
+.ui-controlgroup-vertical > .ui-controlgroup-item {
+ display: block;
+ float: none;
+ width: 100%;
+ margin-top: 0;
+ margin-bottom: 0;
+ text-align: left;
+}
+.ui-controlgroup-vertical .ui-controlgroup-item {
+ box-sizing: border-box;
+}
+.ui-controlgroup .ui-controlgroup-label {
+ padding: 0.4em 1em;
+}
+.ui-controlgroup .ui-controlgroup-label span {
+ font-size: 80%;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label + .ui-controlgroup-item {
+ border-left: none;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label + .ui-controlgroup-item {
+ border-top: 0;
+}
+.ui-controlgroup-horizontal .ui-controlgroup-label.ui-widget-content {
+ border-right: 0;
+}
+.ui-controlgroup-vertical .ui-controlgroup-label.ui-widget-content {
+ border-bottom: 0;
+}
+.ui-controlgroup-vertical .ui-spinner-input {
+ width: 75%;
+ width: calc(100% - 2.4em);
+}
+.ui-controlgroup-vertical .ui-spinner .ui-spinner-up {
+ border-top-style: solid;
+}
+.ui-checkboxradio-label .ui-icon-background {
+ box-shadow: inset 1px 1px 1px #fff;
+ border-radius: 0.12em;
+ border: 0;
+}
+.ui-checkboxradio-radio-label .ui-icon-background {
+ width: 16px;
+ height: 16px;
+ border-radius: 1em;
+ overflow: visible;
+ border: 0;
+}
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked .ui-icon,
+.ui-checkboxradio-radio-label.ui-checkboxradio-checked:hover .ui-icon {
+ background-image: none;
+ width: 8px;
+ height: 8px;
+ border-width: 4px;
+ border-style: solid;
+}
+.ui-checkboxradio-disabled {
+ pointer-events: none;
+}
+.ui-datepicker {
+ width: 17em;
+ padding: 0.2em 0.2em 0;
+ display: none;
+}
+.ui-datepicker .ui-datepicker-header {
+ position: relative;
+ padding: 0.2em 0;
+}
+.ui-datepicker .ui-datepicker-next,
+.ui-datepicker .ui-datepicker-prev {
+ position: absolute;
+ top: 2px;
+ width: 1.8em;
+ height: 1.8em;
+}
+.ui-datepicker .ui-datepicker-next-hover,
+.ui-datepicker .ui-datepicker-prev-hover {
+ top: 1px;
+}
+.ui-datepicker .ui-datepicker-prev {
+ left: 2px;
+}
+.ui-datepicker .ui-datepicker-next {
+ right: 2px;
+}
+.ui-datepicker .ui-datepicker-prev-hover {
+ left: 1px;
+}
+.ui-datepicker .ui-datepicker-next-hover {
+ right: 1px;
+}
+.ui-datepicker .ui-datepicker-next span,
+.ui-datepicker .ui-datepicker-prev span {
+ display: block;
+ position: absolute;
+ left: 50%;
+ margin-left: -8px;
+ top: 50%;
+ margin-top: -8px;
+}
+.ui-datepicker .ui-datepicker-title {
+ margin: 0 2.3em;
+ line-height: 1.8em;
+ text-align: center;
+}
+.ui-datepicker .ui-datepicker-title select {
+ font-size: 1em;
+ margin: 1px 0;
+}
+.ui-datepicker select.ui-datepicker-month,
+.ui-datepicker select.ui-datepicker-year {
+ width: 45%;
+}
+.ui-datepicker table {
+ width: 100%;
+ font-size: 0.9em;
+ border-collapse: collapse;
+ margin: 0 0 0.4em;
+}
+.ui-datepicker th {
+ padding: 0.7em 0.3em;
+ text-align: center;
+ font-weight: 700;
+ border: 0;
+}
+.ui-datepicker td {
+ border: 0;
+ padding: 1px;
+}
+.ui-datepicker td a,
+.ui-datepicker td span {
+ display: block;
+ padding: 0.2em;
+ text-align: right;
+ text-decoration: none;
+}
+.ui-datepicker .ui-datepicker-buttonpane {
+ background-image: none;
+ margin: 0.7em 0 0 0;
+ padding: 0 0.2em;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 0;
+}
+.ui-datepicker .ui-datepicker-buttonpane button {
+ float: right;
+ margin: 0.5em 0.2em 0.4em;
+ cursor: pointer;
+ padding: 0.2em 0.6em 0.3em 0.6em;
+ width: auto;
+ overflow: visible;
+}
+.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current {
+ float: left;
+}
+.ui-datepicker.ui-datepicker-multi {
+ width: auto;
+}
+.ui-datepicker-multi .ui-datepicker-group {
+ float: left;
+}
+.ui-datepicker-multi .ui-datepicker-group table {
+ width: 95%;
+ margin: 0 auto 0.4em;
+}
+.ui-datepicker-multi-2 .ui-datepicker-group {
+ width: 50%;
+}
+.ui-datepicker-multi-3 .ui-datepicker-group {
+ width: 33.3%;
+}
+.ui-datepicker-multi-4 .ui-datepicker-group {
+ width: 25%;
+}
+.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header {
+ border-left-width: 0;
+}
+.ui-datepicker-multi .ui-datepicker-buttonpane {
+ clear: left;
+}
+.ui-datepicker-row-break {
+ clear: both;
+ width: 100%;
+ font-size: 0;
+}
+.ui-datepicker-rtl {
+ direction: rtl;
+}
+.ui-datepicker-rtl .ui-datepicker-prev {
+ right: 2px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next {
+ left: 2px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-prev:hover {
+ right: 1px;
+ left: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-next:hover {
+ left: 1px;
+ right: auto;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane {
+ clear: right;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button {
+ float: left;
+}
+.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,
+.ui-datepicker-rtl .ui-datepicker-group {
+ float: right;
+}
+.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,
+.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header {
+ border-right-width: 0;
+ border-left-width: 1px;
+}
+.ui-datepicker .ui-icon {
+ display: block;
+ text-indent: -99999px;
+ overflow: hidden;
+ background-repeat: no-repeat;
+ left: 0.5em;
+ top: 0.3em;
+}
+.ui-dialog {
+ position: absolute;
+ top: 0;
+ left: 0;
+ padding: 0.2em;
+ outline: 0;
+}
+.ui-dialog .ui-dialog-titlebar {
+ padding: 0.4em 1em;
+ position: relative;
+}
+.ui-dialog .ui-dialog-title {
+ float: left;
+ margin: 0.1em 0;
+ white-space: nowrap;
+ width: 90%;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.ui-dialog .ui-dialog-titlebar-close {
+ position: absolute;
+ right: 0.3em;
+ top: 50%;
+ width: 20px;
+ margin: -10px 0 0 0;
+ padding: 1px;
+ height: 20px;
+}
+.ui-dialog .ui-dialog-content {
+ position: relative;
+ border: 0;
+ padding: 0.5em 1em;
+ background: 0;
+ overflow: auto;
+}
+.ui-dialog .ui-dialog-buttonpane {
+ text-align: left;
+ border-width: 1px 0 0 0;
+ background-image: none;
+ margin-top: 0.5em;
+ padding: 0.3em 1em 0.5em 0.4em;
+}
+.ui-dialog .ui-dialog-buttonpane .ui-dialog-buttonset {
+ float: right;
+}
+.ui-dialog .ui-dialog-buttonpane button {
+ margin: 0.5em 0.4em 0.5em 0;
+ cursor: pointer;
+}
+.ui-dialog .ui-resizable-n {
+ height: 2px;
+ top: 0;
+}
+.ui-dialog .ui-resizable-e {
+ width: 2px;
+ right: 0;
+}
+.ui-dialog .ui-resizable-s {
+ height: 2px;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-w {
+ width: 2px;
+ left: 0;
+}
+.ui-dialog .ui-resizable-ne,
+.ui-dialog .ui-resizable-nw,
+.ui-dialog .ui-resizable-se,
+.ui-dialog .ui-resizable-sw {
+ width: 7px;
+ height: 7px;
+}
+.ui-dialog .ui-resizable-se {
+ right: 0;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-sw {
+ left: 0;
+ bottom: 0;
+}
+.ui-dialog .ui-resizable-ne {
+ right: 0;
+ top: 0;
+}
+.ui-dialog .ui-resizable-nw {
+ left: 0;
+ top: 0;
+}
+.ui-draggable .ui-dialog-titlebar {
+ cursor: move;
+}
+.ui-draggable-handle {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-resizable {
+ position: relative;
+}
+.ui-resizable-handle {
+ position: absolute;
+ font-size: 0.1px;
+ display: block;
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-resizable-autohide .ui-resizable-handle,
+.ui-resizable-disabled .ui-resizable-handle {
+ display: none;
+}
+.ui-resizable-n {
+ cursor: n-resize;
+ height: 7px;
+ width: 100%;
+ top: -5px;
+ left: 0;
+}
+.ui-resizable-s {
+ cursor: s-resize;
+ height: 7px;
+ width: 100%;
+ bottom: -5px;
+ left: 0;
+}
+.ui-resizable-e {
+ cursor: e-resize;
+ width: 7px;
+ right: -5px;
+ top: 0;
+ height: 100%;
+}
+.ui-resizable-w {
+ cursor: w-resize;
+ width: 7px;
+ left: -5px;
+ top: 0;
+ height: 100%;
+}
+.ui-resizable-se {
+ cursor: se-resize;
+ width: 12px;
+ height: 12px;
+ right: 1px;
+ bottom: 1px;
+}
+.ui-resizable-sw {
+ cursor: sw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ bottom: -5px;
+}
+.ui-resizable-nw {
+ cursor: nw-resize;
+ width: 9px;
+ height: 9px;
+ left: -5px;
+ top: -5px;
+}
+.ui-resizable-ne {
+ cursor: ne-resize;
+ width: 9px;
+ height: 9px;
+ right: -5px;
+ top: -5px;
+}
+.ui-progressbar {
+ height: 2em;
+ text-align: left;
+ overflow: hidden;
+}
+.ui-progressbar .ui-progressbar-value {
+ margin: -1px;
+ height: 100%;
+}
+.ui-progressbar .ui-progressbar-overlay {
+ background: url(data:image/gif;base64,R0lGODlhKAAoAIABAAAAAP///yH/C05FVFNDQVBFMi4wAwEAAAAh+QQJAQABACwAAAAAKAAoAAACkYwNqXrdC52DS06a7MFZI+4FHBCKoDeWKXqymPqGqxvJrXZbMx7Ttc+w9XgU2FB3lOyQRWET2IFGiU9m1frDVpxZZc6bfHwv4c1YXP6k1Vdy292Fb6UkuvFtXpvWSzA+HycXJHUXiGYIiMg2R6W459gnWGfHNdjIqDWVqemH2ekpObkpOlppWUqZiqr6edqqWQAAIfkECQEAAQAsAAAAACgAKAAAApSMgZnGfaqcg1E2uuzDmmHUBR8Qil95hiPKqWn3aqtLsS18y7G1SzNeowWBENtQd+T1JktP05nzPTdJZlR6vUxNWWjV+vUWhWNkWFwxl9VpZRedYcflIOLafaa28XdsH/ynlcc1uPVDZxQIR0K25+cICCmoqCe5mGhZOfeYSUh5yJcJyrkZWWpaR8doJ2o4NYq62lAAACH5BAkBAAEALAAAAAAoACgAAAKVDI4Yy22ZnINRNqosw0Bv7i1gyHUkFj7oSaWlu3ovC8GxNso5fluz3qLVhBVeT/Lz7ZTHyxL5dDalQWPVOsQWtRnuwXaFTj9jVVh8pma9JjZ4zYSj5ZOyma7uuolffh+IR5aW97cHuBUXKGKXlKjn+DiHWMcYJah4N0lYCMlJOXipGRr5qdgoSTrqWSq6WFl2ypoaUAAAIfkECQEAAQAsAAAAACgAKAAAApaEb6HLgd/iO7FNWtcFWe+ufODGjRfoiJ2akShbueb0wtI50zm02pbvwfWEMWBQ1zKGlLIhskiEPm9R6vRXxV4ZzWT2yHOGpWMyorblKlNp8HmHEb/lCXjcW7bmtXP8Xt229OVWR1fod2eWqNfHuMjXCPkIGNileOiImVmCOEmoSfn3yXlJWmoHGhqp6ilYuWYpmTqKUgAAIfkECQEAAQAsAAAAACgAKAAAApiEH6kb58biQ3FNWtMFWW3eNVcojuFGfqnZqSebuS06w5V80/X02pKe8zFwP6EFWOT1lDFk8rGERh1TTNOocQ61Hm4Xm2VexUHpzjymViHrFbiELsefVrn6XKfnt2Q9G/+Xdie499XHd2g4h7ioOGhXGJboGAnXSBnoBwKYyfioubZJ2Hn0RuRZaflZOil56Zp6iioKSXpUAAAh+QQJAQABACwAAAAAKAAoAAACkoQRqRvnxuI7kU1a1UU5bd5tnSeOZXhmn5lWK3qNTWvRdQxP8qvaC+/yaYQzXO7BMvaUEmJRd3TsiMAgswmNYrSgZdYrTX6tSHGZO73ezuAw2uxuQ+BbeZfMxsexY35+/Qe4J1inV0g4x3WHuMhIl2jXOKT2Q+VU5fgoSUI52VfZyfkJGkha6jmY+aaYdirq+lQAACH5BAkBAAEALAAAAAAoACgAAAKWBIKpYe0L3YNKToqswUlvznigd4wiR4KhZrKt9Upqip61i9E3vMvxRdHlbEFiEXfk9YARYxOZZD6VQ2pUunBmtRXo1Lf8hMVVcNl8JafV38aM2/Fu5V16Bn63r6xt97j09+MXSFi4BniGFae3hzbH9+hYBzkpuUh5aZmHuanZOZgIuvbGiNeomCnaxxap2upaCZsq+1kAACH5BAkBAAEALAAAAAAoACgAAAKXjI8By5zf4kOxTVrXNVlv1X0d8IGZGKLnNpYtm8Lr9cqVeuOSvfOW79D9aDHizNhDJidFZhNydEahOaDH6nomtJjp1tutKoNWkvA6JqfRVLHU/QUfau9l2x7G54d1fl995xcIGAdXqMfBNadoYrhH+Mg2KBlpVpbluCiXmMnZ2Sh4GBqJ+ckIOqqJ6LmKSllZmsoq6wpQAAAh+QQJAQABACwAAAAAKAAoAAAClYx/oLvoxuJDkU1a1YUZbJ59nSd2ZXhWqbRa2/gF8Gu2DY3iqs7yrq+xBYEkYvFSM8aSSObE+ZgRl1BHFZNr7pRCavZ5BW2142hY3AN/zWtsmf12p9XxxFl2lpLn1rseztfXZjdIWIf2s5dItwjYKBgo9yg5pHgzJXTEeGlZuenpyPmpGQoKOWkYmSpaSnqKileI2FAAACH5BAkBAAEALAAAAAAoACgAAAKVjB+gu+jG4kORTVrVhRlsnn2dJ3ZleFaptFrb+CXmO9OozeL5VfP99HvAWhpiUdcwkpBH3825AwYdU8xTqlLGhtCosArKMpvfa1mMRae9VvWZfeB2XfPkeLmm18lUcBj+p5dnN8jXZ3YIGEhYuOUn45aoCDkp16hl5IjYJvjWKcnoGQpqyPlpOhr3aElaqrq56Bq7VAAAOw==);
+ height: 100%;
+ opacity: 0.25;
+}
+.ui-progressbar-indeterminate .ui-progressbar-value {
+ background-image: none;
+}
+.ui-selectable {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-selectable-helper {
+ position: absolute;
+ z-index: 100;
+ border: 1px dotted #000;
+}
+.ui-selectmenu-menu {
+ padding: 0;
+ margin: 0;
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: none;
+}
+.ui-selectmenu-menu .ui-menu {
+ overflow: auto;
+ overflow-x: hidden;
+ padding-bottom: 1px;
+}
+.ui-selectmenu-menu .ui-menu .ui-selectmenu-optgroup {
+ font-size: 1em;
+ font-weight: 700;
+ line-height: 1.5;
+ padding: 2px 0.4em;
+ margin: 0.5em 0 0 0;
+ height: auto;
+ border: 0;
+}
+.ui-selectmenu-open {
+ display: block;
+}
+.ui-selectmenu-text {
+ display: block;
+ margin-right: 20px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+.ui-selectmenu-button.ui-button {
+ text-align: left;
+ white-space: nowrap;
+ width: 14em;
+}
+.ui-selectmenu-icon.ui-icon {
+ float: right;
+ margin-top: 0;
+}
+.ui-slider {
+ position: relative;
+ text-align: left;
+}
+.ui-slider .ui-slider-handle {
+ position: absolute;
+ z-index: 2;
+ width: 1.2em;
+ height: 1.2em;
+ cursor: default;
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-slider .ui-slider-range {
+ position: absolute;
+ z-index: 1;
+ font-size: 0.7em;
+ display: block;
+ border: 0;
+ background-position: 0 0;
+}
+.ui-slider.ui-state-disabled .ui-slider-handle,
+.ui-slider.ui-state-disabled .ui-slider-range {
+ filter: inherit;
+}
+.ui-slider-horizontal {
+ height: 0.8em;
+}
+.ui-slider-horizontal .ui-slider-handle {
+ top: -0.3em;
+ margin-left: -0.6em;
+}
+.ui-slider-horizontal .ui-slider-range {
+ top: 0;
+ height: 100%;
+}
+.ui-slider-horizontal .ui-slider-range-min {
+ left: 0;
+}
+.ui-slider-horizontal .ui-slider-range-max {
+ right: 0;
+}
+.ui-slider-vertical {
+ width: 0.8em;
+ height: 100px;
+}
+.ui-slider-vertical .ui-slider-handle {
+ left: -0.3em;
+ margin-left: 0;
+ margin-bottom: -0.6em;
+}
+.ui-slider-vertical .ui-slider-range {
+ left: 0;
+ width: 100%;
+}
+.ui-slider-vertical .ui-slider-range-min {
+ bottom: 0;
+}
+.ui-slider-vertical .ui-slider-range-max {
+ top: 0;
+}
+.ui-sortable-handle {
+ -ms-touch-action: none;
+ touch-action: none;
+}
+.ui-spinner {
+ position: relative;
+ display: inline-block;
+ overflow: hidden;
+ padding: 0;
+ vertical-align: middle;
+}
+.ui-spinner-input {
+ border: 0;
+ background: 0;
+ color: inherit;
+ padding: 0.222em 0;
+ margin: 0.2em 0;
+ vertical-align: middle;
+ margin-left: 0.4em;
+ margin-right: 2em;
+}
+.ui-spinner-button {
+ width: 1.6em;
+ height: 50%;
+ font-size: 0.5em;
+ padding: 0;
+ margin: 0;
+ text-align: center;
+ position: absolute;
+ cursor: default;
+ display: block;
+ overflow: hidden;
+ right: 0;
+}
+.ui-spinner a.ui-spinner-button {
+ border-top-style: none;
+ border-bottom-style: none;
+ border-right-style: none;
+}
+.ui-spinner-up {
+ top: 0;
+}
+.ui-spinner-down {
+ bottom: 0;
+}
+.ui-tabs {
+ position: relative;
+ padding: 0.2em;
+}
+.ui-tabs .ui-tabs-nav {
+ margin: 0;
+ padding: 0.2em 0.2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+ list-style: none;
+ float: left;
+ position: relative;
+ top: 0;
+ margin: 1px 0.2em 0 0;
+ border-bottom-width: 0;
+ padding: 0;
+ white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav .ui-tabs-anchor {
+ float: left;
+ padding: 0.5em 1em;
+ text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+ margin-bottom: -1px;
+ padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-state-disabled .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading .ui-tabs-anchor {
+ cursor: text;
+}
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active .ui-tabs-anchor {
+ cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+ display: block;
+ border-width: 0;
+ padding: 1em 1.4em;
+ background: 0;
+}
+.ui-tooltip {
+ padding: 8px;
+ position: absolute;
+ z-index: 9999;
+ max-width: 300px;
+}
+body .ui-tooltip {
+ border-width: 2px;
+}
+.ui-widget {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 1em;
+}
+.ui-widget .ui-widget {
+ font-size: 1em;
+}
+.ui-widget button,
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 1em;
+}
+.ui-widget.ui-widget-content {
+ border: 1px solid #c5c5c5;
+}
+.ui-widget-content {
+ border: 1px solid #ddd;
+ background: #fff;
+ color: #333;
+}
+.ui-widget-content a {
+ color: #333;
+}
+.ui-widget-header {
+ border: 1px solid #ddd;
+ background: #e9e9e9;
+ color: #333;
+ font-weight: 700;
+}
+.ui-widget-header a {
+ color: #333;
+}
+.ui-button,
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default,
+html .ui-button.ui-state-disabled:active,
+html .ui-button.ui-state-disabled:hover {
+ border: 1px solid #c5c5c5;
+ background: #f6f6f6;
+ font-weight: 400;
+ color: #454545;
+}
+.ui-button,
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited,
+a.ui-button,
+a:link.ui-button,
+a:visited.ui-button {
+ color: #454545;
+ text-decoration: none;
+}
+.ui-button:focus,
+.ui-button:hover,
+.ui-state-focus,
+.ui-state-hover,
+.ui-widget-content .ui-state-focus,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-focus,
+.ui-widget-header .ui-state-hover {
+ border: 1px solid #fff;
+ background: #ededed;
+ font-weight: 400;
+ color: #2b2b2b;
+}
+.ui-state-focus a,
+.ui-state-focus a:hover,
+.ui-state-focus a:link,
+.ui-state-focus a:visited,
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited,
+a.ui-button:focus,
+a.ui-button:hover {
+ color: #2b2b2b;
+ text-decoration: none;
+}
+.ui-visual-focus {
+ box-shadow: 0 0 3px 1px #5e9ed6;
+}
+.ui-button.ui-state-active:hover,
+.ui-button:active,
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active,
+a.ui-button:active {
+ border: 1px solid #003eff;
+ background: #007fff;
+ font-weight: 400;
+ color: #fff;
+}
+.ui-icon-background,
+.ui-state-active .ui-icon-background {
+ border: #003eff;
+ background-color: #fff;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+ color: #fff;
+ text-decoration: none;
+}
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+ border: 1px solid #dad55e;
+ background: #fffa90;
+ color: #777620;
+}
+.ui-state-checked {
+ border: 1px solid #dad55e;
+ background: #fffa90;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+ color: #777620;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+ border: 1px solid #f1a899;
+ background: #fddfdf;
+ color: #5f3f3f;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+ color: #5f3f3f;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+ color: #5f3f3f;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+ font-weight: 700;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+ opacity: 0.7;
+ filter: Alpha(Opacity=70);
+ font-weight: 400;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+ opacity: 0.35;
+ filter: Alpha(Opacity=35);
+ background-image: none;
+}
+.ui-state-disabled .ui-icon {
+ filter: Alpha(Opacity=35);
+}
+.ui-icon {
+ width: 16px;
+ height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+ background-image: url(images/ui-icons_444444_256x240.png);
+}
+.ui-widget-header .ui-icon {
+ background-image: url(images/ui-icons_444444_256x240.png);
+}
+.ui-button:focus .ui-icon,
+.ui-button:hover .ui-icon,
+.ui-state-focus .ui-icon,
+.ui-state-hover .ui-icon {
+ background-image: url(images/ui-icons_555555_256x240.png);
+}
+.ui-button:active .ui-icon,
+.ui-state-active .ui-icon {
+ background-image: url(images/ui-icons_ffffff_256x240.png);
+}
+.ui-button .ui-state-highlight.ui-icon,
+.ui-state-highlight .ui-icon {
+ background-image: url(images/ui-icons_777620_256x240.png);
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+ background-image: url(images/ui-icons_cc0000_256x240.png);
+}
+.ui-button .ui-icon {
+ background-image: url(images/ui-icons_777777_256x240.png);
+}
+.ui-icon-blank {
+ background-position: 16px 16px;
+}
+.ui-icon-caret-1-n {
+ background-position: 0 0;
+}
+.ui-icon-caret-1-ne {
+ background-position: -16px 0;
+}
+.ui-icon-caret-1-e {
+ background-position: -32px 0;
+}
+.ui-icon-caret-1-se {
+ background-position: -48px 0;
+}
+.ui-icon-caret-1-s {
+ background-position: -65px 0;
+}
+.ui-icon-caret-1-sw {
+ background-position: -80px 0;
+}
+.ui-icon-caret-1-w {
+ background-position: -96px 0;
+}
+.ui-icon-caret-1-nw {
+ background-position: -112px 0;
+}
+.ui-icon-caret-2-n-s {
+ background-position: -128px 0;
+}
+.ui-icon-caret-2-e-w {
+ background-position: -144px 0;
+}
+.ui-icon-triangle-1-n {
+ background-position: 0 -16px;
+}
+.ui-icon-triangle-1-ne {
+ background-position: -16px -16px;
+}
+.ui-icon-triangle-1-e {
+ background-position: -32px -16px;
+}
+.ui-icon-triangle-1-se {
+ background-position: -48px -16px;
+}
+.ui-icon-triangle-1-s {
+ background-position: -65px -16px;
+}
+.ui-icon-triangle-1-sw {
+ background-position: -80px -16px;
+}
+.ui-icon-triangle-1-w {
+ background-position: -96px -16px;
+}
+.ui-icon-triangle-1-nw {
+ background-position: -112px -16px;
+}
+.ui-icon-triangle-2-n-s {
+ background-position: -128px -16px;
+}
+.ui-icon-triangle-2-e-w {
+ background-position: -144px -16px;
+}
+.ui-icon-arrow-1-n {
+ background-position: 0 -32px;
+}
+.ui-icon-arrow-1-ne {
+ background-position: -16px -32px;
+}
+.ui-icon-arrow-1-e {
+ background-position: -32px -32px;
+}
+.ui-icon-arrow-1-se {
+ background-position: -48px -32px;
+}
+.ui-icon-arrow-1-s {
+ background-position: -65px -32px;
+}
+.ui-icon-arrow-1-sw {
+ background-position: -80px -32px;
+}
+.ui-icon-arrow-1-w {
+ background-position: -96px -32px;
+}
+.ui-icon-arrow-1-nw {
+ background-position: -112px -32px;
+}
+.ui-icon-arrow-2-n-s {
+ background-position: -128px -32px;
+}
+.ui-icon-arrow-2-ne-sw {
+ background-position: -144px -32px;
+}
+.ui-icon-arrow-2-e-w {
+ background-position: -160px -32px;
+}
+.ui-icon-arrow-2-se-nw {
+ background-position: -176px -32px;
+}
+.ui-icon-arrowstop-1-n {
+ background-position: -192px -32px;
+}
+.ui-icon-arrowstop-1-e {
+ background-position: -208px -32px;
+}
+.ui-icon-arrowstop-1-s {
+ background-position: -224px -32px;
+}
+.ui-icon-arrowstop-1-w {
+ background-position: -240px -32px;
+}
+.ui-icon-arrowthick-1-n {
+ background-position: 1px -48px;
+}
+.ui-icon-arrowthick-1-ne {
+ background-position: -16px -48px;
+}
+.ui-icon-arrowthick-1-e {
+ background-position: -32px -48px;
+}
+.ui-icon-arrowthick-1-se {
+ background-position: -48px -48px;
+}
+.ui-icon-arrowthick-1-s {
+ background-position: -64px -48px;
+}
+.ui-icon-arrowthick-1-sw {
+ background-position: -80px -48px;
+}
+.ui-icon-arrowthick-1-w {
+ background-position: -96px -48px;
+}
+.ui-icon-arrowthick-1-nw {
+ background-position: -112px -48px;
+}
+.ui-icon-arrowthick-2-n-s {
+ background-position: -128px -48px;
+}
+.ui-icon-arrowthick-2-ne-sw {
+ background-position: -144px -48px;
+}
+.ui-icon-arrowthick-2-e-w {
+ background-position: -160px -48px;
+}
+.ui-icon-arrowthick-2-se-nw {
+ background-position: -176px -48px;
+}
+.ui-icon-arrowthickstop-1-n {
+ background-position: -192px -48px;
+}
+.ui-icon-arrowthickstop-1-e {
+ background-position: -208px -48px;
+}
+.ui-icon-arrowthickstop-1-s {
+ background-position: -224px -48px;
+}
+.ui-icon-arrowthickstop-1-w {
+ background-position: -240px -48px;
+}
+.ui-icon-arrowreturnthick-1-w {
+ background-position: 0 -64px;
+}
+.ui-icon-arrowreturnthick-1-n {
+ background-position: -16px -64px;
+}
+.ui-icon-arrowreturnthick-1-e {
+ background-position: -32px -64px;
+}
+.ui-icon-arrowreturnthick-1-s {
+ background-position: -48px -64px;
+}
+.ui-icon-arrowreturn-1-w {
+ background-position: -64px -64px;
+}
+.ui-icon-arrowreturn-1-n {
+ background-position: -80px -64px;
+}
+.ui-icon-arrowreturn-1-e {
+ background-position: -96px -64px;
+}
+.ui-icon-arrowreturn-1-s {
+ background-position: -112px -64px;
+}
+.ui-icon-arrowrefresh-1-w {
+ background-position: -128px -64px;
+}
+.ui-icon-arrowrefresh-1-n {
+ background-position: -144px -64px;
+}
+.ui-icon-arrowrefresh-1-e {
+ background-position: -160px -64px;
+}
+.ui-icon-arrowrefresh-1-s {
+ background-position: -176px -64px;
+}
+.ui-icon-arrow-4 {
+ background-position: 0 -80px;
+}
+.ui-icon-arrow-4-diag {
+ background-position: -16px -80px;
+}
+.ui-icon-extlink {
+ background-position: -32px -80px;
+}
+.ui-icon-newwin {
+ background-position: -48px -80px;
+}
+.ui-icon-refresh {
+ background-position: -64px -80px;
+}
+.ui-icon-shuffle {
+ background-position: -80px -80px;
+}
+.ui-icon-transfer-e-w {
+ background-position: -96px -80px;
+}
+.ui-icon-transferthick-e-w {
+ background-position: -112px -80px;
+}
+.ui-icon-folder-collapsed {
+ background-position: 0 -96px;
+}
+.ui-icon-folder-open {
+ background-position: -16px -96px;
+}
+.ui-icon-document {
+ background-position: -32px -96px;
+}
+.ui-icon-document-b {
+ background-position: -48px -96px;
+}
+.ui-icon-note {
+ background-position: -64px -96px;
+}
+.ui-icon-mail-closed {
+ background-position: -80px -96px;
+}
+.ui-icon-mail-open {
+ background-position: -96px -96px;
+}
+.ui-icon-suitcase {
+ background-position: -112px -96px;
+}
+.ui-icon-comment {
+ background-position: -128px -96px;
+}
+.ui-icon-person {
+ background-position: -144px -96px;
+}
+.ui-icon-print {
+ background-position: -160px -96px;
+}
+.ui-icon-trash {
+ background-position: -176px -96px;
+}
+.ui-icon-locked {
+ background-position: -192px -96px;
+}
+.ui-icon-unlocked {
+ background-position: -208px -96px;
+}
+.ui-icon-bookmark {
+ background-position: -224px -96px;
+}
+.ui-icon-tag {
+ background-position: -240px -96px;
+}
+.ui-icon-home {
+ background-position: 0 -112px;
+}
+.ui-icon-flag {
+ background-position: -16px -112px;
+}
+.ui-icon-calendar {
+ background-position: -32px -112px;
+}
+.ui-icon-cart {
+ background-position: -48px -112px;
+}
+.ui-icon-pencil {
+ background-position: -64px -112px;
+}
+.ui-icon-clock {
+ background-position: -80px -112px;
+}
+.ui-icon-disk {
+ background-position: -96px -112px;
+}
+.ui-icon-calculator {
+ background-position: -112px -112px;
+}
+.ui-icon-zoomin {
+ background-position: -128px -112px;
+}
+.ui-icon-zoomout {
+ background-position: -144px -112px;
+}
+.ui-icon-search {
+ background-position: -160px -112px;
+}
+.ui-icon-wrench {
+ background-position: -176px -112px;
+}
+.ui-icon-gear {
+ background-position: -192px -112px;
+}
+.ui-icon-heart {
+ background-position: -208px -112px;
+}
+.ui-icon-star {
+ background-position: -224px -112px;
+}
+.ui-icon-link {
+ background-position: -240px -112px;
+}
+.ui-icon-cancel {
+ background-position: 0 -128px;
+}
+.ui-icon-plus {
+ background-position: -16px -128px;
+}
+.ui-icon-plusthick {
+ background-position: -32px -128px;
+}
+.ui-icon-minus {
+ background-position: -48px -128px;
+}
+.ui-icon-minusthick {
+ background-position: -64px -128px;
+}
+.ui-icon-close {
+ background-position: -80px -128px;
+}
+.ui-icon-closethick {
+ background-position: -96px -128px;
+}
+.ui-icon-key {
+ background-position: -112px -128px;
+}
+.ui-icon-lightbulb {
+ background-position: -128px -128px;
+}
+.ui-icon-scissors {
+ background-position: -144px -128px;
+}
+.ui-icon-clipboard {
+ background-position: -160px -128px;
+}
+.ui-icon-copy {
+ background-position: -176px -128px;
+}
+.ui-icon-contact {
+ background-position: -192px -128px;
+}
+.ui-icon-image {
+ background-position: -208px -128px;
+}
+.ui-icon-video {
+ background-position: -224px -128px;
+}
+.ui-icon-script {
+ background-position: -240px -128px;
+}
+.ui-icon-alert {
+ background-position: 0 -144px;
+}
+.ui-icon-info {
+ background-position: -16px -144px;
+}
+.ui-icon-notice {
+ background-position: -32px -144px;
+}
+.ui-icon-help {
+ background-position: -48px -144px;
+}
+.ui-icon-check {
+ background-position: -64px -144px;
+}
+.ui-icon-bullet {
+ background-position: -80px -144px;
+}
+.ui-icon-radio-on {
+ background-position: -96px -144px;
+}
+.ui-icon-radio-off {
+ background-position: -112px -144px;
+}
+.ui-icon-pin-w {
+ background-position: -128px -144px;
+}
+.ui-icon-pin-s {
+ background-position: -144px -144px;
+}
+.ui-icon-play {
+ background-position: 0 -160px;
+}
+.ui-icon-pause {
+ background-position: -16px -160px;
+}
+.ui-icon-seek-next {
+ background-position: -32px -160px;
+}
+.ui-icon-seek-prev {
+ background-position: -48px -160px;
+}
+.ui-icon-seek-end {
+ background-position: -64px -160px;
+}
+.ui-icon-seek-start {
+ background-position: -80px -160px;
+}
+.ui-icon-seek-first {
+ background-position: -80px -160px;
+}
+.ui-icon-stop {
+ background-position: -96px -160px;
+}
+.ui-icon-eject {
+ background-position: -112px -160px;
+}
+.ui-icon-volume-off {
+ background-position: -128px -160px;
+}
+.ui-icon-volume-on {
+ background-position: -144px -160px;
+}
+.ui-icon-power {
+ background-position: 0 -176px;
+}
+.ui-icon-signal-diag {
+ background-position: -16px -176px;
+}
+.ui-icon-signal {
+ background-position: -32px -176px;
+}
+.ui-icon-battery-0 {
+ background-position: -48px -176px;
+}
+.ui-icon-battery-1 {
+ background-position: -64px -176px;
+}
+.ui-icon-battery-2 {
+ background-position: -80px -176px;
+}
+.ui-icon-battery-3 {
+ background-position: -96px -176px;
+}
+.ui-icon-circle-plus {
+ background-position: 0 -192px;
+}
+.ui-icon-circle-minus {
+ background-position: -16px -192px;
+}
+.ui-icon-circle-close {
+ background-position: -32px -192px;
+}
+.ui-icon-circle-triangle-e {
+ background-position: -48px -192px;
+}
+.ui-icon-circle-triangle-s {
+ background-position: -64px -192px;
+}
+.ui-icon-circle-triangle-w {
+ background-position: -80px -192px;
+}
+.ui-icon-circle-triangle-n {
+ background-position: -96px -192px;
+}
+.ui-icon-circle-arrow-e {
+ background-position: -112px -192px;
+}
+.ui-icon-circle-arrow-s {
+ background-position: -128px -192px;
+}
+.ui-icon-circle-arrow-w {
+ background-position: -144px -192px;
+}
+.ui-icon-circle-arrow-n {
+ background-position: -160px -192px;
+}
+.ui-icon-circle-zoomin {
+ background-position: -176px -192px;
+}
+.ui-icon-circle-zoomout {
+ background-position: -192px -192px;
+}
+.ui-icon-circle-check {
+ background-position: -208px -192px;
+}
+.ui-icon-circlesmall-plus {
+ background-position: 0 -208px;
+}
+.ui-icon-circlesmall-minus {
+ background-position: -16px -208px;
+}
+.ui-icon-circlesmall-close {
+ background-position: -32px -208px;
+}
+.ui-icon-squaresmall-plus {
+ background-position: -48px -208px;
+}
+.ui-icon-squaresmall-minus {
+ background-position: -64px -208px;
+}
+.ui-icon-squaresmall-close {
+ background-position: -80px -208px;
+}
+.ui-icon-grip-dotted-vertical {
+ background-position: 0 -224px;
+}
+.ui-icon-grip-dotted-horizontal {
+ background-position: -16px -224px;
+}
+.ui-icon-grip-solid-vertical {
+ background-position: -32px -224px;
+}
+.ui-icon-grip-solid-horizontal {
+ background-position: -48px -224px;
+}
+.ui-icon-gripsmall-diagonal-se {
+ background-position: -64px -224px;
+}
+.ui-icon-grip-diagonal-se {
+ background-position: -80px -224px;
+}
+.ui-corner-all,
+.ui-corner-left,
+.ui-corner-tl,
+.ui-corner-top {
+ border-top-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-right,
+.ui-corner-top,
+.ui-corner-tr {
+ border-top-right-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bl,
+.ui-corner-bottom,
+.ui-corner-left {
+ border-bottom-left-radius: 3px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-br,
+.ui-corner-right {
+ border-bottom-right-radius: 3px;
+}
+.ui-widget-overlay {
+ background: #aaa;
+ opacity: 0.003;
+ filter: Alpha(Opacity=.3);
+}
+.ui-widget-shadow {
+ -webkit-box-shadow: 0 0 5px #666;
+ box-shadow: 0 0 5px #666;
+}
+.nice-select {
+ -webkit-tap-highlight-color: transparent;
+ background-color: #fff;
+ border-radius: 5px;
+ border: solid 1px #e8e8e8;
+ box-sizing: border-box;
+ clear: both;
+ cursor: pointer;
+ display: block;
+ float: left;
+ font-family: inherit;
+ font-size: 14px;
+ font-weight: 400;
+ height: 42px;
+ line-height: 40px;
+ outline: 0;
+ padding-left: 18px;
+ padding-right: 30px;
+ position: relative;
+ text-align: left !important;
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ white-space: nowrap;
+ width: auto;
+}
+.nice-select:hover {
+ border-color: #dbdbdb;
+}
+.nice-select.open,
+.nice-select:active,
+.nice-select:focus {
+ border-color: #999;
+}
+.nice-select:after {
+ border-bottom: 2px solid #999;
+ border-right: 2px solid #999;
+ content: '';
+ display: block;
+ height: 5px;
+ margin-top: -4px;
+ pointer-events: none;
+ position: absolute;
+ right: 12px;
+ top: 50%;
+ -webkit-transform-origin: 66% 66%;
+ -ms-transform-origin: 66% 66%;
+ transform-origin: 66% 66%;
+ -webkit-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ transform: rotate(45deg);
+ -webkit-transition: all 0.15s ease-in-out;
+ transition: all 0.15s ease-in-out;
+ width: 5px;
+}
+.nice-select.open:after {
+ -webkit-transform: rotate(-135deg);
+ -ms-transform: rotate(-135deg);
+ transform: rotate(-135deg);
+}
+.nice-select.open .list {
+ opacity: 1;
+ pointer-events: auto;
+ -webkit-transform: scale(1) translateY(0);
+ -ms-transform: scale(1) translateY(0);
+ transform: scale(1) translateY(0);
+}
+.nice-select.disabled {
+ border-color: #ededed;
+ color: #999;
+ pointer-events: none;
+}
+.nice-select.disabled:after {
+ border-color: #fff;
+}
+.nice-select.wide {
+ width: 100%;
+}
+.nice-select.wide .list {
+ left: 0 !important;
+ right: 0 !important;
+}
+.nice-select.right {
+ float: right;
+}
+.nice-select.right .list {
+ left: auto;
+ right: 0;
+}
+.nice-select.small {
+ font-size: 12px;
+ height: 36px;
+ line-height: 34px;
+}
+.nice-select.small:after {
+ height: 4px;
+ width: 4px;
+}
+.nice-select.small .option {
+ line-height: 34px;
+ min-height: 34px;
+}
+.nice-select .list {
+ background-color: #fff;
+ border-radius: 5px;
+ box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
+ box-sizing: border-box;
+ margin-top: 4px;
+ opacity: 0;
+ overflow: hidden;
+ padding: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 100%;
+ left: 0;
+ -webkit-transform-origin: 50% 0;
+ -ms-transform-origin: 50% 0;
+ transform-origin: 50% 0;
+ -webkit-transform: scale(0.75) translateY(-21px);
+ -ms-transform: scale(0.75) translateY(-21px);
+ transform: scale(0.75) translateY(-21px);
+ -webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ z-index: 9;
+}
+.nice-select .list:hover .option:not(:hover) {
+ background-color: transparent !important;
+}
+.nice-select .option {
+ cursor: pointer;
+ font-weight: 400;
+ line-height: 40px;
+ list-style: none;
+ min-height: 40px;
+ outline: 0;
+ padding-left: 18px;
+ padding-right: 29px;
+ text-align: left;
+ -webkit-transition: all 0.2s;
+ transition: all 0.2s;
+}
+.nice-select .option.focus,
+.nice-select .option.selected.focus,
+.nice-select .option:hover {
+ background-color: #f6f6f6;
+}
+.nice-select .option.selected {
+ font-weight: 700;
+}
+.nice-select .option.disabled {
+ background-color: transparent;
+ color: #999;
+ cursor: default;
+}
+.no-csspointerevents .nice-select .list {
+ display: none;
+}
+.no-csspointerevents .nice-select.open .list {
+ display: block;
+}
+@font-face {
+ font-family: swiper-icons;
+ src: url('data:application/font-woff;charset=utf-8;base64, d09GRgABAAAAAAZgABAAAAAADAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAGRAAAABoAAAAci6qHkUdERUYAAAWgAAAAIwAAACQAYABXR1BPUwAABhQAAAAuAAAANuAY7+xHU1VCAAAFxAAAAFAAAABm2fPczU9TLzIAAAHcAAAASgAAAGBP9V5RY21hcAAAAkQAAACIAAABYt6F0cBjdnQgAAACzAAAAAQAAAAEABEBRGdhc3AAAAWYAAAACAAAAAj//wADZ2x5ZgAAAywAAADMAAAD2MHtryVoZWFkAAABbAAAADAAAAA2E2+eoWhoZWEAAAGcAAAAHwAAACQC9gDzaG10eAAAAigAAAAZAAAArgJkABFsb2NhAAAC0AAAAFoAAABaFQAUGG1heHAAAAG8AAAAHwAAACAAcABAbmFtZQAAA/gAAAE5AAACXvFdBwlwb3N0AAAFNAAAAGIAAACE5s74hXjaY2BkYGAAYpf5Hu/j+W2+MnAzMYDAzaX6QjD6/4//Bxj5GA8AuRwMYGkAPywL13jaY2BkYGA88P8Agx4j+/8fQDYfA1AEBWgDAIB2BOoAeNpjYGRgYNBh4GdgYgABEMnIABJzYNADCQAACWgAsQB42mNgYfzCOIGBlYGB0YcxjYGBwR1Kf2WQZGhhYGBiYGVmgAFGBiQQkOaawtDAoMBQxXjg/wEGPcYDDA4wNUA2CCgwsAAAO4EL6gAAeNpj2M0gyAACqxgGNWBkZ2D4/wMA+xkDdgAAAHjaY2BgYGaAYBkGRgYQiAHyGMF8FgYHIM3DwMHABGQrMOgyWDLEM1T9/w8UBfEMgLzE////P/5//f/V/xv+r4eaAAeMbAxwIUYmIMHEgKYAYjUcsDAwsLKxc3BycfPw8jEQA/gZBASFhEVExcQlJKWkZWTl5BUUlZRVVNXUNTQZBgMAAMR+E+gAEQFEAAAAKgAqACoANAA+AEgAUgBcAGYAcAB6AIQAjgCYAKIArAC2AMAAygDUAN4A6ADyAPwBBgEQARoBJAEuATgBQgFMAVYBYAFqAXQBfgGIAZIBnAGmAbIBzgHsAAB42u2NMQ6CUAyGW568x9AneYYgm4MJbhKFaExIOAVX8ApewSt4Bic4AfeAid3VOBixDxfPYEza5O+Xfi04YADggiUIULCuEJK8VhO4bSvpdnktHI5QCYtdi2sl8ZnXaHlqUrNKzdKcT8cjlq+rwZSvIVczNiezsfnP/uznmfPFBNODM2K7MTQ45YEAZqGP81AmGGcF3iPqOop0r1SPTaTbVkfUe4HXj97wYE+yNwWYxwWu4v1ugWHgo3S1XdZEVqWM7ET0cfnLGxWfkgR42o2PvWrDMBSFj/IHLaF0zKjRgdiVMwScNRAoWUoH78Y2icB/yIY09An6AH2Bdu/UB+yxopYshQiEvnvu0dURgDt8QeC8PDw7Fpji3fEA4z/PEJ6YOB5hKh4dj3EvXhxPqH/SKUY3rJ7srZ4FZnh1PMAtPhwP6fl2PMJMPDgeQ4rY8YT6Gzao0eAEA409DuggmTnFnOcSCiEiLMgxCiTI6Cq5DZUd3Qmp10vO0LaLTd2cjN4fOumlc7lUYbSQcZFkutRG7g6JKZKy0RmdLY680CDnEJ+UMkpFFe1RN7nxdVpXrC4aTtnaurOnYercZg2YVmLN/d/gczfEimrE/fs/bOuq29Zmn8tloORaXgZgGa78yO9/cnXm2BpaGvq25Dv9S4E9+5SIc9PqupJKhYFSSl47+Qcr1mYNAAAAeNptw0cKwkAAAMDZJA8Q7OUJvkLsPfZ6zFVERPy8qHh2YER+3i/BP83vIBLLySsoKimrqKqpa2hp6+jq6RsYGhmbmJqZSy0sraxtbO3sHRydnEMU4uR6yx7JJXveP7WrDycAAAAAAAH//wACeNpjYGRgYOABYhkgZgJCZgZNBkYGLQZtIJsFLMYAAAw3ALgAeNolizEKgDAQBCchRbC2sFER0YD6qVQiBCv/H9ezGI6Z5XBAw8CBK/m5iQQVauVbXLnOrMZv2oLdKFa8Pjuru2hJzGabmOSLzNMzvutpB3N42mNgZGBg4GKQYzBhYMxJLMlj4GBgAYow/P/PAJJhLM6sSoWKfWCAAwDAjgbRAAB42mNgYGBkAIIbCZo5IPrmUn0hGA0AO8EFTQAA')
+ format('woff');
+ font-weight: 400;
+ font-style: normal;
+}
+:root {
+ --swiper-theme-color: #007aff;
+}
+.swiper-container {
+ margin-left: auto;
+ margin-right: auto;
+ position: relative;
+ overflow: hidden;
+ list-style: none;
+ padding: 0;
+ z-index: 1;
+}
+.swiper-container-vertical > .swiper-wrapper {
+ flex-direction: column;
+}
+.swiper-wrapper {
+ position: relative;
+ width: 100%;
+ height: 100%;
+ z-index: 1;
+ display: flex;
+ transition-property: transform;
+ box-sizing: content-box;
+}
+.swiper-container-android .swiper-slide,
+.swiper-wrapper {
+ transform: translate3d(0px, 0, 0);
+}
+.swiper-container-multirow > .swiper-wrapper {
+ flex-wrap: wrap;
+}
+.swiper-container-multirow-column > .swiper-wrapper {
+ flex-wrap: wrap;
+ flex-direction: column;
+}
+.swiper-container-free-mode > .swiper-wrapper {
+ transition-timing-function: ease-out;
+ margin: 0 auto;
+}
+.swiper-slide {
+ flex-shrink: 0;
+ width: 100%;
+ height: 100%;
+ position: relative;
+ transition-property: transform;
+}
+.swiper-slide-invisible-blank {
+ visibility: hidden;
+}
+.swiper-container-autoheight,
+.swiper-container-autoheight .swiper-slide {
+ height: auto;
+}
+.swiper-container-autoheight .swiper-wrapper {
+ align-items: flex-start;
+ transition-property: transform, height;
+}
+.swiper-container-3d {
+ perspective: 1200px;
+}
+.swiper-container-3d .swiper-cube-shadow,
+.swiper-container-3d .swiper-slide,
+.swiper-container-3d .swiper-slide-shadow-bottom,
+.swiper-container-3d .swiper-slide-shadow-left,
+.swiper-container-3d .swiper-slide-shadow-right,
+.swiper-container-3d .swiper-slide-shadow-top,
+.swiper-container-3d .swiper-wrapper {
+ transform-style: preserve-3d;
+}
+.swiper-container-3d .swiper-slide-shadow-bottom,
+.swiper-container-3d .swiper-slide-shadow-left,
+.swiper-container-3d .swiper-slide-shadow-right,
+.swiper-container-3d .swiper-slide-shadow-top {
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 10;
+}
+.swiper-container-3d .swiper-slide-shadow-left {
+ background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+}
+.swiper-container-3d .swiper-slide-shadow-right {
+ background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+}
+.swiper-container-3d .swiper-slide-shadow-top {
+ background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+}
+.swiper-container-3d .swiper-slide-shadow-bottom {
+ background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
+}
+.swiper-container-css-mode > .swiper-wrapper {
+ overflow: auto;
+ scrollbar-width: none;
+ -ms-overflow-style: none;
+}
+.swiper-container-css-mode > .swiper-wrapper::-webkit-scrollbar {
+ display: none;
+}
+.swiper-container-css-mode > .swiper-wrapper > .swiper-slide {
+ scroll-snap-align: start start;
+}
+.swiper-container-horizontal.swiper-container-css-mode > .swiper-wrapper {
+ scroll-snap-type: x mandatory;
+}
+.swiper-container-vertical.swiper-container-css-mode > .swiper-wrapper {
+ scroll-snap-type: y mandatory;
+}
+:root {
+ --swiper-navigation-size: 44px;
+}
+.swiper-button-next,
+.swiper-button-prev {
+ position: absolute;
+ top: 50%;
+ width: calc(var(--swiper-navigation-size) / 44 * 27);
+ height: var(--swiper-navigation-size);
+ margin-top: calc(-1 * var(--swiper-navigation-size) / 2);
+ z-index: 10;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: var(--swiper-navigation-color, var(--swiper-theme-color));
+}
+.swiper-button-next.swiper-button-disabled,
+.swiper-button-prev.swiper-button-disabled {
+ opacity: 0.35;
+ cursor: auto;
+ pointer-events: none;
+}
+.swiper-button-next:after,
+.swiper-button-prev:after {
+ font-family: swiper-icons;
+ font-size: var(--swiper-navigation-size);
+ text-transform: none !important;
+ letter-spacing: 0;
+ text-transform: none;
+ font-variant: initial;
+ line-height: 1;
+}
+.swiper-button-prev,
+.swiper-container-rtl .swiper-button-next {
+ left: 10px;
+ right: auto;
+}
+.swiper-button-prev:after,
+.swiper-container-rtl .swiper-button-next:after {
+ content: 'prev';
+}
+.swiper-button-next,
+.swiper-container-rtl .swiper-button-prev {
+ right: 10px;
+ left: auto;
+}
+.swiper-button-next:after,
+.swiper-container-rtl .swiper-button-prev:after {
+ content: 'next';
+}
+.swiper-button-next.swiper-button-white,
+.swiper-button-prev.swiper-button-white {
+ --swiper-navigation-color: #fff;
+}
+.swiper-button-next.swiper-button-black,
+.swiper-button-prev.swiper-button-black {
+ --swiper-navigation-color: #000;
+}
+.swiper-button-lock {
+ display: none;
+}
+.swiper-pagination {
+ position: absolute;
+ text-align: center;
+ transition: 0.3s opacity;
+ transform: translate3d(0, 0, 0);
+ z-index: 10;
+}
+.swiper-pagination.swiper-pagination-hidden {
+ opacity: 0;
+}
+.swiper-container-horizontal > .swiper-pagination-bullets,
+.swiper-pagination-custom,
+.swiper-pagination-fraction {
+ bottom: 10px;
+ left: 0;
+ width: 100%;
+}
+.swiper-pagination-bullets-dynamic {
+ overflow: hidden;
+ font-size: 0;
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+ transform: scale(0.33);
+ position: relative;
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active {
+ transform: scale(1);
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-main {
+ transform: scale(1);
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev {
+ transform: scale(0.66);
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-prev-prev {
+ transform: scale(0.33);
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next {
+ transform: scale(0.66);
+}
+.swiper-pagination-bullets-dynamic .swiper-pagination-bullet-active-next-next {
+ transform: scale(0.33);
+}
+.swiper-pagination-bullet {
+ width: 8px;
+ height: 8px;
+ display: inline-block;
+ border-radius: 100%;
+ background: #000;
+ opacity: 0.2;
+}
+button.swiper-pagination-bullet {
+ border: 0;
+ margin: 0;
+ padding: 0;
+ box-shadow: none;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+.swiper-pagination-clickable .swiper-pagination-bullet {
+ cursor: pointer;
+}
+.swiper-pagination-bullet-active {
+ opacity: 1;
+ background: var(--swiper-pagination-color, var(--swiper-theme-color));
+}
+.swiper-container-vertical > .swiper-pagination-bullets {
+ right: 10px;
+ top: 50%;
+ transform: translate3d(0px, -50%, 0);
+}
+.swiper-container-vertical > .swiper-pagination-bullets .swiper-pagination-bullet {
+ margin: 6px 0;
+ display: block;
+}
+.swiper-container-vertical > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
+ top: 50%;
+ transform: translateY(-50%);
+ width: 8px;
+}
+.swiper-container-vertical > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+ display: inline-block;
+ transition: 0.2s transform, 0.2s top;
+}
+.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet {
+ margin: 0 4px;
+}
+.swiper-container-horizontal > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic {
+ left: 50%;
+ transform: translateX(-50%);
+ white-space: nowrap;
+}
+.swiper-container-horizontal > .swiper-pagination-bullets.swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+ transition: 0.2s transform, 0.2s left;
+}
+.swiper-container-horizontal.swiper-container-rtl > .swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
+ transition: 0.2s transform, 0.2s right;
+}
+.swiper-pagination-progressbar {
+ background: rgba(0, 0, 0, 0.25);
+ position: absolute;
+}
+.swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
+ background: var(--swiper-pagination-color, var(--swiper-theme-color));
+ position: absolute;
+ left: 0;
+ top: 0;
+ width: 100%;
+ height: 100%;
+ transform: scale(0);
+ transform-origin: left top;
+}
+.swiper-container-rtl .swiper-pagination-progressbar .swiper-pagination-progressbar-fill {
+ transform-origin: right top;
+}
+.swiper-container-horizontal > .swiper-pagination-progressbar,
+.swiper-container-vertical > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite {
+ width: 100%;
+ height: 4px;
+ left: 0;
+ top: 0;
+}
+.swiper-container-horizontal > .swiper-pagination-progressbar.swiper-pagination-progressbar-opposite,
+.swiper-container-vertical > .swiper-pagination-progressbar {
+ width: 4px;
+ height: 100%;
+ left: 0;
+ top: 0;
+}
+.swiper-pagination-white {
+ --swiper-pagination-color: #fff;
+}
+.swiper-pagination-black {
+ --swiper-pagination-color: #000;
+}
+.swiper-pagination-lock {
+ display: none;
+}
+.swiper-scrollbar {
+ border-radius: 10px;
+ position: relative;
+ -ms-touch-action: none;
+ background: rgba(0, 0, 0, 0.1);
+}
+.swiper-container-horizontal > .swiper-scrollbar {
+ position: absolute;
+ left: 1%;
+ bottom: 3px;
+ z-index: 50;
+ height: 5px;
+ width: 98%;
+}
+.swiper-container-vertical > .swiper-scrollbar {
+ position: absolute;
+ right: 3px;
+ top: 1%;
+ z-index: 50;
+ width: 5px;
+ height: 98%;
+}
+.swiper-scrollbar-drag {
+ height: 100%;
+ width: 100%;
+ position: relative;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 10px;
+ left: 0;
+ top: 0;
+}
+.swiper-scrollbar-cursor-drag {
+ cursor: move;
+}
+.swiper-scrollbar-lock {
+ display: none;
+}
+.swiper-zoom-container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ text-align: center;
+}
+.swiper-zoom-container > canvas,
+.swiper-zoom-container > img,
+.swiper-zoom-container > svg {
+ max-width: 100%;
+ max-height: 100%;
+ object-fit: contain;
+}
+.swiper-slide-zoomed {
+ cursor: move;
+}
+.swiper-lazy-preloader {
+ width: 42px;
+ height: 42px;
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ margin-left: -21px;
+ margin-top: -21px;
+ z-index: 10;
+ transform-origin: 50%;
+ animation: swiper-preloader-spin 1s infinite linear;
+ box-sizing: border-box;
+ border: 4px solid var(--swiper-preloader-color, var(--swiper-theme-color));
+ border-radius: 50%;
+ border-top-color: transparent;
+}
+.swiper-lazy-preloader-white {
+ --swiper-preloader-color: #fff;
+}
+.swiper-lazy-preloader-black {
+ --swiper-preloader-color: #000;
+}
+@keyframes swiper-preloader-spin {
+ 100% {
+ transform: rotate(360deg);
+ }
+}
+.swiper-container .swiper-notification {
+ position: absolute;
+ left: 0;
+ top: 0;
+ pointer-events: none;
+ opacity: 0;
+ z-index: -1000;
+}
+.swiper-container-fade.swiper-container-free-mode .swiper-slide {
+ transition-timing-function: ease-out;
+}
+.swiper-container-fade .swiper-slide {
+ pointer-events: none;
+ transition-property: opacity;
+}
+.swiper-container-fade .swiper-slide .swiper-slide {
+ pointer-events: none;
+}
+.swiper-container-fade .swiper-slide-active,
+.swiper-container-fade .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+}
+.swiper-container-cube {
+ overflow: visible;
+}
+.swiper-container-cube .swiper-slide {
+ pointer-events: none;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ z-index: 1;
+ visibility: hidden;
+ transform-origin: 0 0;
+ width: 100%;
+ height: 100%;
+}
+.swiper-container-cube .swiper-slide .swiper-slide {
+ pointer-events: none;
+}
+.swiper-container-cube.swiper-container-rtl .swiper-slide {
+ transform-origin: 100% 0;
+}
+.swiper-container-cube .swiper-slide-active,
+.swiper-container-cube .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+}
+.swiper-container-cube .swiper-slide-active,
+.swiper-container-cube .swiper-slide-next,
+.swiper-container-cube .swiper-slide-next + .swiper-slide,
+.swiper-container-cube .swiper-slide-prev {
+ pointer-events: auto;
+ visibility: visible;
+}
+.swiper-container-cube .swiper-slide-shadow-bottom,
+.swiper-container-cube .swiper-slide-shadow-left,
+.swiper-container-cube .swiper-slide-shadow-right,
+.swiper-container-cube .swiper-slide-shadow-top {
+ z-index: 0;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+}
+.swiper-container-cube .swiper-cube-shadow {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 100%;
+ background: #000;
+ opacity: 0.6;
+ -webkit-filter: blur(50px);
+ filter: blur(50px);
+ z-index: 0;
+}
+.swiper-container-flip {
+ overflow: visible;
+}
+.swiper-container-flip .swiper-slide {
+ pointer-events: none;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ z-index: 1;
+}
+.swiper-container-flip .swiper-slide .swiper-slide {
+ pointer-events: none;
+}
+.swiper-container-flip .swiper-slide-active,
+.swiper-container-flip .swiper-slide-active .swiper-slide-active {
+ pointer-events: auto;
+}
+.swiper-container-flip .swiper-slide-shadow-bottom,
+.swiper-container-flip .swiper-slide-shadow-left,
+.swiper-container-flip .swiper-slide-shadow-right,
+.swiper-container-flip .swiper-slide-shadow-top {
+ z-index: 0;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+}
+.vbox-overlay *,
+.vbox-overlay :after,
+.vbox-overlay :before {
+ -webkit-backface-visibility: hidden;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+.vbox-overlay * {
+ -webkit-backface-visibility: visible;
+ backface-visibility: visible;
+}
+.vbox-overlay {
+ display: -webkit-flex;
+ display: flex;
+ -webkit-flex-direction: column;
+ flex-direction: column;
+ -webkit-justify-content: center;
+ justify-content: center;
+ -webkit-align-items: center;
+ align-items: center;
+ position: fixed;
+ left: 0;
+ top: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 474747;
+}
+.vbox-title {
+ width: 100%;
+ height: 40px;
+ float: left;
+ text-align: center;
+ line-height: 28px;
+ font-size: 12px;
+ padding: 6px 50px;
+ overflow: hidden;
+ position: fixed;
+ display: none;
+ left: 0;
+ z-index: 89;
+}
+.vbox-close {
+ cursor: pointer;
+ position: fixed;
+ top: -1px;
+ right: 0;
+ width: 50px;
+ height: 40px;
+ padding: 6px;
+ display: block;
+ background-position: 10px center;
+ overflow: hidden;
+ font-size: 24px;
+ line-height: 1;
+ text-align: center;
+ z-index: 99;
+}
+.vbox-left {
+ cursor: pointer;
+ position: fixed;
+ left: 0;
+ height: 40px;
+ overflow: hidden;
+ line-height: 28px;
+ font-size: 12px;
+ z-index: 99;
+ display: flex;
+ align-items: center;
+}
+.vbox-num {
+ display: inline-block;
+ margin: 6px 0 6px 15px;
+}
+.vbox-share {
+ line-height: 28px;
+ font-size: 12px;
+ overflow: hidden;
+ position: fixed;
+ left: 0;
+ z-index: 98;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 100%;
+ text-align: center;
+}
+.vbox-share svg {
+ max-height: 28px;
+ width: 28px;
+ z-index: 10;
+ margin-left: 12px;
+ margin-top: 6px;
+ margin-bottom: 6px;
+ vertical-align: middle;
+}
+.vbox-next,
+.vbox-prev {
+ position: fixed;
+ top: 50%;
+ margin-top: -15px;
+ overflow: hidden;
+ cursor: pointer;
+ display: block;
+ width: 45px;
+ height: 45px;
+ z-index: 99;
+}
+.vbox-next span,
+.vbox-prev span {
+ position: relative;
+ width: 20px;
+ height: 20px;
+ border: 2px solid transparent;
+ border-top-color: #b6b6b6;
+ border-right-color: #b6b6b6;
+ text-indent: -100px;
+ position: absolute;
+ top: 8px;
+ display: block;
+}
+.vbox-prev {
+ left: 15px;
+}
+.vbox-next {
+ right: 15px;
+}
+.vbox-prev span {
+ left: 10px;
+ -ms-transform: rotate(-135deg);
+ -webkit-transform: rotate(-135deg);
+ transform: rotate(-135deg);
+}
+.vbox-next span {
+ -ms-transform: rotate(45deg);
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ right: 10px;
+}
+.vbox-inline {
+ width: 420px;
+ height: 315px;
+ height: 70vh;
+ padding: 10px;
+ background: #fff;
+ margin: 0 auto;
+ overflow: auto;
+ text-align: left;
+}
+.venoframe {
+ max-width: 100%;
+ width: 100%;
+ border: 0;
+ width: 100%;
+ height: 260px;
+ height: 70vh;
+}
+.venoframe.vbvid {
+ height: 260px;
+}
+@media (min-width: 768px) {
+ .vbox-inline,
+ .venoframe {
+ width: 90%;
+ height: 360px;
+ height: 70vh;
+ }
+ .venoframe.vbvid {
+ width: 640px;
+ height: 360px;
+ }
+}
+@media (min-width: 992px) {
+ .vbox-inline,
+ .venoframe {
+ max-width: 1200px;
+ width: 80%;
+ height: 540px;
+ height: 70vh;
+ }
+ .venoframe.vbvid {
+ width: 960px;
+ height: 540px;
+ }
+}
+.vbox-open {
+ overflow: hidden;
+}
+.vbox-container {
+ position: absolute;
+ left: 0;
+ right: 0;
+ top: 0;
+ bottom: 0;
+ overflow-x: hidden;
+ overflow-y: scroll;
+ overflow-scrolling: touch;
+ -webkit-overflow-scrolling: touch;
+ z-index: 20;
+ max-height: 100%;
+}
+.vbox-content {
+ text-align: center;
+ float: left;
+ width: 100%;
+ position: relative;
+ overflow: hidden;
+ padding: 20px 4%;
+}
+.vbox-container img {
+ max-width: 100%;
+ height: auto;
+}
+.vbox-figlio {
+ box-shadow: 0 0 12px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
+ max-width: 100%;
+ text-align: initial;
+}
+img.vbox-figlio {
+ -webkit-user-select: none;
+ -khtml-user-select: none;
+ -moz-user-select: none;
+ -o-user-select: none;
+ user-select: none;
+}
+.vbox-content.swipe-left {
+ margin-left: -200px !important;
+}
+.vbox-content.swipe-right {
+ margin-left: 200px !important;
+}
+.vbox-animated {
+ webkit-transition: margin 0.3s ease-out;
+ transition: margin 0.3s ease-out;
+}
+.sk-double-bounce,
+.sk-rotating-plane {
+ width: 40px;
+ height: 40px;
+ margin: 40px auto;
+}
+.sk-rotating-plane {
+ background-color: #333;
+ -webkit-animation: sk-rotatePlane 1.2s infinite ease-in-out;
+ animation: sk-rotatePlane 1.2s infinite ease-in-out;
+}
+@-webkit-keyframes sk-rotatePlane {
+ 0% {
+ -webkit-transform: perspective(120px) rotateX(0) rotateY(0);
+ transform: perspective(120px) rotateX(0) rotateY(0);
+ }
+ 50% {
+ -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0);
+ transform: perspective(120px) rotateX(-180.1deg) rotateY(0);
+ }
+ 100% {
+ -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ }
+}
+@keyframes sk-rotatePlane {
+ 0% {
+ -webkit-transform: perspective(120px) rotateX(0) rotateY(0);
+ transform: perspective(120px) rotateX(0) rotateY(0);
+ }
+ 50% {
+ -webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0);
+ transform: perspective(120px) rotateX(-180.1deg) rotateY(0);
+ }
+ 100% {
+ -webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
+ }
+}
+.sk-double-bounce {
+ position: relative;
+}
+.sk-double-bounce .sk-child {
+ width: 100%;
+ height: 100%;
+ border-radius: 50%;
+ background-color: #333;
+ opacity: 0.6;
+ position: absolute;
+ top: 0;
+ left: 0;
+ -webkit-animation: sk-doubleBounce 2s infinite ease-in-out;
+ animation: sk-doubleBounce 2s infinite ease-in-out;
+}
+.sk-chasing-dots .sk-child,
+.sk-spinner-pulse,
+.sk-three-bounce .sk-child {
+ background-color: #333;
+ border-radius: 100%;
+}
+.sk-double-bounce .sk-double-bounce2 {
+ -webkit-animation-delay: -1s;
+ animation-delay: -1s;
+}
+@-webkit-keyframes sk-doubleBounce {
+ 0%,
+ 100% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 50% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes sk-doubleBounce {
+ 0%,
+ 100% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 50% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.sk-wave {
+ margin: 40px auto;
+ width: 50px;
+ height: 40px;
+ text-align: center;
+ font-size: 10px;
+}
+.sk-wave .sk-rect {
+ background-color: #333;
+ height: 100%;
+ width: 6px;
+ display: inline-block;
+ -webkit-animation: sk-waveStretchDelay 1.2s infinite ease-in-out;
+ animation: sk-waveStretchDelay 1.2s infinite ease-in-out;
+}
+.sk-wave .sk-rect1 {
+ -webkit-animation-delay: -1.2s;
+ animation-delay: -1.2s;
+}
+.sk-wave .sk-rect2 {
+ -webkit-animation-delay: -1.1s;
+ animation-delay: -1.1s;
+}
+.sk-wave .sk-rect3 {
+ -webkit-animation-delay: -1s;
+ animation-delay: -1s;
+}
+.sk-wave .sk-rect4 {
+ -webkit-animation-delay: -0.9s;
+ animation-delay: -0.9s;
+}
+.sk-wave .sk-rect5 {
+ -webkit-animation-delay: -0.8s;
+ animation-delay: -0.8s;
+}
+@-webkit-keyframes sk-waveStretchDelay {
+ 0%,
+ 100%,
+ 40% {
+ -webkit-transform: scaleY(0.4);
+ transform: scaleY(0.4);
+ }
+ 20% {
+ -webkit-transform: scaleY(1);
+ transform: scaleY(1);
+ }
+}
+@keyframes sk-waveStretchDelay {
+ 0%,
+ 100%,
+ 40% {
+ -webkit-transform: scaleY(0.4);
+ transform: scaleY(0.4);
+ }
+ 20% {
+ -webkit-transform: scaleY(1);
+ transform: scaleY(1);
+ }
+}
+.sk-wandering-cubes {
+ margin: 40px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+}
+.sk-wandering-cubes .sk-cube {
+ background-color: #333;
+ width: 10px;
+ height: 10px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ -webkit-animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both;
+ animation: sk-wanderingCube 1.8s ease-in-out -1.8s infinite both;
+}
+.sk-chasing-dots,
+.sk-spinner-pulse {
+ width: 40px;
+ height: 40px;
+ margin: 40px auto;
+}
+.sk-wandering-cubes .sk-cube2 {
+ -webkit-animation-delay: -0.9s;
+ animation-delay: -0.9s;
+}
+@-webkit-keyframes sk-wanderingCube {
+ 0% {
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+ }
+ 25% {
+ -webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
+ transform: translateX(30px) rotate(-90deg) scale(0.5);
+ }
+ 50% {
+ -webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
+ transform: translateX(30px) translateY(30px) rotate(-179deg);
+ }
+ 50.1% {
+ -webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
+ transform: translateX(30px) translateY(30px) rotate(-180deg);
+ }
+ 75% {
+ -webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
+ transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
+ }
+ 100% {
+ -webkit-transform: rotate(-360deg);
+ transform: rotate(-360deg);
+ }
+}
+@keyframes sk-wanderingCube {
+ 0% {
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+ }
+ 25% {
+ -webkit-transform: translateX(30px) rotate(-90deg) scale(0.5);
+ transform: translateX(30px) rotate(-90deg) scale(0.5);
+ }
+ 50% {
+ -webkit-transform: translateX(30px) translateY(30px) rotate(-179deg);
+ transform: translateX(30px) translateY(30px) rotate(-179deg);
+ }
+ 50.1% {
+ -webkit-transform: translateX(30px) translateY(30px) rotate(-180deg);
+ transform: translateX(30px) translateY(30px) rotate(-180deg);
+ }
+ 75% {
+ -webkit-transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
+ transform: translateX(0) translateY(30px) rotate(-270deg) scale(0.5);
+ }
+ 100% {
+ -webkit-transform: rotate(-360deg);
+ transform: rotate(-360deg);
+ }
+}
+.sk-spinner-pulse {
+ -webkit-animation: sk-pulseScaleOut 1s infinite ease-in-out;
+ animation: sk-pulseScaleOut 1s infinite ease-in-out;
+}
+@-webkit-keyframes sk-pulseScaleOut {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 0;
+ }
+}
+@keyframes sk-pulseScaleOut {
+ 0% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 100% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ opacity: 0;
+ }
+}
+.sk-chasing-dots {
+ position: relative;
+ text-align: center;
+ -webkit-animation: sk-chasingDotsRotate 2s infinite linear;
+ animation: sk-chasingDotsRotate 2s infinite linear;
+}
+.sk-chasing-dots .sk-child {
+ width: 60%;
+ height: 60%;
+ display: inline-block;
+ position: absolute;
+ top: 0;
+ -webkit-animation: sk-chasingDotsBounce 2s infinite ease-in-out;
+ animation: sk-chasingDotsBounce 2s infinite ease-in-out;
+}
+.sk-chasing-dots .sk-dot2 {
+ top: auto;
+ bottom: 0;
+ -webkit-animation-delay: -1s;
+ animation-delay: -1s;
+}
+@-webkit-keyframes sk-chasingDotsRotate {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+@keyframes sk-chasingDotsRotate {
+ 100% {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+@-webkit-keyframes sk-chasingDotsBounce {
+ 0%,
+ 100% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 50% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes sk-chasingDotsBounce {
+ 0%,
+ 100% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 50% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.sk-three-bounce {
+ margin: 40px auto;
+ width: 80px;
+ text-align: center;
+}
+.sk-three-bounce .sk-child {
+ width: 20px;
+ height: 20px;
+ display: inline-block;
+ -webkit-animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
+ animation: sk-three-bounce 1.4s ease-in-out 0s infinite both;
+}
+.sk-circle .sk-child:before,
+.sk-fading-circle .sk-circle:before {
+ display: block;
+ border-radius: 100%;
+ content: '';
+ background-color: #333;
+}
+.sk-three-bounce .sk-bounce1 {
+ -webkit-animation-delay: -0.32s;
+ animation-delay: -0.32s;
+}
+.sk-three-bounce .sk-bounce2 {
+ -webkit-animation-delay: -0.16s;
+ animation-delay: -0.16s;
+}
+@-webkit-keyframes sk-three-bounce {
+ 0%,
+ 100%,
+ 80% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 40% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes sk-three-bounce {
+ 0%,
+ 100%,
+ 80% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 40% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.sk-circle {
+ margin: 40px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+}
+.sk-circle .sk-child {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+.sk-circle .sk-child:before {
+ margin: 0 auto;
+ width: 15%;
+ height: 15%;
+ -webkit-animation: sk-circleBounceDelay 1.2s infinite ease-in-out both;
+ animation: sk-circleBounceDelay 1.2s infinite ease-in-out both;
+}
+.sk-circle .sk-circle2 {
+ -webkit-transform: rotate(30deg);
+ -ms-transform: rotate(30deg);
+ transform: rotate(30deg);
+}
+.sk-circle .sk-circle3 {
+ -webkit-transform: rotate(60deg);
+ -ms-transform: rotate(60deg);
+ transform: rotate(60deg);
+}
+.sk-circle .sk-circle4 {
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.sk-circle .sk-circle5 {
+ -webkit-transform: rotate(120deg);
+ -ms-transform: rotate(120deg);
+ transform: rotate(120deg);
+}
+.sk-circle .sk-circle6 {
+ -webkit-transform: rotate(150deg);
+ -ms-transform: rotate(150deg);
+ transform: rotate(150deg);
+}
+.sk-circle .sk-circle7 {
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.sk-circle .sk-circle8 {
+ -webkit-transform: rotate(210deg);
+ -ms-transform: rotate(210deg);
+ transform: rotate(210deg);
+}
+.sk-circle .sk-circle9 {
+ -webkit-transform: rotate(240deg);
+ -ms-transform: rotate(240deg);
+ transform: rotate(240deg);
+}
+.sk-circle .sk-circle10 {
+ -webkit-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.sk-circle .sk-circle11 {
+ -webkit-transform: rotate(300deg);
+ -ms-transform: rotate(300deg);
+ transform: rotate(300deg);
+}
+.sk-circle .sk-circle12 {
+ -webkit-transform: rotate(330deg);
+ -ms-transform: rotate(330deg);
+ transform: rotate(330deg);
+}
+.sk-circle .sk-circle2:before {
+ -webkit-animation-delay: -1.1s;
+ animation-delay: -1.1s;
+}
+.sk-circle .sk-circle3:before {
+ -webkit-animation-delay: -1s;
+ animation-delay: -1s;
+}
+.sk-circle .sk-circle4:before {
+ -webkit-animation-delay: -0.9s;
+ animation-delay: -0.9s;
+}
+.sk-circle .sk-circle5:before {
+ -webkit-animation-delay: -0.8s;
+ animation-delay: -0.8s;
+}
+.sk-circle .sk-circle6:before {
+ -webkit-animation-delay: -0.7s;
+ animation-delay: -0.7s;
+}
+.sk-circle .sk-circle7:before {
+ -webkit-animation-delay: -0.6s;
+ animation-delay: -0.6s;
+}
+.sk-circle .sk-circle8:before {
+ -webkit-animation-delay: -0.5s;
+ animation-delay: -0.5s;
+}
+.sk-circle .sk-circle9:before {
+ -webkit-animation-delay: -0.4s;
+ animation-delay: -0.4s;
+}
+.sk-circle .sk-circle10:before {
+ -webkit-animation-delay: -0.3s;
+ animation-delay: -0.3s;
+}
+.sk-circle .sk-circle11:before {
+ -webkit-animation-delay: -0.2s;
+ animation-delay: -0.2s;
+}
+.sk-circle .sk-circle12:before {
+ -webkit-animation-delay: -0.1s;
+ animation-delay: -0.1s;
+}
+@-webkit-keyframes sk-circleBounceDelay {
+ 0%,
+ 100%,
+ 80% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 40% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+@keyframes sk-circleBounceDelay {
+ 0%,
+ 100%,
+ 80% {
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ }
+ 40% {
+ -webkit-transform: scale(1);
+ transform: scale(1);
+ }
+}
+.sk-cube-grid {
+ width: 40px;
+ height: 40px;
+ margin: 40px auto;
+}
+.sk-cube-grid .sk-cube {
+ width: 33.33%;
+ height: 33.33%;
+ background-color: #333;
+ float: left;
+ -webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
+ animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
+}
+.sk-cube-grid .sk-cube1 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s;
+}
+.sk-cube-grid .sk-cube2 {
+ -webkit-animation-delay: 0.3s;
+ animation-delay: 0.3s;
+}
+.sk-cube-grid .sk-cube3 {
+ -webkit-animation-delay: 0.4s;
+ animation-delay: 0.4s;
+}
+.sk-cube-grid .sk-cube4 {
+ -webkit-animation-delay: 0.1s;
+ animation-delay: 0.1s;
+}
+.sk-cube-grid .sk-cube5 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s;
+}
+.sk-cube-grid .sk-cube6 {
+ -webkit-animation-delay: 0.3s;
+ animation-delay: 0.3s;
+}
+.sk-cube-grid .sk-cube7 {
+ -webkit-animation-delay: 0s;
+ animation-delay: 0s;
+}
+.sk-cube-grid .sk-cube8 {
+ -webkit-animation-delay: 0.1s;
+ animation-delay: 0.1s;
+}
+.sk-cube-grid .sk-cube9 {
+ -webkit-animation-delay: 0.2s;
+ animation-delay: 0.2s;
+}
+@-webkit-keyframes sk-cubeGridScaleDelay {
+ 0%,
+ 100%,
+ 70% {
+ -webkit-transform: scale3D(1, 1, 1);
+ transform: scale3D(1, 1, 1);
+ }
+ 35% {
+ -webkit-transform: scale3D(0, 0, 1);
+ transform: scale3D(0, 0, 1);
+ }
+}
+@keyframes sk-cubeGridScaleDelay {
+ 0%,
+ 100%,
+ 70% {
+ -webkit-transform: scale3D(1, 1, 1);
+ transform: scale3D(1, 1, 1);
+ }
+ 35% {
+ -webkit-transform: scale3D(0, 0, 1);
+ transform: scale3D(0, 0, 1);
+ }
+}
+.sk-fading-circle {
+ margin: 40px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+}
+.sk-fading-circle .sk-circle {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ left: 0;
+ top: 0;
+}
+.sk-fading-circle .sk-circle:before {
+ margin: 0 auto;
+ width: 15%;
+ height: 15%;
+ -webkit-animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
+ animation: sk-circleFadeDelay 1.2s infinite ease-in-out both;
+}
+.sk-fading-circle .sk-circle2 {
+ -webkit-transform: rotate(30deg);
+ -ms-transform: rotate(30deg);
+ transform: rotate(30deg);
+}
+.sk-fading-circle .sk-circle3 {
+ -webkit-transform: rotate(60deg);
+ -ms-transform: rotate(60deg);
+ transform: rotate(60deg);
+}
+.sk-fading-circle .sk-circle4 {
+ -webkit-transform: rotate(90deg);
+ -ms-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+.sk-fading-circle .sk-circle5 {
+ -webkit-transform: rotate(120deg);
+ -ms-transform: rotate(120deg);
+ transform: rotate(120deg);
+}
+.sk-fading-circle .sk-circle6 {
+ -webkit-transform: rotate(150deg);
+ -ms-transform: rotate(150deg);
+ transform: rotate(150deg);
+}
+.sk-fading-circle .sk-circle7 {
+ -webkit-transform: rotate(180deg);
+ -ms-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.sk-fading-circle .sk-circle8 {
+ -webkit-transform: rotate(210deg);
+ -ms-transform: rotate(210deg);
+ transform: rotate(210deg);
+}
+.sk-fading-circle .sk-circle9 {
+ -webkit-transform: rotate(240deg);
+ -ms-transform: rotate(240deg);
+ transform: rotate(240deg);
+}
+.sk-fading-circle .sk-circle10 {
+ -webkit-transform: rotate(270deg);
+ -ms-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.sk-fading-circle .sk-circle11 {
+ -webkit-transform: rotate(300deg);
+ -ms-transform: rotate(300deg);
+ transform: rotate(300deg);
+}
+.sk-fading-circle .sk-circle12 {
+ -webkit-transform: rotate(330deg);
+ -ms-transform: rotate(330deg);
+ transform: rotate(330deg);
+}
+.sk-fading-circle .sk-circle2:before {
+ -webkit-animation-delay: -1.1s;
+ animation-delay: -1.1s;
+}
+.sk-fading-circle .sk-circle3:before {
+ -webkit-animation-delay: -1s;
+ animation-delay: -1s;
+}
+.sk-fading-circle .sk-circle4:before {
+ -webkit-animation-delay: -0.9s;
+ animation-delay: -0.9s;
+}
+.sk-fading-circle .sk-circle5:before {
+ -webkit-animation-delay: -0.8s;
+ animation-delay: -0.8s;
+}
+.sk-fading-circle .sk-circle6:before {
+ -webkit-animation-delay: -0.7s;
+ animation-delay: -0.7s;
+}
+.sk-fading-circle .sk-circle7:before {
+ -webkit-animation-delay: -0.6s;
+ animation-delay: -0.6s;
+}
+.sk-fading-circle .sk-circle8:before {
+ -webkit-animation-delay: -0.5s;
+ animation-delay: -0.5s;
+}
+.sk-fading-circle .sk-circle9:before {
+ -webkit-animation-delay: -0.4s;
+ animation-delay: -0.4s;
+}
+.sk-fading-circle .sk-circle10:before {
+ -webkit-animation-delay: -0.3s;
+ animation-delay: -0.3s;
+}
+.sk-fading-circle .sk-circle11:before {
+ -webkit-animation-delay: -0.2s;
+ animation-delay: -0.2s;
+}
+.sk-fading-circle .sk-circle12:before {
+ -webkit-animation-delay: -0.1s;
+ animation-delay: -0.1s;
+}
+@-webkit-keyframes sk-circleFadeDelay {
+ 0%,
+ 100%,
+ 39% {
+ opacity: 0;
+ }
+ 40% {
+ opacity: 1;
+ }
+}
+@keyframes sk-circleFadeDelay {
+ 0%,
+ 100%,
+ 39% {
+ opacity: 0;
+ }
+ 40% {
+ opacity: 1;
+ }
+}
+.sk-folding-cube {
+ margin: 40px auto;
+ width: 40px;
+ height: 40px;
+ position: relative;
+ -webkit-transform: rotateZ(45deg);
+ transform: rotateZ(45deg);
+}
+.sk-folding-cube .sk-cube {
+ float: left;
+ width: 50%;
+ height: 50%;
+ position: relative;
+ -webkit-transform: scale(1.1);
+ -ms-transform: scale(1.1);
+ transform: scale(1.1);
+}
+.sk-folding-cube .sk-cube:before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background-color: #333;
+ -webkit-animation: sk-foldCubeAngle 2.4s infinite linear both;
+ animation: sk-foldCubeAngle 2.4s infinite linear both;
+ -webkit-transform-origin: 100% 100%;
+ -ms-transform-origin: 100% 100%;
+ transform-origin: 100% 100%;
+}
+.sk-folding-cube .sk-cube2 {
+ -webkit-transform: scale(1.1) rotateZ(90deg);
+ transform: scale(1.1) rotateZ(90deg);
+}
+.sk-folding-cube .sk-cube3 {
+ -webkit-transform: scale(1.1) rotateZ(180deg);
+ transform: scale(1.1) rotateZ(180deg);
+}
+.sk-folding-cube .sk-cube4 {
+ -webkit-transform: scale(1.1) rotateZ(270deg);
+ transform: scale(1.1) rotateZ(270deg);
+}
+.sk-folding-cube .sk-cube2:before {
+ -webkit-animation-delay: 0.3s;
+ animation-delay: 0.3s;
+}
+.sk-folding-cube .sk-cube3:before {
+ -webkit-animation-delay: 0.6s;
+ animation-delay: 0.6s;
+}
+.sk-folding-cube .sk-cube4:before {
+ -webkit-animation-delay: 0.9s;
+ animation-delay: 0.9s;
+}
+@-webkit-keyframes sk-foldCubeAngle {
+ 0%,
+ 10% {
+ -webkit-transform: perspective(140px) rotateX(-180deg);
+ transform: perspective(140px) rotateX(-180deg);
+ opacity: 0;
+ }
+ 25%,
+ 75% {
+ -webkit-transform: perspective(140px) rotateX(0);
+ transform: perspective(140px) rotateX(0);
+ opacity: 1;
+ }
+ 100%,
+ 90% {
+ -webkit-transform: perspective(140px) rotateY(180deg);
+ transform: perspective(140px) rotateY(180deg);
+ opacity: 0;
+ }
+}
+@keyframes sk-foldCubeAngle {
+ 0%,
+ 10% {
+ -webkit-transform: perspective(140px) rotateX(-180deg);
+ transform: perspective(140px) rotateX(-180deg);
+ opacity: 0;
+ }
+ 25%,
+ 75% {
+ -webkit-transform: perspective(140px) rotateX(0);
+ transform: perspective(140px) rotateX(0);
+ opacity: 1;
+ }
+ 100%,
+ 90% {
+ -webkit-transform: perspective(140px) rotateY(180deg);
+ transform: perspective(140px) rotateY(180deg);
+ opacity: 0;
+ }
+}
+.progressbar {
+ width: 100%;
+ margin-top: 5px;
+ margin-bottom: 35px;
+ position: relative;
+ background-color: #fff;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.1);
+}
+.proggress {
+ height: 8px;
+ width: 10px;
+}
+.percentCount {
+ float: right;
+ margin-top: 10px;
+ clear: both;
+ font-weight: bold;
+ font-family: Arial;
+}
diff --git a/public/assets/css/style.min.css b/public/assets/css/style.min.css
new file mode 100644
index 0000000..f4f1e66
--- /dev/null
+++ b/public/assets/css/style.min.css
@@ -0,0 +1,9403 @@
+@charset "UTF-8";
+@import url(https://fonts.googleapis.com/css2?family=Rubik:wght@300;400;500;600;700&display=swap);
+*,
+::after,
+::before {
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+}
+body,
+html {
+ height: 100%;
+}
+body {
+ font-family: 'Poppins', sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ font-style: normal;
+ line-height: 1.625;
+ position: relative;
+ visibility: visible;
+ color: #474747;
+}
+body[dir='rtl'] {
+ text-align: right;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ color: #000;
+}
+a,
+button {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ text-decoration: none;
+ background-color: transparent;
+ border: 0;
+}
+textarea {
+ width: 100%;
+ padding-left: 20px;
+ padding-top: 20px;
+ outline: 0;
+}
+label {
+ margin-bottom: 15px;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ min-height: 45px;
+ padding: 6px 80px 6px 20px;
+ font-size: 14px;
+ font-weight: 400;
+ line-height: 1.625;
+ color: #474747;
+ border-radius: 5px;
+ background-color: #fff;
+}
+.form-control:focus {
+ color: #495057;
+ background-color: #fff;
+ border-color: #ced4da;
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+p:last-child {
+ margin-bottom: 0;
+}
+dl,
+ol,
+ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+li {
+ list-style: none;
+}
+button:focus,
+input:focus {
+ outline: 0 dotted;
+ outline: 0 auto -webkit-focus-ring-color;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+input {
+ display: inline-block;
+ line-height: 50px;
+ height: 50px;
+ font-size: 15px;
+ width: 100%;
+ background: 0;
+ border-radius: 0;
+ -webkit-border-radius: 0;
+ text-align: left;
+ box-shadow: none;
+ -webkit-box-shadow: none;
+ padding-left: 20px;
+ padding-right: 10px;
+ outline: 0;
+}
+.img-responsive {
+ max-width: 100%;
+ display: block;
+ width: 100%;
+}
+.pt-100px {
+ padding-top: 100px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .pt-100px {
+ padding-top: 80px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .pt-100px {
+ padding-top: 60px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .pt-100px {
+ padding-top: 60px;
+ }
+}
+.pb-100px {
+ padding-bottom: 100px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .pb-100px {
+ padding-bottom: 80px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .pb-100px {
+ padding-bottom: 60px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .pb-100px {
+ padding-bottom: 20px;
+ }
+}
+.pt-70px {
+ padding-top: 70px;
+}
+.pb-40px {
+ padding-bottom: 40px;
+}
+.line-height-1 {
+ line-height: 1;
+}
+.mt-25px {
+ margin-top: 25px;
+}
+.mt-30px {
+ margin-top: 30px;
+}
+.mt-20px {
+ margin-top: 20px;
+}
+.mb-30px {
+ margin-bottom: 30px;
+}
+.ml-20px {
+ margin-left: 20px;
+}
+.ml-15px {
+ margin-left: 15px;
+}
+.mr-15px {
+ margin-right: 15px;
+}
+.ml-5px {
+ margin-left: 5px;
+}
+.ml-10px {
+ margin-left: 10px;
+}
+.pl-35px {
+ padding-left: 35px;
+}
+.pr-35px {
+ padding-right: 35px;
+}
+.mb-n-50 {
+ margin-bottom: -50px;
+}
+.mb-50px {
+ margin-bottom: 50px;
+}
+.mb-40px {
+ margin-bottom: 40px;
+}
+.ml-auto {
+ margin-left: auto;
+}
+.mr-auto {
+ margin-right: auto;
+}
+.bg-black {
+ background-color: #2f333a;
+}
+.bg-gray {
+ background-color: #f4f4f4;
+}
+.bg-white {
+ background-color: #fff;
+}
+#scrollUp {
+ width: 50px;
+ height: 50px;
+ background: #036eb8;
+ color: #fff;
+ right: 20px;
+ bottom: 60px;
+ text-align: center;
+ overflow: hidden;
+ border-radius: 50px;
+ z-index: 9811 !important;
+ font-size: 36px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+#scrollUp:hover {
+ background: #036eb8;
+ color: #fff;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(153, 63, 107, 0.5);
+ box-shadow: 0 5px 15px 0 rgba(153, 63, 107, 0.5);
+ -webkit-transform: translateY(-1px);
+ transform: translateY(-1px);
+}
+.slider-animated-1 > * {
+ -webkit-animation-duration: 1s;
+ animation-duration: 1s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+ -webkit-animation-name: fadeOutUp;
+ animation-name: fadeOutUp;
+}
+.swiper-slide-active .slider-animated-1 > * {
+ -webkit-animation-name: fadeInUp;
+ animation-name: fadeInUp;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(1) {
+ -webkit-animation-delay: 0.5s;
+ animation-delay: 0.5s;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(2) {
+ -webkit-animation-delay: 1s;
+ animation-delay: 1s;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(3) {
+ -webkit-animation-delay: 1.5s;
+ animation-delay: 1.5s;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(4) {
+ -webkit-animation-delay: 2s;
+ animation-delay: 2s;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(5) {
+ -webkit-animation-delay: 2.5s;
+ animation-delay: 2.5s;
+}
+.swiper-slide-active .slider-animated-1 > :nth-child(6) {
+ -webkit-animation-delay: 3s;
+ animation-delay: 3s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > * {
+ -webkit-animation-name: lightSpeedInLeft;
+ animation-name: lightSpeedInLeft;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(1) {
+ -webkit-animation-delay: 0.5s;
+ animation-delay: 0.5s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(2) {
+ -webkit-animation-delay: 1s;
+ animation-delay: 1s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(3) {
+ -webkit-animation-delay: 1.5s;
+ animation-delay: 1.5s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(4) {
+ -webkit-animation-delay: 2s;
+ animation-delay: 2s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(5) {
+ -webkit-animation-delay: 2.5s;
+ animation-delay: 2.5s;
+}
+.swiper-slide-active .slider-animated-1.slider-animated-2 > :nth-child(6) {
+ -webkit-animation-delay: 3s;
+ animation-delay: 3s;
+}
+.section-title {
+ line-height: 1;
+ padding: 0 300px;
+ margin-bottom: 50px;
+}
+.section-title .title {
+ font-size: 24px;
+ font-weight: 600;
+ display: inline-block;
+ color: #424242;
+ margin: 0 0 25px;
+ line-height: 27px;
+}
+@media only screen and (max-width: 767px) {
+ .section-title .title {
+ font-size: 30px;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .section-title {
+ padding: 0 170px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .section-title {
+ padding: 0 80px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .section-title {
+ padding: 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .section-title {
+ margin-bottom: 30px;
+ }
+}
+.section-title P {
+ line-height: 30px;
+ color: #747474;
+}
+@media only screen and (max-width: 479px) {
+ .section-title.mb-60px {
+ margin-bottom: 30px;
+ }
+}
+.sticky-nav.menu_fixed {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ z-index: 99;
+ -webkit-animation: sticky 1s;
+ animation: sticky 1s;
+ -webkit-box-shadow: 2px 4px 8px rgba(51, 51, 51, 0.25);
+ box-shadow: 2px 4px 8px rgba(51, 51, 51, 0.25);
+ background-color: #fff;
+}
+@-webkit-keyframes sticky {
+ 0% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+@keyframes sticky {
+ 0% {
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+ 100% {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ }
+}
+.header-to-bar {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ color: #b5b5b5;
+ font-size: 14px;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ line-height: 50px;
+ background-color: #242424;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-weight: 300;
+}
+.header-main {
+ background-color: #fff;
+ border-bottom: 1px solid #eee;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .header-main {
+ padding: 10px 0;
+ }
+}
+.header-actions {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.header-actions > * + * {
+ margin-left: 18px;
+}
+@media only screen and (max-width: 575px) {
+ .header-actions > * + * {
+ margin-left: 15px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .header-actions > * + * {
+ margin-left: 8px;
+ }
+}
+.header-actions .header-action-btn {
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ text-decoration: none;
+ color: #000;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.header-actions .header-action-btn:hover {
+ color: #036eb8;
+}
+.header-actions .header-action-btn i {
+ -webkit-transition: 0s;
+ transition: 0s;
+ font-size: 26px;
+}
+@media only screen and (max-width: 575px) {
+ .header-actions .header-action-btn i {
+ font-size: 25px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .header-actions .header-action-btn i {
+ font-size: 22px;
+ }
+}
+.header-actions .header-action-btn i:hover {
+ color: #036eb8;
+}
+.header-actions .header-action-btn .header-action-num {
+ font-size: 11px;
+ font-weight: 700;
+ position: absolute;
+ z-index: 2;
+ top: -10px;
+ right: -7px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ color: #fff;
+ border-radius: 50%;
+ background-color: #036eb8;
+ width: 21px;
+ height: 21px;
+}
+.header-actions .header-action-btn .cart-amount {
+ display: block;
+ font-size: 16px;
+ font-weight: 700;
+ text-align: center;
+ padding-left: 15px;
+ color: #0f0f0f;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.header-actions .header-action-btn:hover .cart-amount {
+ color: #036eb8;
+}
+.main-menu {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: right;
+ margin-right: 80px;
+ float: right;
+}
+.main-menu ul {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ margin-bottom: 0;
+ padding-left: 0;
+ list-style: none;
+}
+.main-menu ul li + li {
+ margin-left: 50px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .main-menu ul li + li {
+ margin-left: 30px;
+ }
+}
+.main-menu ul li a {
+ font-size: 14px;
+ font-weight: 400;
+ text-decoration: none;
+ text-transform: uppercase;
+ color: #2d2d2d;
+ display: block;
+ position: relative;
+ line-height: 80px;
+}
+.main-menu ul li.active > a,
+.main-menu ul li:hover > a {
+ color: #036eb8 !important;
+}
+.main-menu ul li.dropdown {
+ position: relative;
+}
+.main-menu ul li.dropdown ul.sub-menu {
+ position: absolute;
+ z-index: 9;
+ text-align: left;
+ opacity: 0;
+ visibility: hidden;
+ -o-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ -moz-transform-origin: 0 0;
+ -webkit-transform-origin: 0 0;
+ transform-style: preserve-3d;
+ -o-transform-style: preserve-3d;
+ -moz-transform-style: preserve-3d;
+ -webkit-transform-style: preserve-3d;
+ transform: rotateX(-75deg);
+ -o-transform: rotateX(-75deg);
+ -moz-transform: rotateX(-75deg);
+ -webkit-transform: rotateX(-75deg);
+ min-width: 120px;
+ left: auto !important;
+ background: #fff;
+ -webkit-box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ display: block;
+ -o-transition: -o-transform 0.3s, opacity 0.3s;
+ -ms-transition: -ms-transform 0.3s, opacity 0.3s;
+ -moz-transition: -moz-transform 0.3s, opacity 0.3s;
+ -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
+ padding: 10px 0;
+}
+.main-menu ul li.dropdown ul li {
+ padding: 0;
+ margin: 0;
+ display: block;
+}
+.main-menu ul li.dropdown ul li a {
+ display: block;
+ line-height: 20px;
+ padding: 12px 0 12px 20px;
+ font-weight: 400;
+ font-size: 12px;
+ color: #2d2d2d;
+ text-transform: capitalize;
+}
+.main-menu ul li.dropdown ul li a:hover {
+ padding-left: 25px;
+}
+.main-menu ul li.dropdown:hover .sub-menu {
+ opacity: 1;
+ visibility: visible;
+ transform: rotateX(0);
+ -o-transform: rotateX(0);
+ -moz-transform: rotateX(0);
+ -webkit-transform: rotateX(0);
+ -o-transition: -o-transform 0.3s, opacity 0.3s;
+ -ms-transition: -ms-transform 0.3s, opacity 0.3s;
+ -moz-transition: -moz-transform 0.3s, opacity 0.3s;
+ -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
+}
+.main-menu ul li.dropdown:hover .mega-menu {
+ opacity: 1;
+ visibility: visible;
+ transform: rotateX(0);
+ -o-transform: rotateX(0);
+ -moz-transform: rotateX(0);
+ -webkit-transform: rotateX(0);
+ -o-transition: -o-transform 0.3s, opacity 0.3s;
+ -ms-transition: -ms-transform 0.3s, opacity 0.3s;
+ -moz-transition: -moz-transform 0.3s, opacity 0.3s;
+ -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
+}
+.main-menu ul li .mega-menu {
+ position: absolute;
+ -webkit-box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ background: #fff;
+ padding: 30px 0 30px 30px;
+ opacity: 0;
+ visibility: hidden;
+ -o-transform-origin: 0 0;
+ -ms-transform-origin: 0 0;
+ -moz-transform-origin: 0 0;
+ -webkit-transform-origin: 0 0;
+ transform-style: preserve-3d;
+ -o-transform-style: preserve-3d;
+ -moz-transform-style: preserve-3d;
+ -webkit-transform-style: preserve-3d;
+ transform: rotateX(-75deg);
+ -o-transform: rotateX(-75deg);
+ -moz-transform: rotateX(-75deg);
+ -webkit-transform: rotateX(-75deg);
+ left: 0;
+ width: 100%;
+ z-index: 2;
+ -o-transition: -o-transform 0.3s, opacity 0.3s;
+ -ms-transition: -ms-transform 0.3s, opacity 0.3s;
+ -moz-transition: -moz-transform 0.3s, opacity 0.3s;
+ -webkit-transition: -webkit-transform 0.3s, opacity 0.3s;
+ z-index: 15;
+}
+.main-menu ul li .mega-menu li ul {
+ width: 25%;
+ margin-right: 30px;
+ border-right: 1px solid #ebebeb;
+}
+.main-menu ul li .mega-menu li ul:last-child {
+ border-right: 0;
+}
+.main-menu ul li .mega-menu li ul li.title a {
+ color: #000;
+ font-size: 14px;
+ font-weight: 600;
+ display: block;
+ margin-bottom: 20px;
+ height: auto;
+ margin-top: 10px;
+}
+.main-menu ul li .mega-menu li ul li.title a:hover {
+ color: #036eb8;
+ padding-left: 0;
+}
+.main-menu ul li .mega-menu li ul li a {
+ color: #999;
+ text-transform: capitalize;
+ line-height: 20px;
+ font-weight: 400;
+ font-size: 12px;
+ display: block;
+ padding: 0;
+ border: 0;
+ height: auto;
+ margin-bottom: 8px;
+}
+.mega-menu span {
+ margin-right: 16px;
+ display: inline-block;
+}
+.mega-menu span img {
+ width: 96px;
+ height: 96px;
+ background: #f5f5f5;
+ padding: 12px;
+ border-radius: 8px;
+ -webkit-border-radius: 8px;
+ -moz-border-radius: 8px;
+ -ms-border-radius: 8px;
+ -o-border-radius: 8px;
+}
+.main-menu ul li .mega-menu li ul li a:hover {
+ color: #036eb8;
+ padding-left: 10px;
+}
+.main-menu ul li .mega-menu li ul li:last-child a {
+ margin: 0;
+}
+.header-bottom-set .dropdown-toggle {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ border: 0;
+ background-color: transparent;
+ padding: 0;
+}
+.header-bottom-set .dropdown-toggle::after {
+ display: none;
+}
+.header-bottom-set .dropdown-toggle i {
+ font-size: 29px;
+}
+.header-bottom-set .dropdown-menu {
+ margin: 0;
+ top: 40px !important;
+ left: auto !important;
+ right: 0;
+ min-width: 130px;
+ overflow: hidden;
+ padding: 0 15px;
+ background: #fff;
+ border-radius: 0;
+ border: 0;
+ -webkit-box-shadow: 0 3px 25.5px 4.5px rgba(0, 0, 0, 0.06);
+ box-shadow: 0 3px 25.5px 4.5px rgba(0, 0, 0, 0.06);
+ -webkit-transform: translate3d(0, 0, 0) !important;
+ transform: translate3d(0, 0, 0) !important;
+ inset: 40px 0 auto auto !important;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .header-bottom-set .dropdown-menu {
+ top: 48px !important;
+ inset: 48px 0 auto auto !important;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .header-bottom-set .dropdown-menu {
+ top: 46px !important;
+ inset: 46px 0 auto auto !important;
+ }
+}
+.header-bottom-set .dropdown-menu li {
+ border-bottom: 1px solid #ebebeb;
+}
+.header-bottom-set .dropdown-menu li:last-child {
+ border: 0;
+}
+.header-bottom-set .dropdown-menu .dropdown-item {
+ padding: 10px;
+ color: #2d2d2d;
+ line-height: 25px;
+ font-size: 14px;
+ background: 0;
+}
+.header-bottom-set .dropdown-menu .dropdown-item:hover {
+ color: #036eb8;
+}
+.action-form {
+ position: relative;
+}
+.submit {
+ position: absolute;
+ top: 0;
+ left: auto;
+ right: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ width: 60px;
+ height: 100%;
+ background: #036eb8;
+ color: #fff;
+ font-size: 20px;
+ border-radius: 0 5px 5px 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ outline: 0;
+}
+body.offcanvas-open {
+ overflow: hidden;
+}
+.offcanvas {
+ font-size: 14px;
+ font-weight: 400;
+ position: fixed;
+ z-index: 1000;
+ top: 0;
+ right: 0;
+ left: auto;
+ display: block;
+ width: 400px;
+ height: 100%;
+ padding: 20px;
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: translateX(100%);
+ transform: translateX(100%);
+ background-color: #fff;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ overflow: auto;
+ visibility: visible;
+}
+@media only screen and (max-width: 479px) {
+ .offcanvas {
+ width: 300px;
+ }
+}
+.offcanvas .inner {
+ position: relative;
+ z-index: 9;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ height: 100%;
+}
+.offcanvas .inner .head {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ width: 100%;
+ padding: 30px 20px;
+}
+.offcanvas .inner .head .title {
+ color: #000;
+ font-weight: 700;
+}
+.offcanvas .inner .head .offcanvas-close {
+ position: relative;
+ width: 20px;
+ height: 20px;
+ text-indent: -9999px;
+ border: 0;
+ background-color: transparent;
+}
+.offcanvas .inner .head .offcanvas-close::after {
+ position: absolute;
+ top: calc(50% - 1px);
+ left: 0;
+ width: 20px;
+ height: 2px;
+ content: '';
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ background-color: #036eb8;
+}
+.offcanvas .inner .head .offcanvas-close::before {
+ position: absolute;
+ top: calc(50% - 1px);
+ left: 0;
+ width: 20px;
+ height: 2px;
+ content: '';
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ background-color: #036eb8;
+}
+.offcanvas .inner .head .offcanvas-close:hover:before {
+ -webkit-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.offcanvas .inner .head .offcanvas-close:hover:after {
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+}
+.offcanvas .inner .offcanvas-menu ul li {
+ position: relative;
+ display: block;
+ line-height: 28px;
+}
+.offcanvas .inner .offcanvas-menu ul li a {
+ display: block;
+ padding: 10px 0;
+ text-transform: capitalize;
+ color: #474747;
+ border-top: 1px solid #eee;
+ font-size: 16px;
+ font-weight: 600;
+}
+.offcanvas .inner .offcanvas-menu ul li .sub-menu {
+ position: static;
+ top: auto;
+ display: none;
+ visibility: visible;
+ width: 100%;
+ min-width: auto;
+ padding: 0;
+ -webkit-transition: none;
+ transition: none;
+ opacity: 1;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.offcanvas .inner .offcanvas-menu ul li .sub-menu li {
+ line-height: inherit;
+ position: relative;
+}
+.offcanvas .inner .offcanvas-menu ul li .sub-menu li a {
+ text-transform: capitalize;
+ font-weight: 400;
+ padding-left: 10px;
+ padding-right: 0;
+ display: block;
+ border-top: 1px solid #eee;
+ font-size: 14px;
+ font-weight: 500;
+}
+.offcanvas .inner .offcanvas-menu ul li .sub-menu li:last-child {
+ border-bottom: 0 solid #eee;
+}
+.offcanvas .inner .offcanvas-menu ul li .menu-expand {
+ position: absolute;
+ z-index: 2;
+ top: 0;
+ right: 0;
+ width: 24px;
+ height: 49px;
+ cursor: pointer;
+ background-color: transparent;
+}
+.offcanvas .inner .offcanvas-menu ul li:hover > a {
+ color: #036eb8;
+}
+.offcanvas .inner .offcanvas-menu ul li:hover > span.menu-expand:before {
+ background: #036eb8;
+}
+.offcanvas .inner .offcanvas-menu ul li:hover > span.menu-expand:after {
+ background: #036eb8;
+}
+.offcanvas .inner .offcanvas-menu ul li:last-child {
+ border-bottom: 1px solid #eee;
+}
+.offcanvas .inner .offcanvas-social li {
+ display: inline-block;
+ margin: 0 10px 0 0;
+ line-height: 40px;
+ padding: 0;
+}
+@media only screen and (max-width: 479px) {
+ .offcanvas .inner .offcanvas-social li {
+ margin: 0 5px 0 0;
+ }
+}
+.offcanvas .inner .offcanvas-social li a {
+ position: relative;
+ display: inline-block;
+ vertical-align: middle;
+ color: #fff;
+ background: #036eb8;
+ font-size: 16px;
+ padding: 0;
+ line-height: 40px;
+ width: 40px;
+ height: 40px;
+ border-radius: 100%;
+ text-align: center;
+ border: 0;
+ z-index: 1;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+}
+.offcanvas .inner .offcanvas-social li a:hover {
+ background: #000;
+ color: #fff;
+}
+@media only screen and (max-width: 479px) {
+ .offcanvas .inner .offcanvas-social li a {
+ line-height: 35px;
+ width: 35px;
+ height: 35px;
+ font-size: 15px;
+ }
+}
+.offcanvas .inner .foot .buttons a {
+ display: block;
+ text-transform: capitalize;
+ font-weight: 500;
+ font-size: 16px;
+ border: 0;
+ color: #fff;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ padding: 10px 15px;
+ line-height: 26px;
+ border: 0;
+ background: #000;
+ border-radius: 0;
+ width: auto;
+ height: auto;
+}
+.offcanvas .inner .foot .buttons a:hover {
+ background-color: #036eb8;
+ color: #fff;
+}
+.offcanvas .inner .foot .buttons .current-btn {
+ background-color: #036eb8;
+ color: #fff;
+}
+.offcanvas .inner .foot .sub-total {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ border-top: 1px solid #eee;
+ margin: 30px 0 0 0;
+}
+.offcanvas .inner .foot .sub-total .table > :not(caption) > * > * {
+ padding: 0;
+ border: 0;
+}
+.offcanvas .inner .foot .sub-total .table > tbody > tr > td {
+ border: 0;
+ padding: 0;
+ color: #000;
+ text-transform: capitalize;
+ font-size: 20px;
+ vertical-align: middle;
+ font-weight: 500;
+ line-height: 30px;
+}
+.offcanvas .inner .foot .sub-total .table > tbody > tr > td.theme-color {
+ color: #036eb8;
+}
+.offcanvas .inner .foot .sub-total .amount {
+ color: #eb2606;
+ font-weight: 600;
+}
+.offcanvas .inner .foot .minicart-message {
+ margin-top: 30px;
+ margin-bottom: 30px;
+}
+.offcanvas-menu > ul > li .menu-expand {
+ position: absolute;
+ z-index: 2;
+ top: 0;
+ right: 0;
+ width: 24px;
+ height: 44px;
+ cursor: pointer;
+ background-color: transparent;
+}
+.offcanvas-menu > ul.sub-menu > li .menu-expand {
+ right: 15px;
+}
+.offcanvas.offcanvas-mobile-menu {
+ right: auto;
+ left: 0;
+ padding: 0;
+ -webkit-transform: translateX(-100%);
+ transform: translateX(-100%);
+ width: 350px;
+ padding: 50px 30px;
+}
+@media only screen and (max-width: 479px) {
+ .offcanvas.offcanvas-mobile-menu {
+ width: 300px;
+ }
+}
+.offcanvas.offcanvas-mobile-menu .offcanvas-close {
+ position: absolute;
+ width: 40px;
+ height: 40px;
+ text-indent: -9999px;
+ border: 0;
+ left: 0;
+ top: 5px;
+ background-color: #036eb8;
+ -webkit-animation-delay: 0.5s;
+ animation-delay: 0.5s;
+ border-radius: 50%;
+}
+.offcanvas.offcanvas-mobile-menu .offcanvas-close::after {
+ position: absolute;
+ top: calc(50% - 1px);
+ left: 50%;
+ margin-left: -10px;
+ width: 20px;
+ height: 2px;
+ content: '';
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: rotate(-45deg);
+ transform: rotate(-45deg);
+ background-color: #fff;
+}
+.offcanvas.offcanvas-mobile-menu .offcanvas-close::before {
+ position: absolute;
+ top: calc(50% - 1px);
+ left: 50%;
+ margin-left: -10px;
+ width: 20px;
+ height: 2px;
+ content: '';
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: rotate(45deg);
+ transform: rotate(45deg);
+ background-color: #fff;
+}
+.offcanvas.offcanvas-mobile-menu .offcanvas-close:hover:before {
+ -webkit-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.offcanvas.offcanvas-mobile-menu .offcanvas-close:hover:after {
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+}
+.offcanvas.offcanvas-cart .inner .head,
+.offcanvas.offcanvas-wishlist .inner .head {
+ margin-bottom: 30px;
+ padding: 0;
+}
+.offcanvas.offcanvas-cart .inner .head .title,
+.offcanvas.offcanvas-wishlist .inner .head .title {
+ font-size: 20px;
+}
+.offcanvas-menu > ul > li .menu-expand::after,
+.offcanvas-menu > ul > li .menu-expand::before {
+ position: absolute;
+ top: calc(50% - 1px);
+ left: calc(50% - 7px);
+ width: 14px;
+ height: 2px;
+ content: '';
+ -webkit-transition: all 0.5s ease 0s;
+ transition: all 0.5s ease 0s;
+ -webkit-transform: scale(0.75);
+ transform: scale(0.75);
+ background-color: #000;
+}
+.offcanvas-menu > ul > li .menu-expand::after {
+ -webkit-transform: rotate(90deg) scale(0.75);
+ transform: rotate(90deg) scale(0.75);
+}
+.offcanvas-menu > ul > li.active > .menu-expand::after {
+ -webkit-transform: rotate(0) scale(0.75);
+ transform: rotate(0) scale(0.75);
+}
+.offcanvas-menu > ul > li .sub-menu li.active > .menu-expand::after {
+ -webkit-transform: rotate(0) scale(0.75);
+ transform: rotate(0) scale(0.75);
+}
+.offcanvas.offcanvas-mobile-menu.offcanvas-open {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+}
+.offcanvas.offcanvas-mobile-menu.offcanvas-open .offcanvas-close {
+ left: 80%;
+}
+.offcanvas-overlay {
+ position: fixed;
+ z-index: 999;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ display: none;
+ background-color: rgba(0, 0, 0, 0.5);
+}
+.offcanvas.offcanvas-open {
+ -webkit-transform: translateX(0);
+ transform: translateX(0);
+}
+.minicart-product-list {
+ margin: 0;
+ padding-left: 0;
+ list-style: none;
+}
+.minicart-product-list li {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ margin-bottom: 30px;
+ padding-bottom: 30px;
+ border-bottom: 1px solid #ebebeb;
+}
+.minicart-product-list li .image {
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 75px;
+ flex: 1 0 75px;
+}
+.minicart-product-list li .image img {
+ max-width: 100%;
+ border: 1px solid #ebebeb;
+}
+@media only screen and (max-width: 575px) {
+ .minicart-product-list li .image {
+ -ms-flex: 1 0 50px;
+ -webkit-box-flex: 1;
+ flex: 1 0 50px;
+ }
+}
+.minicart-product-list li .content {
+ position: relative;
+ -webkit-box-flex: 1;
+ -ms-flex: 1 0 calc(100% - 150px);
+ flex: 1 0 calc(100% - 150px);
+ padding-left: 15px;
+}
+.minicart-product-list li .content .title {
+ color: #000;
+ font-weight: 500;
+}
+.minicart-product-list li .content .title:hover {
+ color: #036eb8;
+}
+.minicart-product-list li .content .quantity-price {
+ font-size: 14px;
+ display: block;
+ margin-top: 10px;
+}
+.minicart-product-list li .content .quantity-price .amount {
+ color: #036eb8;
+ font-weight: 500;
+ font-size: 18px;
+}
+.minicart-product-list li .content .remove {
+ line-height: 1.5;
+ position: absolute;
+ top: 0;
+ right: 0;
+ padding: 0 3px;
+ color: #000;
+ font-size: 16px;
+}
+.minicart-product-list li .content .remove:hover {
+ color: #eb2606;
+}
+@media only screen and (max-width: 575px) {
+ .minicart-product-list li .content {
+ -ms-flex: 1 0 calc(100% - 75px);
+ -webkit-box-flex: 1;
+ flex: 1 0 calc(100% - 75px);
+ }
+}
+.minicart-product-list li:last-child {
+ margin-bottom: 0;
+ padding-bottom: 0;
+ border-bottom: 0;
+}
+.bg-color1 {
+ background-color: #f5f5f5;
+}
+.bg-color2 {
+ background-color: #cebdb5;
+}
+.bg-color3 {
+ background-color: #cebdb5;
+}
+.slider-height {
+ height: 771px;
+}
+@media only screen and (min-width: 1200px) and (max-width: 1599px) {
+ .slider-height {
+ height: 700px;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .slider-height {
+ height: 550px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-height {
+ height: 500px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .slider-height {
+ height: 450px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .slider-height {
+ height: 650px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .slider-height {
+ height: 600px;
+ }
+}
+.ptb-30px {
+ padding: 30px 0;
+}
+.pl-80px {
+ padding-left: 80px;
+}
+.slider-height-2 {
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center;
+ height: 513px;
+}
+@media only screen and (min-width: 1200px) and (max-width: 1599px) {
+ .slider-height-2 {
+ height: 500px;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .slider-height-2 {
+ height: 500px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-height-2 {
+ height: 500px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .slider-height-2 {
+ height: 500px;
+ }
+}
+.hero-slide-image {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: end;
+ -ms-flex-align: end;
+ align-items: flex-end;
+}
+.hero-slide-image img {
+ max-width: 100%;
+ -webkit-animation-duration: 1s;
+ animation-duration: 1s;
+ -webkit-animation-fill-mode: both;
+ animation-fill-mode: both;
+ -webkit-animation-name: fadeOutUp;
+ animation-name: fadeOutUp;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .hero-slide-image img {
+ width: 80%;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .hero-slide-image img {
+ width: 60%;
+ margin: auto;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .hero-slide-image img {
+ width: 70%;
+ margin: auto;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .hero-slide-image {
+ margin-top: 50px;
+ text-align: center;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .sm-center-view {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+}
+.swiper-slide-active .hero-slide-image img {
+ -webkit-animation-name: fadeInUp;
+ animation-name: fadeInUp;
+ -webkit-animation-delay: 1s;
+ animation-delay: 1s;
+}
+.hero-slide-content {
+ position: relative;
+ z-index: 9;
+ text-transform: capitalize;
+ text-align: center;
+}
+.hero-slide-content .category {
+ display: block;
+ font-size: 36px;
+ color: #036eb8;
+ margin: 0;
+ font-weight: 400;
+}
+.hero-slide-content .title-1 {
+ font-size: 60px;
+ font-weight: 500;
+ margin-bottom: 22px;
+ color: #4a4a4a;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .hero-slide-content .title-1 {
+ font-size: 56px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .hero-slide-content .title-1 {
+ font-size: 42px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .hero-slide-content .title-1 {
+ font-size: 30px;
+ margin-bottom: 15px;
+ }
+}
+.hero-slide-content .price {
+ font-size: 36px;
+ font-weight: 500;
+ margin-bottom: 37px;
+ color: #4a4a4a;
+ display: block;
+}
+.hero-slide-content .price .new {
+ color: #036eb8;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .hero-slide-content .price {
+ font-size: 30px;
+ margin-bottom: 30px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .hero-slide-content .price {
+ font-size: 24px;
+ margin-bottom: 25px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .hero-slide-content .btn {
+ width: 150px;
+ height: 50px;
+ font-size: 14px;
+ }
+}
+.hero-slide-content .btn i {
+ font-size: 16px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .hero-slide-content .btn i {
+ font-size: 14px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .hero-slide-content.hero-slide-content-2.pl-80px {
+ padding-left: 30px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .hero-slide-content.hero-slide-content-2 .category {
+ font-size: 24px;
+ margin-bottom: 10px;
+ }
+}
+.hero-slide-content.hero-slide-content-2 .title-1 {
+ text-transform: capitalize;
+ font-weight: 400;
+ margin-bottom: 37px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .hero-slide-content.hero-slide-content-2 .title-1 {
+ font-size: 54px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .hero-slide-content.hero-slide-content-2 .title-1 {
+ font-size: 48px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .hero-slide-content.hero-slide-content-2 .title-1 {
+ font-size: 40px;
+ }
+}
+.hero-slide-content.hero-slide-content-2 .btn-primary {
+ width: 160px;
+ height: 55px;
+}
+@media only screen and (max-width: 575px) {
+ .show-case {
+ position: relative;
+ }
+}
+.newsletter-area {
+ background-color: #fff;
+ color: #fff;
+ line-height: 1;
+ padding: 48px 0;
+}
+@media only screen and (max-width: 1400px) {
+ .newsletter-area {
+ padding: 24px 0;
+ width: 94%;
+ }
+}
+.newsletter-area .newsletter-content {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .newsletter-area .newsletter-content {
+ margin: 0 0 30px;
+ }
+}
+.newsletter-area .newsletter-content i {
+ font-size: 60px;
+ color: #036eb8;
+ margin-right: 30px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .newsletter-area .newsletter-content i {
+ margin-bottom: 15px;
+ margin-right: 20px;
+ }
+}
+.newsletter-area .newsletter-content .newsletter-text .title {
+ font-size: 24px;
+ font-weight: 400;
+ color: #fff;
+ margin: 0 0 10px;
+}
+.newsletter-area .newsletter-content .newsletter-text p {
+ font-size: 16px;
+ color: #a1a1a1;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (max-width: 479px) {
+ .newsletter-area .newsletter-content .newsletter-text p {
+ font-size: 14px;
+ }
+}
+.newsletter-area .news-letter-form .subscribe-form {
+ position: relative;
+}
+.newsletter-area .news-letter-form .subscribe-form input {
+ height: 52px;
+ font-size: 14px;
+ border: 0;
+ background-color: #f5f5f5;
+ color: #B2B2B2f;
+ border-radius: 5px 5px 5px 5px;
+ padding-right: 130px;
+}
+@media only screen and (max-width: 479px) {
+ .newsletter-area .news-letter-form .subscribe-form input {
+ padding-right: 105px;
+ }
+}
+.newsletter-area .news-letter-form .subscribe-form input::-webkit-input-placeholder {
+ color: #a1a1a1;
+}
+.newsletter-area .news-letter-form .subscribe-form input::-moz-placeholder {
+ color: #a1a1a1;
+}
+.newsletter-area .news-letter-form .subscribe-form input:-ms-input-placeholder {
+ color: #a1a1a1;
+}
+.newsletter-area .news-letter-form .subscribe-form input::-ms-input-placeholder {
+ color: #a1a1a1;
+}
+.newsletter-area .news-letter-form .subscribe-form input::placeholder {
+ color: #a1a1a1;
+}
+.newsletter-area .news-letter-form .subscribe-form button {
+ height: 52px;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 126px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ font-size: 14px;
+ color: #fff;
+ font-weight: 500;
+ text-transform: uppercase;
+ background-color: #036eb8;
+ border-radius: 0 5px 5px 0;
+ z-index: 1;
+ overflow: hidden;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+@media only screen and (max-width: 479px) {
+ .newsletter-area .news-letter-form .subscribe-form button {
+ width: 100px;
+ }
+}
+.newsletter-area .news-letter-form .subscribe-form button::before {
+ position: absolute;
+ content: '';
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: #000;
+ z-index: -1;
+ -webkit-transition: 0.3s linear;
+ transition: 0.3s linear;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ border-radius: 50%;
+ width: 100%;
+ height: 100%;
+}
+.newsletter-area .news-letter-form .subscribe-form button:hover::before {
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5);
+}
+.line-shape-bottom {
+ position: relative;
+}
+.line-shape-bottom::after {
+ position: absolute;
+ top: auto;
+ left: 0;
+ width: 100%;
+ max-width: 1170px;
+ height: 1px;
+ content: '';
+ background-color: #454545;
+ margin: auto;
+ bottom: -60px;
+ right: 0;
+}
+.line-shape {
+ position: relative;
+}
+.line-shape::after {
+ position: absolute;
+ top: 10px;
+ left: 20px;
+ height: 100%;
+ width: 1px;
+ content: '';
+ background-color: #454545;
+ margin: auto;
+ bottom: 0;
+}
+.payment-img {
+ margin: 0 0 2em 10px;
+ padding: 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .line-shape::after {
+ left: 10px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .line-shape::after {
+ display: none;
+ }
+}
+.line-shape-top {
+ border-top: 1px solid #eee;
+ margin: 25px 0 25px 0;
+}
+.line-footer-top {
+ border-top: 1px solid #eee;
+ padding: 25px 0 25px 0;
+}
+.pl-120px {
+ padding-left: 120px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .pl-120px {
+ padding-left: 40px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .pl-120px {
+ padding-left: 12px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .pl-120px {
+ padding-left: 12px;
+ padding-top: 0;
+ padding-bottom: 20px;
+ }
+}
+.footer-area {
+ color: #333;
+ border-top: 1px solid #eee;
+}
+.footer-area .footer-top {
+ padding: 60px 0 55px 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .footer-area .footer-top {
+ padding: 60px 0 0 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .footer-area .footer-top {
+ padding: 60px 0 0 0;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .footer-area .footer-top {
+ padding: 50px 0 0 0;
+ }
+}
+.img-weixin {
+ box-shadow: 0px 0px 20px #e8e9eb;
+ border-radius: 8px;
+ width: 60%;
+ padding: 12px;
+}
+.img-weixin p {
+ text-align: center;
+ line-height: 40px;
+}
+.footer-area .footer-top .single-wedge .footer-logo {
+ margin: 0 0 27px;
+}
+.footer-area .footer-top .single-wedge .footer-herading {
+ font-size: 14px;
+ text-transform: capitalize;
+ position: relative;
+ color: #333;
+}
+.footer-area .footer-top .single-wedge .footer-links li {
+ display: block;
+ margin: 0;
+ line-height: 1;
+ border: 0;
+ font-weight: 400;
+}
+.footer-area .footer-top .single-wedge .footer-links .single-link {
+ font-size: 12px;
+ line-height: 22px;
+ padding: 0;
+ display: inline-block;
+ text-transform: capitalize;
+ color: #999;
+ margin-bottom: 0;
+ display: inline-block;
+ position: relative;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+}
+.footer-area .footer-top .single-wedge .footer-links .single-link:hover {
+ padding-left: 10px;
+ color: #036eb8;
+}
+.footer-area .footer-top .single-wedge .footer-links p {
+ margin: 0 0 25px;
+ font-weight: 400;
+ color: #036eb8;
+ font-size: 24px;
+}
+@media only screen and (max-width: 767px) {
+ .footer-area .footer-top .single-wedge .footer-links p.mail br {
+ display: none;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .footer-area .footer-top .single-wedge .footer-links p.mail a {
+ font-size: 24px;
+ }
+ .footer-area .footer-top .single-wedge .footer-links p {
+ font-size: 14px;
+ }
+}
+.footer-area .footer-top .single-wedge .footer-links p a {
+ color: #036eb8;
+ font-weight: 500;
+}
+.footer-area .footer-top .single-wedge .footer-links p a:hover {
+ color: #036eb8;
+}
+.footer-area .footer-top .single-wedge .footer-links p.address,
+.footer-area .footer-top .single-wedge .footer-links p.phone {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.footer-area .footer-top .single-wedge .footer-links p.address i,
+.footer-area .footer-top .single-wedge .footer-links p.phone i {
+ font-size: 36px;
+ color: #036eb8;
+ margin-right: 20px;
+}
+.footer-area .footer-top .single-wedge .footer-links p.address a,
+.footer-area .footer-top .single-wedge .footer-links p.phone a {
+ font-weight: 600;
+ color: #036eb8;
+}
+.footer-area .footer-top .single-wedge .footer-links p.address a:hover,
+.footer-area .footer-top .single-wedge .footer-links p.phone a:hover {
+ color: #036eb8;
+}
+.footer-bottom {
+ line-height: 1;
+}
+.footer-bottom .copy-text {
+ color: #a1a1a1;
+ font-size: 12px;
+ line-height: 22px;
+ text-align: center;
+}
+@media only screen and (max-width: 767px) {
+ .footer-bottom .copy-text {
+ margin-top: 15px;
+ }
+}
+.footer-bottom .copy-text .company-name {
+ color: #a1a1a1;
+}
+.footer-bottom .copy-text .company-name:hover {
+ color: #036eb8;
+}
+.footer-bottom .copy-text i {
+ color: red;
+ margin: 0 3px;
+ font-size: 16px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .mb-lg-30px {
+ margin-bottom: 30px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .mb-md-30px {
+ margin-bottom: 30px;
+ }
+ .mt-md-30px {
+ margin-top: 30px;
+ }
+ .mt-md-50px {
+ margin-top: 50px;
+ }
+ .mb-md-60px {
+ margin-bottom: 60px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .mb-lm-30px {
+ margin-bottom: 30px;
+ }
+ .mt-lm-50px {
+ margin-top: 50px;
+ }
+ .mt-lm-30px {
+ margin-top: 24px;
+ }
+ .mt-lm-20px {
+ margin-top: 20px;
+ }
+ .mb-lm-20px {
+ margin-bottom: 20px;
+ }
+ .mb-lm-60px {
+ margin-bottom: 60px;
+ }
+ .mb-lm-30px {
+ margin-bottom: 30px;
+ }
+ .mb-lm-10px {
+ margin-bottom: 10px;
+ }
+ .mb-lm-15px {
+ margin-bottom: 15px;
+ }
+ .mt-lm-15px {
+ margin-top: 15px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .mb-xs-30px {
+ margin-bottom: 30px;
+ }
+ .mb-xs-15px {
+ margin-bottom: 15px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .mb-es-30px {
+ margin-bottom: 30px;
+ }
+}
+.modal-dialog {
+ margin: 0 auto;
+ max-width: 960px;
+ width: 960px;
+ padding: 35px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .modal-dialog {
+ max-width: 720px;
+ width: 720px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .modal-dialog {
+ width: 98%;
+ max-width: 100%;
+ padding: 35px 0;
+ margin: auto 2%;
+ }
+}
+.modal-dialog .gallery-thumbs {
+ width: 100%;
+ margin: 20px auto;
+}
+.modal-dialog .gallery-thumbs .swiper-slide img {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ border: 1px solid transparent;
+ border-radius: 5px;
+}
+.modal-dialog .gallery-thumbs .swiper-slide:hover img {
+ border-color: #036eb8;
+}
+.modal-dialog .gallery-thumbs .swiper-slide.swiper-slide-thumb-active img {
+ border-color: #036eb8;
+}
+.modal-dialog .gallery-thumbs .swiper-slide .img-responsive {
+ width: auto;
+}
+.modal-dialog .social-info ul {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}
+.modal.fade {
+ display: block !important;
+ opacity: 0;
+ visibility: hidden;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.modal.fade.show {
+ display: block !important;
+ opacity: 1;
+ visibility: visible;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.shop-category-area .shop-top-bar {
+ margin-bottom: 40px;
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-size: 16px;
+ border-radius: 10px;
+}
+@media only screen and (max-width: 767px) {
+ .shop-category-area .shop-top-bar > * {
+ margin-bottom: 20px;
+ }
+}
+.shop-category-area .shop-top-bar .compare-product {
+ color: #6c6c6c;
+ height: 40px;
+ width: 230px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border: 1px solid #d5d5d5;
+ border-radius: 5px;
+ background-color: #fff;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .shop-category-area .shop-top-bar .compare-product {
+ width: 190px;
+ }
+}
+.shop-category-area .shop-top-bar .compare-product span {
+ margin-left: 5px;
+ color: #036eb8;
+}
+@media only screen and (max-width: 767px) {
+ .shop-category-area .shop-top-bar.d-flex {
+ display: block !important;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .desktop-tab {
+ display: none;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .desktop-tab {
+ display: block;
+ }
+}
+.mobile-tab {
+ display: none;
+}
+@media only screen and (max-width: 767px) {
+ .mobile-tab {
+ display: block;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .mobile-tab {
+ display: none;
+ }
+}
+.mobile-view {
+ display: none;
+}
+@media only screen and (max-width: 767px) {
+ .mobile-view {
+ display: block;
+ }
+}
+.shop-tab {
+ line-height: 1;
+}
+.shop-tab a + a {
+ margin-left: 15px;
+}
+.shop-tab a {
+ font-size: 18px;
+ color: #9e9e9e;
+ width: 40px;
+ height: 40px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border: 1px solid #d5d5d5;
+ border-radius: 5px;
+ background-color: #fff;
+}
+.shop-tab a.active {
+ background-color: #036eb8;
+ color: #fff;
+ border-color: #036eb8;
+}
+@media only screen and (max-width: 767px) {
+ .shop-tab {
+ margin-top: 15px;
+ margin-bottom: 5px;
+ }
+}
+.shot-product p {
+ color: #6c6c6c;
+}
+.shop-select {
+ border: 1px solid #d5d5d5;
+ margin-left: 10px;
+ border-radius: 5px;
+ height: 40px;
+}
+.shop-select.show {
+ height: 40px;
+}
+.shop-select.show .nice-select {
+ max-width: 64px;
+ width: 64px;
+ padding-right: 10px;
+}
+.shop-select.show .nice-select:after {
+ right: 10px;
+}
+.shop-select .nice-select {
+ -webkit-tap-highlight-color: transparent;
+ background-color: transparent;
+ border-radius: 0;
+ border: solid 1px transparent;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ clear: both;
+ cursor: pointer;
+ display: block;
+ float: left;
+ font-family: Rubik, sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ height: 40px;
+ line-height: 40px;
+ outline: 0;
+ padding-left: 10px;
+ padding-right: 30px;
+ position: relative;
+ text-align: left !important;
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ white-space: nowrap;
+ max-width: 200px;
+ width: 200px;
+ color: #6c6c6c;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .shop-select .nice-select {
+ max-width: 170px;
+ width: 170px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .shop-select .nice-select {
+ max-width: 200px;
+ }
+}
+.shop-select .nice-select .current {
+ color: #090909;
+}
+.shop-select .nice-select:after {
+ border: 0;
+ content: '';
+ display: inline-block;
+ font-family: FontAwesome;
+ height: auto;
+ margin-top: 0;
+ pointer-events: none;
+ position: absolute;
+ right: 20px;
+ top: auto;
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+ -webkit-transition: all 0.15s ease-in-out;
+ transition: all 0.15s ease-in-out;
+ width: auto;
+ color: #036eb8;
+ font-size: 16px;
+}
+.shop-select .nice-select .list {
+ background-color: #fff;
+ border-radius: 0;
+ -webkit-box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
+ box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-top: 5px;
+ opacity: 0;
+ overflow: hidden;
+ padding: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 100%;
+ left: 0;
+ -webkit-transform-origin: 50% 0;
+ transform-origin: 50% 0;
+ -webkit-transform: scale(0.75) translate(-21px);
+ transform: scale(0.75) translate(-21px);
+ -webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ z-index: 15;
+ width: 100%;
+ color: #090909;
+ font-size: 16px;
+}
+.shop-select .nice-select.open .list {
+ opacity: 1;
+ pointer-events: auto;
+ -webkit-transform: scale(1) translate(0);
+ transform: scale(1) translate(0);
+}
+.shop-sidebar-wrap .sidebar-widget-search {
+ margin: 0 0 40px;
+ position: relative;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field {
+ border: 1px solid #cfcfcf;
+ background-color: #f9f9f9;
+ border-radius: 10px;
+ width: 100%;
+ height: 60px;
+ padding-left: 15px;
+ padding-right: 75px;
+ font-size: 16px;
+ font-style: italic;
+ color: #969696;
+ background-color: transparent;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field::-webkit-input-placeholder {
+ color: #969696;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field::-moz-placeholder {
+ color: #969696;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field:-ms-input-placeholder {
+ color: #969696;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field::-ms-input-placeholder {
+ color: #969696;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .input-field::placeholder {
+ color: #969696;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .widgets-searchbox-btn {
+ background-color: transparent;
+ border: 0;
+ border-left: 1px solid #cfcfcf;
+ position: absolute;
+ top: 50%;
+ right: 0;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ font-size: 18px;
+ padding-left: 15px;
+ padding-right: 15px;
+ color: #cfcfcf;
+ line-height: 1;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.shop-sidebar-wrap .sidebar-widget-search #widgets-searchbox .widgets-searchbox-btn:hover {
+ color: #036eb8;
+}
+.shop-sidebar-wrap .sidebar-widget-category,
+.shop-sidebar-wrap .sidebar-widget-color,
+.shop-sidebar-wrap .sidebar-widget-size {
+ padding-bottom: 23px;
+ padding-left: 30px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .shop-sidebar-wrap .sidebar-widget-category,
+ .shop-sidebar-wrap .sidebar-widget-color,
+ .shop-sidebar-wrap .sidebar-widget-size {
+ padding-left: 20px;
+ }
+}
+.shop-sidebar-wrap .sidebar-widget-category li a,
+.shop-sidebar-wrap .sidebar-widget-color li a,
+.shop-sidebar-wrap .sidebar-widget-size li a {
+ color: #6a6a6a;
+ font-size: 16px;
+ display: inline-block;
+ margin-top: 18px;
+}
+.shop-sidebar-wrap .sidebar-widget-category li a:hover,
+.shop-sidebar-wrap .sidebar-widget-color li a:hover,
+.shop-sidebar-wrap .sidebar-widget-size li a:hover {
+ color: #036eb8;
+}
+.shop-sidebar-wrap .sidebar-widget {
+ background-color: #fff;
+ border-radius: 10px;
+ margin: 0 0 40px;
+ border: 1px solid #f3f3f3;
+}
+.shop-sidebar-wrap .sidebar-widget h4 {
+ font-size: 24px;
+ display: block;
+ text-transform: capitalize;
+ font-weight: 400;
+ color: #6c6c6c;
+ margin: 0 0 24px;
+ padding: 14px 0 15px 28px;
+ background: #f3f3f3;
+}
+.shop-sidebar-wrap .sidebar-widget .price-slider-amount input {
+ color: #656565;
+ font-size: 16px;
+ border: 0;
+}
+.shop-sidebar-wrap .sidebar-widget .price-filter {
+ padding: 0 25px 37px 29px;
+}
+.shop-sidebar-wrap .sidebar-widget .ui-widget-content {
+ border: 1px solid #036eb8;
+}
+.shop-sidebar-wrap .sidebar-widget .ui-slider-horizontal {
+ height: 3px;
+ margin: 15px 0 0;
+}
+.shop-sidebar-wrap .sidebar-widget .ui-widget-header {
+ background: #036eb8;
+}
+.shop-sidebar-wrap .sidebar-widget .ui-slider-handle {
+ top: 50%;
+ width: 16px;
+ height: 16px;
+ background: #fff;
+ border-radius: 100%;
+ outline: 0;
+ margin-top: -8px;
+ border: 5px solid #036eb8;
+ cursor: pointer;
+ -webkit-transition: 0.3s;
+ transition: 0.3s;
+}
+.shop-sidebar-wrap .sidebar-widget .ui-slider-handle.ui-state-hover {
+ background: #036eb8;
+}
+.shop-sidebar-wrap .sidebar-widget-tag {
+ padding: 0 0 10px 15px;
+}
+.shop-sidebar-wrap .sidebar-widget-tag li {
+ line-height: 1;
+ display: inline-block;
+ margin: 8px 0;
+}
+.shop-sidebar-wrap .sidebar-widget-tag li a {
+ display: block;
+ float: left;
+ padding: 8px 17px;
+ font-size: 16px;
+ color: #7e7e7e;
+ font-weight: 400;
+ border: 1px solid #f3f3f3;
+ border-radius: 5px;
+ background: 0;
+ text-transform: capitalize;
+ margin-left: 15px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .shop-sidebar-wrap .sidebar-widget-tag li a {
+ padding: 8px 14px;
+ font-size: 14px;
+ margin-left: 5px;
+ }
+}
+.shop-sidebar-wrap .sidebar-widget-tag li a:hover {
+ background-color: #036eb8;
+ border-color: #036eb8;
+ color: #fff;
+}
+.sidebar-widget-image {
+ margin: 0 0 40px;
+}
+.sidebar-widget-image .single-banner {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ border-radius: 10px;
+}
+.sidebar-widget-image .single-banner img {
+ width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.sidebar-widget-image .single-banner:hover img {
+ -webkit-transform: scale(1.1) rotate(1deg);
+ transform: scale(1.1) rotate(1deg);
+}
+.shop-list-wrapper .content-desc-wrap .content {
+ position: relative;
+ z-index: 10;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding: 24px 0 10px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ background-color: #fff;
+ border-bottom: 1px solid #eee;
+}
+.download-text {
+ padding: 24px 0;
+ font-size: 14px;
+}
+.download-text b {
+ position: relative;
+ width: 100%;
+ padding-left: 14px;
+}
+.download-text p {
+ padding-left: 14px;
+ color: #666;
+}
+.download-text b::before {
+ content: '';
+ position: absolute;
+ background: #036eb8;
+ width: 6px;
+ height: 6px;
+ left: 0;
+ top: 5px;
+}
+@media only screen and (max-width: 767px) {
+ .shop-list-wrapper .content-desc-wrap .content {
+ margin-top: 0;
+ padding: 0 0 10px;
+ }
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ margin-bottom: 4px;
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings .rating-wrap {
+ font-size: 14px;
+ line-height: 1;
+ position: relative;
+ color: #e4e4e4;
+ white-space: nowrap;
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings .rating-wrap::before {
+ font-family: FontAwesome;
+ content: ' ';
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings .rating-wrap .star {
+ position: absolute;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ color: #ffde00;
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings .rating-wrap .star::before {
+ font-family: FontAwesome;
+ content: ' ';
+}
+.shop-list-wrapper .content-desc-wrap .content .ratings .rating-num {
+ font-size: 14px;
+ line-height: 1;
+ margin-left: 6px;
+ color: #9f9e9e;
+}
+.shop-list-wrapper .content-desc-wrap .content .title {
+ font-size: 18px;
+ margin: 10px 0 10px;
+}
+.shop-list-wrapper .content-desc-wrap .content .title a {
+ text-decoration: none;
+ color: #474747;
+ font-weight: 600;
+}
+.shop-list-wrapper .content-desc-wrap .content .title a:hover {
+ color: #036eb8;
+}
+.shop-list-wrapper .content-desc-wrap .content p {
+ font-size: 14px;
+ color: #6c6c6c;
+ line-height: 24px;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner {
+ margin-top: 20px;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .price {
+ font-size: 16px;
+ line-height: 1;
+ display: block;
+ margin: 0 0 20px;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .price .new {
+ color: #1d1d1d;
+ font-weight: 500;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .price .old {
+ font-size: 14px;
+ margin-left: 10px;
+ text-decoration: line-through;
+ color: #9f9e9e;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .add-to-cart {
+ width: 170px;
+ height: 50px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ background: #036eb8;
+ border: 0;
+ border-radius: 10px;
+ font-size: 14px;
+ z-index: 11;
+ font-weight: 400;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ color: #fff;
+ text-transform: uppercase;
+ margin-top: 30px;
+ position: relative;
+ overflow: hidden;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .add-to-cart::before {
+ position: absolute;
+ content: '';
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: #4a4a4a;
+ z-index: -1;
+ -webkit-transition: 0.3s linear;
+ transition: 0.3s linear;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ border-radius: 50%;
+ width: 100%;
+ height: 100%;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .add-to-cart:hover {
+ color: #fff;
+ -webkit-box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ background: 0;
+ -webkit-transform: translateY(-3px);
+ transform: translateY(-3px);
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .add-to-cart:hover::before {
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5);
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .actions {
+ z-index: 9;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .actions .action + .action {
+ margin-left: 10px;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .actions .action {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 40px;
+ height: 40px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ text-decoration: none;
+ color: #000;
+ border-radius: 50%;
+ background-color: #eaeaea;
+ font-size: 24px;
+}
+.shop-list-wrapper .content-desc-wrap .box-inner .actions .action:hover {
+ color: #fff;
+ background-color: #036eb8;
+}
+.shop-list-wrapper + .shop-list-wrapper {
+ margin-top: 24px;
+}
+.zoom-thumbs {
+ width: 100%;
+ margin: 18px auto 0 auto;
+}
+.zoom-thumbs .swiper-slide img {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ border: 1px solid transparent;
+ border-radius: 5px;
+}
+.zoom-thumbs .swiper-slide:hover img {
+ border-color: #036eb8;
+}
+.zoom-thumbs .swiper-slide.swiper-slide-thumb-active img {
+ border-color: #036eb8;
+}
+.zoom-thumbs .swiper-slide .img-responsive {
+ width: auto;
+}
+.zoom-top .swiper-slide {
+ border-radius: 5px;
+ border: 1px solid #eeeeee;
+}
+.product-details-content.ml-25px {
+ margin-left: 25px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .product-details-content.ml-25px {
+ margin-left: 0;
+ }
+}
+.product-details-content h2 {
+ color: #333;
+ font-size: 24px;
+ text-transform: capitalize;
+ line-height: 32px;
+ font-weight: 600;
+ margin: 0 0 18px 0;
+}
+@media only screen and (max-width: 767px) {
+ .product-details-content h2 {
+ font-size: 28px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .product-details-content h2 {
+ font-size: 24px;
+ }
+}
+.product-details-content .pricing-meta ul li + li {
+ margin-left: 10px;
+}
+.product-details-content .pricing-meta ul li {
+ font-size: 24px;
+ color: #d1d2d4;
+ line-height: 30px;
+ margin-bottom: 20px;
+ font-weight: 400;
+}
+@media only screen and (max-width: 479px) {
+ .product-details-content .pricing-meta ul li {
+ font-size: 20px;
+ }
+}
+.product-details-content .pricing-meta ul li.new-price {
+ color: #036eb8;
+}
+.product-details-content .pro-details-rating-wrap {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ line-height: 1;
+}
+.product-details-content .pro-details-rating-wrap .rating-product {
+ margin-right: 5px;
+}
+.product-details-content .pro-details-rating-wrap .rating-product i {
+ color: #ffde00;
+ font-size: 14px;
+}
+.product-details-content .pro-details-rating-wrap .rating-product i + i {
+ margin-left: 3px;
+}
+.product-details-content .pro-details-rating-wrap .read-review a {
+ text-decoration: none;
+ color: #424242;
+ position: relative;
+ margin-left: 8px;
+ padding: 0;
+ font-size: 16px;
+ display: inline-block;
+}
+.product-details-content .pro-details-rating-wrap .read-review a:hover {
+ color: #036eb8;
+}
+.product-details-content .stock {
+ line-height: 1;
+}
+.product-details-content .stock .avallabillty {
+ color: #090909;
+ font-weight: 500;
+}
+.product-details-content .stock .avallabillty .in-stock {
+ color: #036eb8;
+ font-weight: 400;
+}
+.product-details-content .stock .avallabillty .in-stock i {
+ margin: 0 5px;
+}
+.product-details-content .pro-details-list {
+ padding: 0 0 30px 0;
+ margin: 0 0 15px 0;
+ border-bottom: 1px solid #ebebeb;
+ display: inline-block;
+ width: 100%;
+ color: #474747;
+}
+.product-details-content .pro-details-list p {
+ font-weight: 400;
+ color: #474747;
+ line-height: 24px;
+ margin: 0;
+}
+.product-details-content .pro-details-list li {
+ display: block;
+ width: 100%;
+ line-height: 24px;
+}
+.product-details-content p {
+ color: #666;
+ line-height: 22px;
+ font-size: 14px;
+}
+.product-details-content .pro-details-quality {
+ display: -webkit-inline-box;
+ display: -ms-inline-flexbox;
+ display: inline-flex;
+ margin: 30px 0;
+ width: 100%;
+}
+.product-details-content .pro-details-quality .cart-plus-minus {
+ border: 1px solid #ebebeb;
+ display: inline-block;
+ height: 50px;
+ overflow: hidden;
+ padding: 0;
+ position: relative;
+ width: 80px;
+ background: #505050;
+ border-radius: 5px;
+}
+.product-details-content .pro-details-quality .cart-plus-minus .qtybutton {
+ color: #fff;
+ cursor: pointer;
+ float: inherit;
+ font-size: 18px;
+ font-weight: 500;
+ line-height: 20px;
+ margin: 0;
+ position: absolute;
+ text-align: center;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ width: 30px;
+}
+.product-details-content .pro-details-quality .cart-plus-minus input.cart-plus-minus-box {
+ background: transparent none repeat scroll 0 0;
+ border: medium none;
+ color: #fff;
+ float: left;
+ font-size: 14px;
+ height: 50px;
+ margin: 0;
+ padding: 0;
+ text-align: center;
+ width: 80px;
+ outline: 0;
+}
+.product-details-content .pro-details-quality .cart-plus-minus .inc.qtybutton {
+ height: 50px;
+ padding-top: 14px;
+ right: 0;
+ top: 0;
+}
+.product-details-content .pro-details-quality .cart-plus-minus .dec.qtybutton {
+ height: 50px;
+ left: 0;
+ padding-top: 14px;
+ top: 0;
+}
+.product-details-content .pro-details-quality .pro-details-cart .add-cart {
+ position: relative;
+ padding: 0 35px;
+ height: 50px;
+ font-size: 14px;
+ font-weight: 500;
+ border: 0;
+ border-radius: 5px;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ text-transform: uppercase;
+ display: inline-block;
+ margin-left: 10px;
+ background: #505050;
+ color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ letter-spacing: 2px;
+}
+.product-details-content .pro-details-quality .pro-details-cart .add-cart.buy-button {
+ background: #036eb8;
+}
+.product-details-content .pro-details-quality .pro-details-cart .add-cart.buy-button:hover {
+ background-color: #000;
+}
+.product-details-content .pro-details-quality .pro-details-cart .add-cart:hover {
+ background-color: #000;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .product-details-content .pro-details-quality .pro-details-cart .add-cart {
+ padding: 0 15px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .product-details-content .pro-details-quality .pro-details-cart .add-cart {
+ padding: 0 12px;
+ letter-spacing: 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .product-details-content .pro-details-quality .pro-details-cart .add-cart {
+ padding: 0 10px;
+ font-size: 12px;
+ margin-left: 5px;
+ }
+}
+.product-details-content .pro-details-compare-wishlist a {
+ padding: 0;
+ border: 0;
+ color: #fff;
+ font-size: 18px;
+ margin-left: 10px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border-radius: 5px;
+ background-color: #3d3d3d;
+ width: 50px;
+ height: 50px;
+}
+@media only screen and (max-width: 479px) {
+ .product-details-content .pro-details-compare-wishlist a {
+ margin-left: 5px;
+ }
+}
+.product-details-content .pro-details-compare-wishlist a:hover {
+ background-color: #000;
+}
+.product-details-content .pro-details-same-style span {
+ font-weight: 500;
+ color: #b2b2b2;
+ display: inline-block;
+ margin-right: 5px;
+}
+.product-details-content .pro-details-same-style a {
+ font-weight: 400;
+ color: #9f9e9e;
+ margin-left: 3px;
+}
+.product-details-content .pro-details-same-style a:hover {
+ color: #036eb8;
+}
+.product-details-content .pro-details-same-style.pro-details-categories-info {
+ margin: 10px 0;
+ font-size: 14px;
+}
+.product-details-content .pro-details-same-style.pro-details-social-info {
+ margin-bottom: 40px;
+}
+.product-details-content .pro-details-same-style.pro-details-social-info a {
+ margin-left: 20px;
+}
+.description-review-topbar.nav {
+ border-bottom: 0;
+ position: relative;
+ margin-bottom: 0;
+ margin: auto;
+ text-align: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ height: 48px;
+ border: 0;
+ background-color: #f5f5f5;
+ border: 1px solid #f5f5f5;
+}
+
+.description-review-topbar.nav a {
+ background: 0;
+ border: 0;
+ text-transform: capitalize;
+ line-height: 24px;
+ color: #363636;
+ padding: 12px 40px;
+ font-size: 16px;
+ font-weight: 500;
+ position: relative;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ display: inline-block;
+ font-family: 'Nunito Sans', sans-serif;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+
+.description-review-topbar.nav a:hover {
+ color: #fff;
+ background-color: #036eb8;
+}
+.description-review-topbar.nav a.active {
+ color: #fff;
+ background-color: #036eb8;
+}
+
+@media only screen and (max-width: 767px) {
+ .description-review-topbar.nav a {
+ margin: 0 15px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .description-review-topbar.nav a {
+ margin: 0 10px;
+ font-size: 16px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .description-review-topbar.nav a {
+ margin: 0 5px;
+ font-size: 14px;
+ padding: 12px 30px;
+ }
+}
+.description-review-bottom {
+ overflow: hidden;
+ font-size: 16px;
+ background: #fff;
+ padding: 44px 56px;
+ border-top: 1px solid #f4f4f4;
+ margin-top: 24px;
+}
+@media only screen and (max-width: 767px) {
+ .description-review-bottom {
+ padding: 40px 0 0 0;
+ border: 0;
+ border-top: 1px solid #f4f4f4;
+ }
+}
+.description-review-bottom .product-description-wrapper {
+ text-align: left;
+}
+.description-review-bottom .product-description-wrapper p {
+ margin: 0;
+ font-size: 16px;
+ line-height: 30px;
+ color: #000;
+ font-weight: 400;
+ text-align: center;
+}
+.description-review-bottom .product-description-wrapper img {
+ max-width: 100%;
+}
+.description-review-bottom .product-anotherinfo-wrapper li {
+ color: #3d3d3d;
+ font-size: 14px;
+ list-style: outside none none;
+ margin: 0 0 13px;
+ display: block;
+}
+.description-review-bottom .product-anotherinfo-wrapper li span {
+ color: #525252;
+ display: inline-block;
+ font-weight: 500;
+ margin: 0 24px 0 0;
+ min-width: 60px;
+}
+.description-review-bottom .product-anotherinfo-wrapper li em {
+ font-style: normal;
+ color: #999;
+}
+.description-review-bottom .single-review {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin: 0 0 50px;
+}
+.description-review-bottom .single-review .review-img {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 90px;
+ flex: 0 0 90px;
+ margin: 0 15px 0 0;
+}
+@media only screen and (max-width: 767px) {
+ .description-review-bottom .single-review .review-img {
+ margin: 0 0 20px 0;
+ }
+}
+.description-review-bottom .single-review .review-top-wrap {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin: 0 0 10px;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left .review-name {
+ margin-right: 15px;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left .review-name h4 {
+ font-size: 20px;
+ margin: 0;
+ line-height: 1;
+ font-weight: 500;
+ color: #525252;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left .rating-product {
+ line-height: 1;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left .rating-product i {
+ overflow: hidden;
+ font-size: 14px;
+ color: #fdd835;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left a {
+ color: #525252;
+}
+.description-review-bottom .single-review .review-top-wrap .review-left a:hover {
+ color: #036eb8;
+}
+.description-review-bottom .single-review .review-bottom p {
+ margin: 0;
+ width: 93%;
+ color: #6c788c;
+}
+.description-review-bottom .single-review.child-review {
+ margin-left: 70px;
+ margin-bottom: 0;
+}
+@media only screen and (max-width: 767px) {
+ .description-review-bottom .single-review.child-review {
+ margin-left: 0;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .description-review-bottom .single-review {
+ display: block;
+ }
+}
+.description-review-bottom .ratting-form-wrapper {
+ padding-left: 50px;
+ line-height: 1;
+}
+.description-review-bottom .ratting-form-wrapper h3 {
+ margin: 0;
+ font-size: 18px;
+ font-weight: 500;
+ color: #525252;
+}
+.description-review-bottom .ratting-form-wrapper .star-box {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin: 10px 0 20px;
+}
+.description-review-bottom .ratting-form-wrapper .star-box span {
+ margin: 0 15px 0 0;
+ font-size: 18px;
+ color: #525252;
+ font-weight: 500;
+}
+.description-review-bottom .ratting-form-wrapper .star-box i {
+ overflow: hidden;
+ font-size: 14px;
+ color: #fdd835;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style {
+ margin-bottom: 10px;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style input {
+ height: 45px;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ padding-left: 10px;
+ font-size: 14px;
+ width: 100%;
+ margin-bottom: 15px;
+ outline: 0;
+ padding: 2px 10px 2px 20px;
+ background: 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ padding: 2px 10px 2px 20px;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style input:focus {
+ border-color: #036eb8;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style textarea {
+ background: 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ height: 180px;
+ padding: 20px 10px 2px 20px;
+ margin-bottom: 20px;
+ width: 100%;
+ outline: 0;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style textarea:focus {
+ border-color: #036eb8;
+}
+.description-review-bottom .ratting-form-wrapper .rating-form-style button {
+ width: 170px;
+ height: 50px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .description-review-bottom .ratting-form-wrapper {
+ margin-top: 50px;
+ padding: 0;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .description-review-bottom .ratting-form-wrapper {
+ margin-top: 50px;
+ padding: 0;
+ }
+}
+.pro-details-color-size {
+ margin-top: 30px;
+ margin-bottom: 10px;
+}
+.pro-details-color-size p {
+ font-weight: 500;
+ color: #090909;
+}
+.pro-details-color-size .ml-30px {
+ margin-left: 30px;
+}
+@media only screen and (max-width: 575px) {
+ .pro-details-color-size .ml-30px {
+ margin-left: 20px;
+ }
+}
+.pro-details-color-size .shop-select {
+ border: 1px solid #d5d5d5;
+ margin-left: 10px;
+ border-radius: 5px;
+ height: 40px;
+}
+.pro-details-color-size .shop-select.show {
+ height: 40px;
+}
+.pro-details-color-size .shop-select.show .nice-select {
+ max-width: 79px;
+ width: 79px;
+ padding-right: 10px;
+}
+@media only screen and (max-width: 575px) {
+ .pro-details-color-size .shop-select.show .nice-select {
+ width: 70px;
+ }
+}
+.pro-details-color-size .shop-select.show .nice-select:after {
+ right: 10px;
+}
+.pro-details-color-size .shop-select .nice-select {
+ -webkit-tap-highlight-color: transparent;
+ background-color: transparent;
+ border-radius: 0;
+ border: solid 1px transparent;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ clear: both;
+ cursor: pointer;
+ display: block;
+ float: left;
+ font-family: Rubik, sans-serif;
+ font-size: 16px;
+ font-weight: 400;
+ height: 40px;
+ line-height: 40px;
+ outline: 0;
+ padding-left: 10px;
+ padding-right: 30px;
+ position: relative;
+ text-align: left !important;
+ -webkit-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ white-space: nowrap;
+ max-width: 162px;
+ width: 162px;
+ color: #090909;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (max-width: 575px) {
+ .pro-details-color-size .shop-select .nice-select {
+ width: 130px;
+ }
+}
+.pro-details-color-size .shop-select .nice-select .current {
+ color: #090909;
+}
+.pro-details-color-size .shop-select .nice-select:after {
+ border: 0;
+ content: '';
+ display: inline-block;
+ font-family: FontAwesome;
+ height: auto;
+ margin-top: 0;
+ pointer-events: none;
+ position: absolute;
+ right: 20px;
+ top: auto;
+ -webkit-transform-origin: 0 0;
+ transform-origin: 0 0;
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+ -webkit-transition: all 0.15s ease-in-out;
+ transition: all 0.15s ease-in-out;
+ width: auto;
+ color: #036eb8;
+ font-size: 18px;
+}
+.pro-details-color-size .shop-select .nice-select .list {
+ background-color: #fff;
+ border-radius: 0;
+ -webkit-box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
+ box-shadow: 0 0 0 1px rgba(68, 68, 68, 0.11);
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
+ margin-top: 5px;
+ opacity: 0;
+ overflow: hidden;
+ padding: 0;
+ pointer-events: none;
+ position: absolute;
+ top: 100%;
+ left: 0;
+ -webkit-transform-origin: 50% 0;
+ transform-origin: 50% 0;
+ -webkit-transform: scale(0.75) translate(-21px);
+ transform: scale(0.75) translate(-21px);
+ -webkit-transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ transition: all 0.2s cubic-bezier(0.5, 0, 0, 1.25), opacity 0.15s ease-out;
+ z-index: 15;
+ width: 100%;
+ color: #090909;
+ font-size: 16px;
+}
+.pro-details-color-size .shop-select .nice-select.open .list {
+ opacity: 1;
+ pointer-events: auto;
+ -webkit-transform: scale(1) translate(0);
+ transform: scale(1) translate(0);
+}
+.product-details-table.pro-details-quality {
+ display: block;
+ margin: 30px 0 10px 0;
+}
+.product-details-table .table tbody tr td {
+ padding: 10px 15px;
+ width: 33.33%;
+ text-align: center;
+ border: 1px solid #ebebeb;
+ vertical-align: middle;
+ font-size: 16px;
+}
+.product-details-table .table tbody tr td a {
+ color: #090909;
+}
+.product-details-table .table tbody tr td a:hover {
+ color: #036eb8;
+}
+.product-details-img.product-details-tab.product-details-tab-2 {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ overflow: hidden;
+}
+.product-details-img.product-details-tab.product-details-tab-2.product-details-tab-3 {
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: reverse;
+ -ms-flex-direction: row-reverse;
+ flex-direction: row-reverse;
+}
+.product-details-img.product-details-tab.product-details-tab-2 .zoom-thumbs-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 15%;
+ flex: 0 0 15%;
+ width: 15%;
+}
+.product-details-img.product-details-tab.product-details-tab-2 .zoom-top-2 {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 85%;
+ flex: 0 0 85%;
+ width: 85%;
+}
+.zoom-thumbs-2 {
+ display: inline-block;
+ float: left;
+ text-align: center;
+}
+.zoom-thumbs-2 .swiper-slide {
+ text-align: center;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ outline: 0 none;
+}
+.zoom-thumbs-2 .swiper-slide + .swiper-slide {
+ margin-top: 10px;
+}
+.zoom-thumbs-2 .swiper-slide img {
+ margin: auto;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ border: 1px solid transparent;
+ border-radius: 5px;
+}
+.zoom-thumbs-2 .swiper-slide.swiper-slide-thumb-active img {
+ border-color: #036eb8;
+}
+.zoom-thumbs-2 .swiper-slide:hover img {
+ border-color: #036eb8;
+}
+.single-product-gallery .single-product-slider-item {
+ width: 50%;
+}
+.single-product-gallery img {
+ border: 1px solid #fff;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ margin: auto;
+ width: 100%;
+}
+.single-product-gallery img:hover {
+ border-color: #036eb8;
+}
+.single-product-sticky .single-product-slider-item {
+ width: 100%;
+ text-align: center;
+}
+.single-product-sticky img {
+ border: 1px solid #fff;
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ width: 100%;
+}
+.single-product-sticky img:hover {
+ border-color: #036eb8;
+}
+.product-details-content.sticky {
+ position: sticky;
+ top: 140px;
+ left: 0;
+ width: 100%;
+}
+.cart-main-area .cart-page-title {
+ color: #000;
+ text-align: left;
+ font-size: 24px;
+ line-height: 16px;
+ font-style: normal;
+ text-transform: none;
+ margin: 0 0 30px;
+ font-weight: 500;
+}
+.cart-main-area .table-content table {
+ border: 1px solid #ebebeb;
+ width: 100%;
+}
+.cart-main-area .table-content table thead > tr {
+ background-color: #ebebeb;
+ border: 1px solid #ebebeb;
+}
+.cart-main-area .table-content table thead > tr > th {
+ border-top: medium none;
+ color: #000;
+ font-size: 16px;
+ font-weight: 500;
+ padding: 21px 45px 22px;
+ text-align: center;
+ text-transform: uppercase;
+ vertical-align: middle;
+ white-space: nowrap;
+}
+.cart-main-area .table-content table tbody > tr {
+ border-bottom: 1px solid #ebebeb;
+}
+.cart-main-area .table-content table tbody > tr td {
+ color: #474747;
+ font-size: 16px;
+ padding: 30px 0;
+ text-align: center;
+}
+.cart-main-area .table-content table tbody > tr td.product-thumbnail {
+ width: 150px;
+}
+.cart-main-area .table-content table tbody > tr td.product-name {
+ width: 435px;
+}
+.cart-main-area .table-content table tbody > tr td.product-name a {
+ color: #474747;
+ font-size: 16px;
+ font-weight: 500;
+}
+.cart-main-area .table-content table tbody > tr td.product-price-cart {
+ width: 435px;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity {
+ width: 435px;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity .cart-plus-minus {
+ display: inline-block;
+ height: 40px;
+ padding: 0;
+ position: relative;
+ width: 110px;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity .cart-plus-minus .dec.qtybutton {
+ border-right: 1px solid #e5e5e5;
+ height: 40px;
+ left: 0;
+ padding-top: 8px;
+ top: 0;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity .cart-plus-minus .inc.qtybutton {
+ border-left: 1px solid #e5e5e5;
+ height: 40px;
+ padding-top: 9px;
+ right: 0;
+ top: 0;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity .cart-plus-minus .qtybutton {
+ color: #474747;
+ cursor: pointer;
+ float: inherit;
+ font-size: 16px;
+ margin: 0;
+ position: absolute;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ width: 20px;
+ text-align: center;
+}
+.cart-main-area .table-content table tbody > tr td.product-quantity .cart-plus-minus input.cart-plus-minus-box {
+ color: #474747;
+ float: left;
+ font-size: 16px;
+ height: 40px;
+ margin: 0;
+ width: 110px;
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #e1e1e1;
+ padding: 0;
+ text-align: center;
+}
+.cart-main-area .table-content table tbody > tr td.product-remove {
+ width: 100px;
+}
+.cart-main-area .table-content table tbody > tr td.product-remove a {
+ color: #474747;
+ font-size: 16px;
+ margin: 0 10px;
+}
+.cart-main-area .table-content table tbody > tr td.product-remove a:hover {
+ color: #036eb8;
+}
+.cart-main-area .table-content table tbody > tr td.product-wishlist-cart > a {
+ background-color: #036eb8;
+ border-radius: 0;
+ color: #fff;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 10px 12px;
+ text-transform: uppercase;
+}
+.cart-main-area .table-content table tbody > tr td.product-wishlist-cart > a:hover {
+ background-color: #000;
+}
+.cart-main-area .cart-shiping-update-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ padding: 30px 0 60px;
+}
+.cart-main-area .cart-shiping-update-wrapper .cart-clear > button {
+ border: medium none;
+ cursor: pointer;
+ margin-right: 27px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+@media only screen and (max-width: 767px) {
+ .cart-main-area .cart-shiping-update-wrapper {
+ display: block;
+ padding: 30px 0 15px;
+ }
+}
+.cart-shiping-update-wrapper .cart-clear > a,
+.cart-shiping-update-wrapper .cart-clear > button,
+.cart-shiping-update-wrapper .cart-shiping-update > a {
+ background-color: #f2f2f2;
+ border-radius: 0;
+ color: #000;
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 18px 63px 17px;
+ text-transform: uppercase;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .cart-shiping-update-wrapper .cart-clear > a,
+ .cart-shiping-update-wrapper .cart-clear > button,
+ .cart-shiping-update-wrapper .cart-shiping-update > a {
+ padding: 18px 25px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .cart-shiping-update-wrapper .cart-clear > a,
+ .cart-shiping-update-wrapper .cart-clear > button,
+ .cart-shiping-update-wrapper .cart-shiping-update > a {
+ padding: 18px 25px;
+ margin: 0 0 15px;
+ }
+}
+.cart-shiping-update-wrapper .cart-clear > button:hover,
+.cart-shiping-update-wrapper .cart-shiping-update > a:hover {
+ background-color: #036eb8;
+ color: #fff;
+}
+.cart-shiping-update-wrapper .cart-clear > a {
+ background-color: #036eb8;
+ color: #fff;
+}
+.cart-shiping-update-wrapper .cart-clear > a:hover {
+ background-color: #000;
+ color: #fff;
+}
+.cart-tax,
+.discount-code-wrapper,
+.grand-totall {
+ background-color: #ebebeb;
+ border: 1px solid #ebebeb;
+ border-radius: 0;
+ padding: 45px 30px 50px;
+}
+.cart-tax .title-wrap,
+.discount-code-wrapper .title-wrap,
+.grand-totall .title-wrap {
+ position: relative;
+}
+.cart-tax .title-wrap::before,
+.discount-code-wrapper .title-wrap::before,
+.grand-totall .title-wrap::before {
+ background-color: #e3e1e1;
+ content: '';
+ height: 1px;
+ left: 0;
+ position: absolute;
+ top: 13px;
+ -webkit-transition: all 0.4s ease 0s;
+ transition: all 0.4s ease 0s;
+ width: 100%;
+ z-index: 1;
+}
+.cart-tax .title-wrap h4.cart-bottom-title,
+.discount-code-wrapper .title-wrap h4.cart-bottom-title,
+.grand-totall .title-wrap h4.cart-bottom-title {
+ display: inline-block;
+ font-size: 18px;
+ font-weight: 500;
+ margin: 0;
+ padding-right: 18px;
+ background-color: #ebebeb;
+ position: relative;
+ z-index: 1;
+ color: #000;
+}
+.cart-tax .tax-wrapper,
+.discount-code-wrapper .tax-wrapper,
+.grand-totall .tax-wrapper {
+ margin-top: 22px;
+}
+.tax-select-wrapper {
+ margin: 15px 0 0;
+}
+.tax-select-wrapper select {
+ width: 100%;
+ height: 42px;
+ line-height: 42px;
+ border: 1px solid #ebebeb;
+ background: #fff;
+ padding-left: 20px;
+ border-radius: 0;
+}
+.tax-select-wrapper input {
+ width: 100%;
+ height: 42px;
+ line-height: 42px;
+ border: 1px solid #ebebeb;
+ background: #fff;
+ padding-left: 20px;
+ border-radius: 0;
+}
+.tax-select-wrapper .tax-select {
+ margin-bottom: 20px;
+}
+.tax-select-wrapper .tax-select label {
+ color: #000;
+ font-size: 16px;
+ margin: 0 0 10px;
+}
+.tax-select-wrapper button.cart-btn-2 {
+ background: #036eb8;
+ border-radius: 0;
+ color: #fff;
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 18px 58px;
+ text-transform: uppercase;
+}
+.tax-select-wrapper button.cart-btn-2:hover {
+ color: #fff;
+ background: #000;
+}
+.discount-code-wrapper .title-wrap {
+ margin-bottom: 22px;
+}
+.discount-code-wrapper .discount-code p {
+ margin: 0 0 15px;
+}
+.discount-code-wrapper .discount-code input {
+ background: #fff;
+ border: 1px solid #ebebeb;
+ height: 45px;
+ margin-bottom: 30px;
+ padding-left: 10px;
+ outline: 0;
+ width: 100%;
+ border-radius: 0;
+}
+.discount-code-wrapper .discount-code button.cart-btn-2 {
+ background: #036eb8;
+ border-radius: 0;
+ color: #fff;
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 18px 58px;
+ text-transform: uppercase;
+}
+.discount-code-wrapper .discount-code button.cart-btn-2:hover {
+ color: #fff;
+ background: #000;
+}
+.grand-totall h5 {
+ font-size: 16px;
+ margin: 36px 0 27px;
+ font-weight: 400;
+}
+.grand-totall h5 span {
+ float: right;
+ font-size: 18px;
+ font-weight: 500;
+}
+.grand-totall .total-shipping {
+ border-bottom: 1px solid #ebebeb;
+ border-top: 1px solid #ebebeb;
+ margin: 0 0 27px;
+ padding: 28px 0;
+}
+.grand-totall .total-shipping h5 {
+ font-size: 16px;
+ margin: 0;
+}
+.grand-totall .total-shipping ul {
+ padding: 19px 0 0 0;
+}
+.grand-totall .total-shipping ul li {
+ color: #474747;
+ list-style: outside none none;
+ margin: 0 0 6px;
+ display: block;
+}
+.grand-totall .total-shipping ul li input {
+ background: #e9e9e9 none repeat scroll 0 0;
+ border: 1px solid #d7d7d7;
+ border-radius: 5px !important;
+ color: #474747;
+ cursor: pointer;
+ height: 13px;
+ margin-right: 10px;
+ padding: 0;
+ position: relative;
+ top: 2px;
+ width: 13px;
+}
+.grand-totall .total-shipping ul li span {
+ float: right;
+}
+.grand-totall .grand-totall-title {
+ color: #036eb8;
+ font-size: 20px;
+ font-weight: 500;
+ margin: 0 0 25px;
+}
+.grand-totall .grand-totall-title span {
+ float: right;
+}
+.grand-totall a {
+ background-color: #036eb8;
+ border-radius: 0;
+ color: #fff;
+ display: block;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 18px 10px 17px;
+ text-align: center;
+ text-transform: uppercase;
+ text-transform: uppercase;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.grand-totall a:hover {
+ background-color: #000;
+}
+.billing-info-wrap h3 {
+ font-weight: 500;
+ color: #000;
+ margin: 0 0 30px;
+ font-size: 24px;
+ line-height: 16px;
+}
+.billing-info-wrap .billing-info input {
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ font-size: 16px;
+ padding-left: 20px;
+ padding-right: 10px;
+ width: 100%;
+ outline: 0;
+ height: 45px;
+}
+.billing-info-wrap .billing-info input.billing-address {
+ margin-bottom: 10px;
+}
+.billing-info-wrap .billing-info .checkout-account label {
+ color: #474747;
+ font-weight: 400;
+ margin: 0 0 0 12px;
+}
+.billing-info-wrap .billing-info .checkout-account input {
+ border: 1px solid #ebebeb;
+ display: inline-block;
+ float: left;
+ height: 12px;
+ width: 12px;
+ margin-top: 7px;
+ cursor: pointer;
+}
+.billing-info-wrap .billing-select select {
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ font-size: 16px;
+ padding-left: 20px;
+ padding-right: 10px;
+ width: 100%;
+ outline: 0;
+ height: 45px;
+}
+.billing-info-wrap .checkout-account-toggle input {
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ font-size: 16px;
+ padding-left: 20px;
+ padding-right: 10px;
+ margin: 0 0 20px;
+ width: 100%;
+ height: 45px;
+ outline: 0;
+}
+.billing-info-wrap .checkout-account-toggle button.checkout-btn {
+ background-color: #036eb8;
+ border: medium none;
+ color: #fff;
+ cursor: pointer;
+ font-weight: 500;
+ padding: 10px 30px;
+ text-transform: uppercase;
+ border-radius: 0;
+ z-index: 9;
+}
+.billing-info-wrap .checkout-account-toggle button.checkout-btn:hover {
+ background-color: #000;
+}
+.billing-info-wrap .additional-info-wrap {
+ margin: 30px 0;
+}
+.billing-info-wrap .additional-info-wrap h4 {
+ font-size: 18px;
+ font-weight: 500;
+ color: #000;
+ margin: 0 0 10px;
+}
+.billing-info-wrap .additional-info-wrap textarea {
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ font-size: 16px;
+ height: 138px;
+ padding: 17px 20px;
+ width: 100%;
+ outline: 0;
+}
+.billing-info-wrap label {
+ margin-bottom: 10px;
+}
+.your-order-area h3 {
+ font-weight: 500;
+ color: #000;
+ margin: 0 0 30px;
+ font-size: 24px;
+ line-height: 16px;
+}
+.your-order-area .your-order-wrap {
+ padding: 38px 45px 44px;
+ background: #ebebeb;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-top ul {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-family: Rubik, sans-serif;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-top ul li {
+ font-size: 16px;
+ font-weight: 500;
+ list-style: outside none none;
+ color: #000;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-middle {
+ border-bottom: 1px solid #dee0e4;
+ border-top: 1px solid #dee0e4;
+ margin: 29px 0;
+ padding: 19px 0 18px;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-middle li {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin: 0 0 10px;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-bottom ul {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ font-family: Rubik, sans-serif;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-bottom ul li.your-order-shipping {
+ font-size: 16px;
+ color: #000;
+ font-weight: 500;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-total {
+ border-bottom: 1px solid #dee0e4;
+ border-top: 1px solid #dee0e4;
+ margin: 18px 0 33px;
+ padding: 17px 0 19px;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-total ul {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-total ul li {
+ font-weight: 500;
+ color: #036eb8;
+ font-size: 16px;
+ list-style: outside none none;
+ font-family: Rubik, sans-serif;
+}
+.your-order-area .your-order-wrap .your-order-product-info .your-order-total ul li.order-total {
+ font-weight: 500;
+ color: #000;
+ font-size: 18px;
+}
+@media only screen and (max-width: 767px) {
+ .your-order-area .your-order-wrap {
+ padding: 38px 30px 44px;
+ }
+}
+.your-order-area .payment-accordion {
+ margin: 0 0 16px;
+}
+.your-order-area .payment-accordion:last-child {
+ margin: 0;
+}
+.your-order-area .payment-accordion h4 a {
+ color: #000;
+ font-size: 16px;
+ margin: 0;
+ font-weight: 500;
+}
+.your-order-area .payment-accordion .panel-body {
+ padding: 5px 0 0 0;
+}
+.your-order-area .payment-accordion .panel-body p {
+ padding: 0 0 0 10px;
+ font-size: 14px;
+ color: #474747;
+ line-height: 24px;
+}
+.your-order-area .Place-order {
+ margin-top: 25px;
+}
+.your-order-area .Place-order a {
+ background-color: #036eb8;
+ color: #fff;
+ display: block;
+ font-weight: 500;
+ letter-spacing: 1px;
+ line-height: 1;
+ padding: 18px 20px;
+ text-align: center;
+ text-transform: uppercase;
+ border-radius: 0;
+ z-index: 9;
+}
+.your-order-area .Place-order a:hover {
+ background-color: #000;
+}
+.open-toggle,
+.open-toggle2 {
+ display: none;
+}
+.compare-table .table tbody {
+ border-right: 1px solid #ebebeb;
+}
+.compare-table .table tbody tr:first-child {
+ border-top: 1px solid #ebebeb;
+}
+.compare-table .table tbody tr td {
+ text-align: center;
+ border: 0;
+ padding: 25px 30px;
+ vertical-align: middle;
+ border-bottom: 1px solid #ebebeb;
+ border-left: 1px solid #ebebeb;
+}
+.compare-table .table tbody tr td.first-column {
+ min-width: 180px;
+ font-size: 18px;
+ font-weight: 500;
+ color: #000;
+ margin: 0;
+ line-height: 1;
+}
+.compare-table .table tbody tr td.product-image-title {
+ min-width: 310px;
+ vertical-align: bottom;
+ padding-top: 70px;
+}
+.compare-table .table tbody tr td.product-image-title .image {
+ clear: both;
+ width: 100%;
+ margin-bottom: 40px;
+ display: block;
+}
+.compare-table .table tbody tr td.product-image-title .category {
+ float: left;
+ clear: both;
+ font-size: 13px;
+ line-height: 15px;
+ color: #000;
+ text-transform: capitalize;
+ letter-spacing: 0.5px;
+}
+.compare-table .table tbody tr td.product-image-title .title {
+ float: left;
+ clear: both;
+ font-size: 16px;
+ font-weight: 500;
+ color: #000;
+ line-height: 20px;
+ margin-bottom: 10px;
+}
+.compare-table .table tbody tr td.pro-desc p {
+ text-align: left;
+ margin: 0;
+ line-height: 24px;
+ font-size: 14px;
+}
+.compare-table .table tbody tr td.pro-color,
+.compare-table .table tbody tr td.pro-price,
+.compare-table .table tbody tr td.pro-stock {
+ font-size: 16px;
+ font-weight: 500;
+ color: #000;
+}
+.compare-table .table tbody tr td.pro-addtocart .add-to-cart {
+ position: relative;
+ background-color: #036eb8;
+ color: #fff;
+ border-radius: 0;
+ display: inline-block;
+ width: 170px;
+ padding: 14px 25px 14px 25px;
+ -webkit-transition: all 0.3s ease-in-out;
+ transition: all 0.3s ease-in-out;
+ outline: 0;
+ font-weight: 500;
+}
+.compare-table .table tbody tr td.pro-addtocart .add-to-cart:hover {
+ background-color: #000;
+}
+.compare-table .table tbody tr td.pro-remove button {
+ border: 0;
+ background-color: transparent;
+ padding: 0;
+ cursor: pointer;
+ -webkit-transition: all 0.3s ease-in-out;
+ transition: all 0.3s ease-in-out;
+ outline: 0;
+ color: #000;
+}
+.compare-table .table tbody tr td.pro-remove button i {
+ font-size: 22px;
+}
+.compare-table .table tbody tr td.pro-remove button:hover {
+ color: #036eb8;
+}
+.compare-table .table tbody tr td.pro-ratting i {
+ font-size: 20px;
+ color: #fdd835;
+}
+.single-my-account {
+ margin-bottom: 20px;
+ border: 1px solid #ebebeb;
+}
+.single-my-account .myaccount-info-wrapper {
+ padding: 30px 20px;
+ background-color: #fff;
+}
+.single-my-account .myaccount-info-wrapper .account-info-wrapper {
+ border-bottom: 1px solid #eaeaea;
+ margin-bottom: 28px;
+ padding-bottom: 30px;
+}
+.single-my-account .myaccount-info-wrapper .account-info-wrapper h4 {
+ font-size: 14px;
+ margin: 0;
+ text-transform: uppercase;
+ color: #000;
+ font-weight: 500;
+}
+.single-my-account .myaccount-info-wrapper .account-info-wrapper h5 {
+ font-size: 14px;
+ letter-spacing: 0.2px;
+ margin-top: 7px;
+ font-weight: 500;
+ color: #000;
+}
+.single-my-account .myaccount-info-wrapper .account-info-wrapper .account-info-wrapper {
+ border-bottom: 1px solid #eaeaea;
+ margin-bottom: 28px;
+ padding-bottom: 30px;
+}
+.single-my-account .myaccount-info-wrapper .billing-info {
+ margin-bottom: 20px;
+}
+.single-my-account .myaccount-info-wrapper .billing-info label {
+ color: #474747;
+ font-size: 14px;
+ text-transform: capitalize;
+ margin-bottom: 10px;
+}
+.single-my-account .myaccount-info-wrapper .billing-info input {
+ background: transparent none repeat scroll 0 0;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ height: 40px;
+ padding: 0 15px;
+ width: 100%;
+ outline: 0;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin-top: 26px;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn .billing-back a {
+ color: #000;
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn .billing-back a i {
+ font-size: 15px;
+ color: #036eb8;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn .billing-back a:hover {
+ color: #036eb8;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn .billing-btn button {
+ background-color: #f2f2f2;
+ border: medium none;
+ color: #000;
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 16px 35px 17px;
+ text-transform: uppercase;
+ cursor: pointer;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ outline: 0;
+ border-radius: 0;
+}
+.single-my-account .myaccount-info-wrapper .billing-back-btn .billing-btn button:hover {
+ background-color: #036eb8;
+ color: #fff;
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper {
+ border: 1px solid #eaeaea;
+ position: relative;
+}
+@media only screen and (max-width: 767px) {
+ .single-my-account .myaccount-info-wrapper .entries-wrapper {
+ padding: 30px 10px;
+ }
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper:before {
+ position: absolute;
+ content: '';
+ height: 100%;
+ width: 1px;
+ left: 50%;
+ top: 0;
+ background-color: #eaeaea;
+}
+@media only screen and (max-width: 767px) {
+ .single-my-account .myaccount-info-wrapper .entries-wrapper:before {
+ display: none;
+ }
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-info {
+ padding: 30px 20px;
+}
+@media only screen and (max-width: 767px) {
+ .single-my-account .myaccount-info-wrapper .entries-wrapper .entries-info {
+ padding: 0 10px 30px;
+ }
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-info p {
+ color: #474747;
+ font-size: 14px;
+ margin: 0;
+ text-transform: capitalize;
+ line-height: 24px;
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-edit-delete a {
+ background-color: #f32013;
+ color: #fff;
+ display: inline-block;
+ line-height: 1;
+ margin: 0 2px;
+ padding: 12px 15px;
+ text-transform: uppercase;
+ font-weight: 500;
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-edit-delete a:hover {
+ background-color: #036eb8;
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-edit-delete a.edit {
+ background-color: #000;
+ font-weight: 500;
+}
+.single-my-account .myaccount-info-wrapper .entries-wrapper .entries-edit-delete a.edit:hover {
+ background-color: #036eb8;
+}
+@media only screen and (max-width: 767px) {
+ .dashboard_tab_button {
+ margin-bottom: 50px;
+ }
+}
+.dashboard_tab_button li {
+ margin-bottom: 10px;
+}
+.dashboard_tab_button li:last-child {
+ margin-bottom: 0;
+}
+.dashboard_tab_button li .nav-link {
+ font-weight: 500;
+ color: #fff;
+ background-color: #000;
+ font-size: 16px;
+ text-transform: uppercase;
+ display: block;
+}
+.dashboard_tab_button li .nav-link.active {
+ background-color: #036eb8;
+}
+.dashboard_content h4 {
+ font-size: 24px;
+ text-transform: capitalize;
+ font-weight: 500;
+ margin-bottom: 15px;
+}
+.dashboard_content h5 {
+ font-size: 20px;
+ text-transform: capitalize;
+ font-weight: 500;
+ margin-bottom: 10px;
+ margin-top: 10px;
+}
+.dashboard_content p {
+ font-size: 16px;
+ line-height: 26px;
+}
+.dashboard_content p a {
+ color: #036eb8;
+ font-weight: 500;
+}
+.input-radio span {
+ font-weight: 500;
+ padding-right: 10px;
+}
+.account_login_form form span input[type='checkbox'],
+.input-radio span input[type='radio'] {
+ width: 15px;
+ height: 15px;
+ margin-right: 2px;
+ position: relative;
+ top: 2px;
+}
+.checkbox-default-more-text em {
+ margin-top: 14px;
+ display: block;
+ line-height: 24px;
+}
+.table_page table {
+ width: 100%;
+ caption-side: bottom;
+ border-collapse: collapse;
+}
+.table_page table thead {
+ background: #f2f2f2;
+}
+.table_page table thead tr th {
+ color: #24262b;
+ border-bottom: 3px solid #036eb8;
+ border-right: 1px solid #ededed;
+ font-size: 16px;
+ font-weight: 500;
+ text-transform: capitalize;
+ padding: 10px;
+ text-align: center;
+}
+.table_page tbody tr td {
+ border-right: 1px solid #ededed;
+ font-weight: 500;
+ text-transform: capitalize;
+ font-size: 14px;
+ text-align: center;
+ min-width: 150px;
+}
+.table_page tbody tr td a:hover {
+ color: #036eb8;
+}
+.table_page table tbody tr td {
+ border-bottom: 1px solid #ededed;
+ border-right: 1px solid #ededed;
+ text-align: center;
+ padding: 10px;
+}
+.table_desc table tbody tr td:last-child,
+.table_page table thead tr:last-child th {
+ border-right: 0;
+}
+.default-form-box {
+ margin-bottom: 20px;
+}
+.default-form-box label {
+ font-weight: 400;
+ font-size: 16px;
+ margin-bottom: 10px;
+ display: block;
+}
+.default-form-box input {
+ display: block;
+ width: 100%;
+ height: 45px;
+ padding: 0 10px 0 20px;
+ font-size: 16px;
+ font-weight: 400;
+ color: #474747;
+ border-radius: 3px;
+ background-color: #fff;
+ border: 1px solid #e2e2e2;
+ line-height: 45px;
+}
+.default-form-box input:focus {
+ border-color: #036eb8;
+}
+.checkbox-default {
+ line-height: 1;
+ display: inline-block;
+}
+.checkbox-default input {
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ position: relative;
+ line-height: 0;
+ height: auto;
+}
+.checkbox-default input::after {
+ position: absolute;
+ content: '';
+ width: 20px;
+ height: 20px;
+ border: 1px solid #dee2e6;
+ line-height: 20px;
+ text-align: center;
+ left: 0;
+}
+.checkbox-default span {
+ display: inline-block;
+ -webkit-transform: translateX(35px);
+ transform: translateX(35px);
+ text-transform: capitalize;
+ color: #777 !important;
+ font-size: 16px;
+ cursor: pointer;
+}
+.checkbox-default input:checked::after {
+ position: absolute;
+ content: '';
+ background: #036eb8;
+ border-color: #036eb8;
+ font-family: FontAwesome;
+ color: #fff;
+}
+.save_button button {
+ background-color: #3b3b3b;
+ border-color: #3b3b3b;
+ color: #fff;
+ font-weight: 400;
+ font-size: 14px;
+ width: 130px;
+ height: 45px;
+ line-height: 45px;
+}
+.save_button button:hover {
+ border-color: #036eb8;
+ background-color: #036eb8;
+ color: #fff;
+}
+.login-register-wrapper .login-register-tab-list {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ margin-bottom: 40px;
+}
+.login-register-wrapper .login-register-tab-list a {
+ position: relative;
+}
+.login-register-wrapper .login-register-tab-list a:before {
+ background-color: #000;
+ bottom: 5px;
+ content: '';
+ height: 18px;
+ margin: 0 auto;
+ position: absolute;
+ right: -2px;
+ -webkit-transition: all 0.4s ease 0s;
+ transition: all 0.4s ease 0s;
+ width: 1px;
+}
+.login-register-wrapper .login-register-tab-list a:hover h4 {
+ color: #036eb8 !important;
+}
+.login-register-wrapper .login-register-tab-list a h4 {
+ font-size: 25px;
+ font-weight: 500;
+ margin: 0 20px;
+ text-transform: capitalize;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ color: #000;
+}
+.login-register-wrapper .login-register-tab-list a:last-child:before {
+ display: none;
+}
+.login-register-wrapper .login-form-container {
+ background: transparent none repeat scroll 0 0;
+ -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.1);
+ padding: 80px;
+ text-align: left;
+}
+.login-register-wrapper .login-form-container .login-register-form input {
+ background-color: transparent;
+ border: 1px solid #ebebeb;
+ color: #474747;
+ font-size: 14px;
+ margin-bottom: 30px;
+ padding: 0 15px;
+ width: 100%;
+ outline: 0;
+}
+.login-register-wrapper .login-form-container .login-register-form input:focus {
+ border-color: #036eb8;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box .login-toggle-btn {
+ padding: 10px 0 19px;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box .login-toggle-btn input[type='checkbox'] {
+ height: 15px;
+ margin: 0;
+ position: relative;
+ top: 1px;
+ width: 17px;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box .login-toggle-btn a {
+ color: #000;
+ float: right;
+ font-size: 15px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box .login-toggle-btn a.flote-none {
+ float: none !important;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box .login-toggle-btn a:hover {
+ color: #036eb8;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box button {
+ background-color: #f2f2f2;
+ border: medium none;
+ color: #000;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 500;
+ line-height: 1;
+ padding: 11px 30px;
+ text-transform: uppercase;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ outline: 0;
+ border-radius: 0;
+ font-family: Rubik, sans-serif;
+}
+.login-register-wrapper .login-form-container .login-register-form .button-box button:hover {
+ background-color: #036eb8;
+ color: #fff;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .login-register-wrapper .login-form-container {
+ padding: 80px 50px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .login-register-wrapper .login-form-container {
+ padding: 40px 15px;
+ }
+}
+.login-register-wrapper .login-register-tab-list a.active h4 {
+ color: #036eb8;
+}
+.cart-heading h2 {
+ color: #000;
+ text-align: left;
+ font-size: 24px;
+ line-height: 16px;
+ font-style: normal;
+ text-transform: none;
+ margin: 0 0 30px;
+ font-weight: 500;
+}
+.empty-text-contant i {
+ font-size: 60px;
+ color: #000;
+}
+.empty-text-contant h3 {
+ font-size: 20px;
+ color: #000;
+ margin: 20px 0 20px;
+ font-weight: 500;
+}
+@media only screen and (max-width: 575px) {
+ .empty-text-contant h3 {
+ font-size: 18px;
+ }
+}
+.empty-text-contant a.empty-cart-btn {
+ padding: 15px 25px;
+ display: inline-block;
+ background: #036eb8;
+ color: #fff;
+ font-size: 14px;
+ font-weight: 500;
+ border-radius: 30px;
+ -webkit-transition: 0.3s;
+ transition: 0.3s;
+ text-transform: uppercase;
+}
+.empty-text-contant a.empty-cart-btn:hover {
+ background-color: #000;
+}
+.empty-text-contant a.empty-cart-btn:hover i {
+ -webkit-transform: translate(-5px, 0);
+ transform: translate(-5px, 0);
+}
+.empty-text-contant a.empty-cart-btn i {
+ font-size: 14px !important;
+ color: #fff;
+ -webkit-transition: 0.3s;
+ transition: 0.3s;
+ display: inline-block;
+}
+.privacy_policy_main_area .privacy_content {
+ margin-bottom: 22px;
+}
+.privacy_policy_main_area .privacy_content h2 {
+ font-size: 22px;
+ line-height: 26px;
+ font-weight: 500;
+ margin-bottom: 7px;
+}
+@media only screen and (max-width: 767px) {
+ .privacy_policy_main_area .privacy_content h2 {
+ font-size: 20px;
+ }
+}
+.privacy_policy_main_area .privacy_content h3 {
+ font-size: 22px;
+ line-height: 26px;
+ font-weight: 500;
+ margin-bottom: 7px;
+}
+.privacy_policy_main_area .privacy_content p {
+ font-size: 16px;
+ line-height: 26px;
+ margin-bottom: 19px;
+}
+.privacy_policy_main_area .privacy_content p a {
+ color: #036eb8;
+}
+@media only screen and (max-width: 479px) {
+ .privacy_policy_main_area .privacy_content p a {
+ font-size: 12px;
+ }
+}
+.privacy_policy_main_area .privacy_content p a:hover {
+ color: #036eb8;
+}
+.privacy_policy_main_area .privacy_content.section_2 h2 {
+ margin-bottom: 24px;
+}
+.privacy_policy_main_area .privacy_content.section_3:last-child {
+ margin: 0;
+}
+.privacy_policy_main_area .privacy_content.section_3:last-child p {
+ margin: 0;
+}
+.coming_soon_area {
+ height: 100vh;
+ background-repeat: no-repeat;
+ background-attachment: scroll;
+ background-position: center center;
+ background-size: cover;
+ background-image: url(../images/coming-soon-bg/coming-soon.jpg);
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.coming_soon_area::before {
+ position: absolute;
+ content: '';
+ width: 100%;
+ height: 100%;
+ left: 0;
+ top: 0;
+ background: #000;
+ opacity: 0.15;
+}
+.coming_soon_title {
+ text-align: center;
+ margin-bottom: 40px;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_title {
+ margin-bottom: 36px;
+ }
+}
+.coming_soon_title h2 {
+ font-size: 37px;
+ text-transform: capitalize;
+ color: #fff;
+ font-weight: 600;
+ margin-bottom: 15px;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_title h2 {
+ font-size: 22px;
+ margin-bottom: 11px;
+ }
+}
+.coming_soon_title p {
+ color: #fff;
+ font-size: 16px;
+ max-width: 730px;
+ margin: 0 auto;
+ line-height: 26px;
+}
+@media only screen and (max-width: 575px) {
+ .coming_soon_title p {
+ font-size: 14px;
+ }
+}
+.coming_soon_timing {
+ text-align: center;
+ margin: 57px 0 42px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .coming_soon_timing {
+ margin: 50px 0 30px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_timing {
+ margin: 34px 0 22px;
+ }
+}
+.coming_soon_timing span.cdown {
+ display: inline-block;
+ margin-right: 35px;
+ background: inherit;
+ font-size: 26px;
+ font-weight: 600;
+ line-height: 1;
+ color: #fff;
+ margin-bottom: 8px;
+ width: 60px;
+ height: 40px;
+ line-height: 38px;
+ border: 1px solid #ebebeb;
+ border-radius: 4px;
+ padding-top: 0;
+ font-family: Rubik, sans-serif;
+}
+@media only screen and (max-width: 575px) {
+ .coming_soon_timing span.cdown {
+ margin-right: 20px;
+ width: 55px;
+ font-size: 20px;
+ }
+}
+.coming_soon_timing span.cdown:last-child {
+ margin-right: 0;
+}
+.coming_soon_timing span p {
+ font-size: 14px;
+ text-transform: capitalize;
+ color: #fff;
+}
+.coming_soon_newsletter {
+ text-align: center;
+}
+.coming_soon_newsletter .subscribe_form {
+ margin-top: 0;
+}
+.coming_soon_newsletter .subscribe_form form {
+ margin: 0 auto;
+ width: 600px;
+ background: inherit;
+ border: 1px solid #efefef;
+ border-radius: 50px;
+ position: relative;
+ text-align: left;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_newsletter .subscribe_form form {
+ width: 100%;
+ }
+}
+.coming_soon_newsletter .subscribe_form form input::-webkit-input-placeholder {
+ color: #fff;
+}
+.coming_soon_newsletter .subscribe_form form input::-moz-placeholder {
+ color: #fff;
+}
+.coming_soon_newsletter .subscribe_form form input:-ms-input-placeholder {
+ color: #fff;
+}
+.coming_soon_newsletter .subscribe_form form input:-moz-placeholder {
+ color: #fff;
+}
+.coming_soon_newsletter .subscribe_form form input {
+ color: #fff;
+ font-size: 16px;
+ padding: 0 140px 0 28px;
+ background: inherit;
+ height: 48px;
+ border: 0;
+ width: 100%;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_newsletter .subscribe_form form input {
+ padding: 0 106px 0 18px;
+ height: 45px;
+ }
+}
+.coming_soon_newsletter .subscribe_form form button {
+ font-size: 16px;
+ text-transform: uppercase;
+ font-weight: 700;
+ background: inherit;
+ color: #fff;
+ position: absolute;
+ right: 0;
+ top: 50%;
+ margin-top: -24px;
+ width: 120px;
+ height: 48px;
+}
+.coming_soon_newsletter .subscribe_form form button:hover {
+ color: #036eb8;
+}
+.coming_soon_newsletter .subscribe_form form button::before {
+ content: '';
+ background: #fff;
+ width: 2px;
+ position: absolute;
+ bottom: 8px;
+ top: 8px;
+ left: 0;
+ height: 30px;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_newsletter .subscribe_form form button {
+ font-size: 13px;
+ }
+}
+.coming_soon_newsletter h3 {
+ font-size: 16px;
+ color: #fff;
+ font-weight: 700;
+ margin-bottom: 15px;
+ letter-spacing: 2px;
+ text-transform: capitalize;
+}
+@media only screen and (max-width: 767px) {
+ .coming_soon_newsletter h3 {
+ letter-spacing: 1px;
+ }
+}
+.coming_soon_newsletter .mailchimp-error {
+ text-align: center;
+ color: #fff;
+}
+.coming_soon_newsletter .mailchimp-success {
+ text-align: center;
+ color: #fff;
+}
+.coming_soon_logo {
+ margin-bottom: 32px;
+}
+@media only screen and (max-width: 575px) {
+ .coming_soon_logo {
+ margin-bottom: 25px;
+ }
+}
+.coming_soon_container {
+ position: relative;
+}
+.faq-area .inner-descripe {
+ margin-bottom: 30px;
+}
+.faq-area .inner-descripe h4 {
+ color: #000;
+ font-size: 24px;
+ font-weight: 500;
+ margin: 0 0 15px;
+ line-height: 28px;
+}
+@media only screen and (max-width: 767px) {
+ .faq-area .inner-descripe h4 {
+ font-size: 20px;
+ }
+}
+.faq-area .inner-descripe p {
+ color: #474747;
+ line-height: 26px;
+}
+.faq-area .single-my-account h3.panel-title {
+ border-bottom: 0;
+ text-transform: capitalize;
+}
+.faq-area .single-my-account h3.panel-title a {
+ font-size: 16px;
+ color: #212121;
+ display: block;
+ padding: 16px 45px;
+ position: relative;
+ color: #000;
+}
+@media only screen and (max-width: 767px) {
+ .faq-area .single-my-account h3.panel-title a {
+ padding: 12px 38px;
+ font-size: 14px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .faq-area .single-my-account h3.panel-title a {
+ font-size: 13px;
+ }
+}
+.faq-area .single-my-account h3.panel-title a:before {
+ content: '';
+ display: inline-block;
+ font-family: FontAwesome;
+ font-size: 14px;
+ position: absolute;
+ right: 20px;
+ top: 50%;
+ margin-top: -14px;
+}
+.faq-area .single-my-account h3.panel-title span {
+ color: #212121;
+ font-size: 14px;
+ left: 20px;
+ position: absolute;
+ top: 10px;
+ font-size: 16px;
+ top: 14px;
+}
+@media only screen and (max-width: 767px) {
+ .faq-area .single-my-account h3.panel-title span {
+ top: 10px;
+ font-size: 14px;
+ }
+}
+.faq-area .single-my-account h3.panel-title a[aria-expanded='true'] {
+ color: #036eb8;
+}
+.faq-area .single-my-account .panel-body {
+ padding: 20px;
+ line-height: 26px;
+}
+.single-my-account h3.panel-title {
+ background-color: #ebebeb;
+ border-bottom: 1px solid #ebebeb;
+ color: #212121;
+ font-size: 14px;
+ font-weight: 500;
+ margin: 0;
+ position: relative;
+ text-transform: uppercase;
+ line-height: 2;
+}
+.blank-page-area {
+ background-size: cover;
+ background-position: center;
+ background-repeat: no-repeat;
+ height: 770px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .blank-page-area {
+ height: 560px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .blank-page-area {
+ height: 550px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .blank-page-area {
+ height: 500px;
+ }
+}
+.blank-page-area .page-not-found {
+ margin-top: 310px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .blank-page-area .page-not-found {
+ margin-top: 200px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .blank-page-area .page-not-found {
+ margin-top: 150px;
+ }
+}
+.blank-page-area .page-not-found h2 {
+ font-size: 48px;
+ font-weight: 700;
+ font-style: italic;
+ color: #4e4e4e;
+ line-height: 61px;
+}
+@media only screen and (max-width: 767px) {
+ .blank-page-area .page-not-found h2 {
+ font-size: 36px;
+ line-height: 48px;
+ }
+}
+.blank-page-area .page-not-found p {
+ font-size: 36px;
+ font-weight: 400;
+ color: #4e4e4e;
+ line-height: 61px;
+ margin: 0 0 50px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .blank-page-area .page-not-found p {
+ margin: 0 0 30px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .blank-page-area .page-not-found p {
+ font-size: 28px;
+ line-height: 40px;
+ margin: 0 0 20px;
+ }
+}
+.blank-page-area .page-not-found a {
+ color: #fff;
+ font-weight: 500;
+ margin: 10px 0;
+ display: inline-block;
+ text-transform: capitalize;
+ width: 208px;
+ height: 63px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border-radius: 5px;
+ background-color: #036eb8;
+ margin-top: 20px;
+ margin: auto;
+}
+.blank-page-area .page-not-found a i {
+ margin-left: 10px;
+ font-size: 20px;
+}
+.blank-page-area .page-not-found a:hover {
+ background-color: #000;
+}
+.inner_complated {
+ text-align: center;
+}
+.inner_complated img {
+ max-width: 100%;
+}
+.img_cmpted {
+ margin: 0 0 30px;
+}
+.dsc_cmpted {
+ margin: 0 0 30px;
+ line-height: 24px;
+}
+.btn_cmpted .shop-btn {
+ width: 210px;
+ background: #036eb8;
+ text-transform: capitalize;
+ height: 45px;
+ line-height: 45px;
+ text-align: center;
+ display: inline-block;
+ color: #fff;
+ font-weight: 500;
+ border-radius: 5px;
+ font-size: 16px;
+}
+.btn_cmpted .shop-btn:hover {
+ background-color: #1d1d1d;
+}
+.quick_order {
+ margin: 60px 0 60px;
+ text-align: center;
+}
+.quick_order .title {
+ font-size: 32px;
+}
+@media only screen and (max-width: 575px) {
+ .quick_order .title {
+ font-size: 26px;
+ }
+}
+.cntct.typewriter-effect a {
+ font-size: 20px;
+ color: #eb2606;
+ margin: 15px 0 0;
+ display: inline-block;
+ font-weight: 500;
+}
+.service-right-content {
+ padding-left: 84px;
+ width: 90%;
+}
+@media only screen and (max-width: 990px) {
+ .service-right-content {
+ padding-left: 12px;
+ width: 98%;
+ }
+}
+.service-left {
+ position: relative;
+ z-index: 1;
+}
+.service-left img {
+ max-width: 100%;
+}
+.service-left-image {
+ max-width: 100%;
+ display: block;
+ border-radius: 50%;
+}
+.pd-80 {
+ padding: 80px 0 0;
+}
+.pd-64 {
+ padding: 64px 0;
+}
+.about-bg {
+ background: #fff;
+}
+.p-0 {
+ padding: 0;
+}
+.service-area .service-right-content .title {
+ position: relative;
+}
+.service-area .service-right-content .eng-text {
+ position: absolute;
+ content: '';
+ left: 0;
+ top: -50%;
+ opacity: 0.03;
+ font-weight: 600;
+ color: #036eb8;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .service-left-image {
+ margin: auto;
+ }
+}
+.service-left-image-2 {
+ position: absolute;
+ left: auto;
+ right: 25px;
+ z-index: -1;
+ top: 25px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .service-left-image-2 {
+ top: 0;
+ right: 0;
+ width: 85%;
+ max-width: 100%;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .service-left-image-2 {
+ top: 23px;
+ right: 15%;
+ max-width: 100%;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .service-left-image-2 {
+ display: none;
+ }
+ .pd-64 {
+ padding: 32px 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .service-area .service-right-content {
+ margin-top: 80px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .service-area .service-right-content {
+ margin-top: 20px;
+ }
+}
+.service-area .service-right-content .title {
+ font-size: 40px;
+ color: #333;
+ font-weight: 600;
+ margin: 0 0 30px;
+ line-height: 50px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .service-area .service-right-content .title {
+ font-size: 24px;
+ line-height: 36px;
+ }
+}
+.service-area .service-right-content .para-1 {
+ color: #666;
+ font-weight: 500;
+ font-size: 16px;
+ line-height: 30px;
+ margin: 0 0 25px;
+}
+.service-area .service-right-content .para-2 {
+ color: #5e5e5e;
+ font-weight: 400;
+ font-size: 16px;
+ line-height: 28px;
+ margin: 0 0 45px;
+}
+.service-area .service-right-content .mision-vision .mision {
+ margin-bottom: 40px;
+}
+.service-area .service-right-content .mision-vision .mision,
+.service-area .service-right-content .mision-vision .vision {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (max-width: 575px) {
+ .service-area .service-right-content .mision-vision .mision,
+ .service-area .service-right-content .mision-vision .vision {
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ }
+}
+.service-area .service-right-content .mision-vision .mision .heading,
+.service-area .service-right-content .mision-vision .vision .heading {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 235px;
+ font-size: 30px;
+ color: #4a4a4a;
+ padding-left: 20px;
+ position: relative;
+}
+.service-area .service-right-content .mision-vision .mision .heading::after,
+.service-area .service-right-content .mision-vision .vision .heading::after {
+ position: absolute;
+ top: 50%;
+ left: 0;
+ width: 10px;
+ height: 4px;
+ content: '';
+ background-color: #000;
+ margin-top: -2.5px;
+}
+.service-area .service-right-content .mision-vision .mision-desc,
+.service-area .service-right-content .mision-vision .vision-desc {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: calc(100% - 235px);
+ color: #747474;
+ line-height: 30px;
+}
+@media only screen and (max-width: 575px) {
+ .service-area .service-right-content .mision-vision .mision-desc,
+ .service-area .service-right-content .mision-vision .vision-desc {
+ width: 100%;
+ }
+}
+.promo-video {
+ border-radius: 50%;
+ position: relative;
+}
+.promo-video .overlay-box {
+ width: 98px;
+ height: 98px;
+ transition: all 0.3s ease;
+ -moz-transition: all 0.3s ease;
+ -webkit-transition: all 0.3s ease;
+ -ms-transition: all 0.3s ease;
+ -o-transition: all 0.3s ease;
+ position: absolute;
+ left: 40px;
+ top: -70px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .promo-video .overlay-box {
+ left: 35%;
+ }
+}
+.promo-video .overlay-box span {
+ position: absolute;
+ width: 98px;
+ height: 98px;
+ left: 50%;
+ top: 50%;
+ z-index: 10;
+ color: #fff;
+ font-weight: 400;
+ font-size: 38px;
+ border-radius: 50%;
+ margin-top: -49px;
+ margin-left: -49px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ transition: all 0.9s ease;
+ -moz-transition: all 0.9s ease;
+ -webkit-transition: all 0.9s ease;
+ -ms-transition: all 0.9s ease;
+ -o-transition: all 0.9s ease;
+ background-color: #036eb8;
+}
+@media only screen and (max-width: 479px) {
+ .promo-video .overlay-box span {
+ width: 60px;
+ height: 60px;
+ margin-top: -30px;
+ margin-left: -30px;
+ font-size: 14px;
+ }
+}
+.ripple,
+.ripple:after,
+.ripple:before {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ width: 98px;
+ height: 98px;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+ border-radius: 50%;
+ -webkit-box-shadow: 0 0 0 0 rgba(230, 167, 131, 0.8);
+ -ms-box-shadow: 0 0 0 0 rgba(230, 167, 131, 0.8);
+ -o-box-shadow: 0 0 0 0 rgba(230, 167, 131, 0.8);
+ box-shadow: 0 0 0 0 rgba(230, 167, 131, 0.8);
+ -webkit-animation: ripple 3s infinite;
+ animation: ripple 3s infinite;
+}
+@media only screen and (max-width: 479px) {
+ .ripple,
+ .ripple:after,
+ .ripple:before {
+ width: 60px;
+ height: 60px;
+ }
+}
+.ripple:before {
+ -webkit-animation-delay: 0.9s;
+ animation-delay: 0.9s;
+ content: '';
+ position: absolute;
+}
+.ripple:after {
+ -webkit-animation-delay: 0.6s;
+ animation-delay: 0.6s;
+ content: '';
+ position: absolute;
+}
+@-webkit-keyframes ripple {
+ 70% {
+ -webkit-box-shadow: 0 0 0 70px rgba(37, 24, 24, 0);
+ box-shadow: 0 0 0 70px rgba(37, 24, 24, 0);
+ }
+ 100% {
+ -webkit-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ }
+}
+@keyframes ripple {
+ 70% {
+ -webkit-box-shadow: 0 0 0 70px rgba(255, 255, 255, 0);
+ box-shadow: 0 0 0 70px rgba(255, 255, 255, 0);
+ }
+ 100% {
+ -webkit-box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ box-shadow: 0 0 0 0 rgba(255, 255, 255, 0);
+ }
+}
+.team-wrapper .team-image img {
+ max-width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ width: 100%;
+}
+.team-wrapper .team-inner {
+ margin-top: -30px;
+ padding: 20px 0 20px 30px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ background-color: #fff;
+ position: relative;
+}
+.team-wrapper .team-inner .team-content {
+ text-align: left;
+ line-height: 1;
+}
+.team-wrapper .team-inner .team-content .title {
+ font-size: 18px;
+ color: #393939;
+ font-weight: 500;
+ text-transform: uppercase;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.team-wrapper .team-inner .team-content .sub-title {
+ font-size: 16px;
+ font-weight: 400;
+ color: grey;
+ text-transform: uppercase;
+ margin: 9px 0 27px;
+ display: block;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.team-wrapper .team-inner .team-social {
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+}
+.team-wrapper .team-inner .team-social li + li {
+ margin-left: 10px;
+}
+.team-wrapper .team-inner .team-social li a {
+ width: 36px;
+ height: 36px;
+ background-color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ color: #fff;
+ font-size: 14px;
+ position: relative;
+ overflow: hidden;
+ z-index: 1;
+ margin-top: -1px;
+ border-radius: 5px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.team-wrapper:hover .team-image img {
+ -webkit-transform: scale(1.1) rotate(3deg);
+ transform: scale(1.1) rotate(3deg);
+}
+.team-wrapper:hover .team-inner {
+ margin-left: 40px;
+ background-color: #036eb8;
+}
+@media only screen and (max-width: 767px) {
+ .team-wrapper:hover .team-inner {
+ margin-left: 30px;
+ }
+}
+.team-wrapper:hover .team-inner .title {
+ color: #fff;
+}
+.team-wrapper:hover .team-inner .sub-title {
+ color: #fff;
+}
+.team-wrapper:hover .team-inner .team-social li a {
+ background-color: #fff;
+ color: #036eb8;
+}
+.gmap_canvas {
+ line-height: 0;
+}
+.gmap_canvas iframe {
+ overflow: hidden;
+ background: 0 0 !important;
+ height: 600px;
+ width: 100%;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .gmap_canvas iframe {
+ height: 400px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .gmap_canvas iframe {
+ height: 350px;
+ }
+}
+.contact-wrapper .contact-info {
+ padding: 32px 40px 48px;
+ background: #fff;
+ margin: 0 14px;
+}
+@media only screen and (max-width: 575px) {
+ .contact-wrapper .contact-info {
+ padding: 0;
+ }
+}
+.contact-wrapper .contact-info .sub-title {
+ font-size: 18px;
+ font-weight: 500;
+ color: #036eb8;
+ margin: 0 0 5px;
+ display: block;
+}
+.contact-wrapper .contact-info .heading {
+ font-size: 36px;
+ color: #424242;
+ font-weight: 500;
+ margin: 0 0 35px;
+ line-height: 55px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .contact-wrapper .contact-info .heading {
+ font-size: 28px;
+ line-height: 45px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .contact-wrapper .contact-info .heading {
+ font-size: 24px;
+ line-height: 35px;
+ }
+}
+.contact-wrapper .contact-info .single-contact {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ /* justify-content: center;
+ align-items: center; */
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ border-bottom: 1px solid #eee;
+ padding: 63px;
+ margin-left: 33%;
+}
+@media only screen and (max-width: 767px) {
+ .contact-wrapper .contact-info .single-contact {
+ padding: 24px 0;
+ margin-left: 0;
+ }
+}
+.contact-wrapper .contact-info .single-contact:last-child {
+ border-bottom: none;
+}
+.contact-wrapper .contact-info .single-contact .icon-box {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ /* justify-content: center;
+ align-items: center; */
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ margin-right: 30px;
+ position: relative;
+ -webkit-transition: all 0.5s ease-in-out;
+ transition: all 0.5s ease-in-out;
+}
+.contact-wrapper .contact-info .single-contact .icon-box i {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ font-size: 36px;
+ color: #fff;
+}
+@media only screen and (max-width: 575px) {
+ .contact-wrapper .contact-info .single-contact .icon-box {
+ margin-right: 0;
+ }
+ .icon-box img {
+ max-width: 50%;
+ margin-left: 10px;
+ }
+}
+.contact-wrapper .contact-info .single-contact .info-box {
+ width: calc(100% - 110px);
+}
+@media only screen and (max-width: 479px) {
+ .contact-wrapper .contact-info .single-contact .info-box {
+ width: calc(100% - 80px);
+ }
+}
+.contact-wrapper .contact-info .single-contact .info-box .title {
+ font-size: 40px;
+ color: #036eb8;
+ font-weight: 600;
+ margin: 0 0 24px;
+ word-wrap: break-word;
+}
+@media only screen and (max-width: 750px) {
+ .contact-wrapper .contact-info .single-contact .info-box .title {
+ font-size: 20px;
+ margin: 0 0 5px;
+ }
+}
+.contact-wrapper .contact-info .single-contact .info-box p {
+ font-size: 14px;
+ color: #999;
+ margin: 0;
+}
+.contact-wrapper .contact-info .single-contact .info-box a {
+ color: #848484;
+}
+.contact-wrapper .contact-info .single-contact .info-box a:hover {
+ color: #036eb8;
+}
+.contact-wrapper .contact-info .single-contact:hover i {
+ -webkit-transform: scale(0.95) rotate(0);
+ transform: scale(0.95) rotate(0);
+}
+
+.contact-wrapper .contact-info .social {
+ margin-top: 60px;
+}
+.contact-wrapper .contact-info .social li {
+ display: inline-block;
+ margin-left: 10px;
+}
+.contact-wrapper .contact-info .social li a {
+ width: 36px;
+ height: 36px;
+ color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ font-size: 16px;
+ background-color: #000;
+ border-radius: 5px;
+}
+.contact-wrapper .contact-info .social li a:hover {
+ background-color: #036eb8;
+}
+.contact-form {
+ padding: 60px 40px 60px 40px;
+ -webkit-box-shadow: 0 8px 36px 0 rgba(0, 0, 0, 0.1);
+ box-shadow: 0 8px 36px 0 rgba(0, 0, 0, 0.1);
+ border-radius: 20px;
+}
+.contact-form .contact-title {
+ margin: 0 0 31px;
+}
+.contact-form .contact-title .title {
+ font-size: 36px;
+ color: #424242;
+ font-weight: 500;
+ margin: 0 0 14px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .contact-form .contact-title .title {
+ font-size: 28px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .contact-form .contact-title .title {
+ font-size: 24px;
+ }
+}
+.contact-form .contact-title p {
+ color: #747474;
+ line-height: 27px;
+}
+.contact-form .contact-form-style input,
+.contact-form .contact-form-style textarea {
+ background: 0;
+ border: 1px solid #c1c1c1;
+ margin-bottom: 30px;
+ color: #474747;
+ font-size: 14px;
+}
+.contact-form .contact-form-style input::-webkit-input-placeholder,
+.contact-form .contact-form-style textarea::-webkit-input-placeholder {
+ font-style: italic;
+ color: #999;
+}
+.contact-form .contact-form-style input::-moz-placeholder,
+.contact-form .contact-form-style textarea::-moz-placeholder {
+ font-style: italic;
+ color: #999;
+}
+.contact-form .contact-form-style input:-ms-input-placeholder,
+.contact-form .contact-form-style textarea:-ms-input-placeholder {
+ font-style: italic;
+ color: #999;
+}
+.contact-form .contact-form-style input::-ms-input-placeholder,
+.contact-form .contact-form-style textarea::-ms-input-placeholder {
+ font-style: italic;
+ color: #999;
+}
+.contact-form .contact-form-style input::placeholder,
+.contact-form .contact-form-style textarea::placeholder {
+ font-style: italic;
+ color: #999;
+}
+.contact-form .contact-form-style input:focus,
+.contact-form .contact-form-style textarea:focus {
+ border-color: #036eb8;
+}
+.contact-form .contact-form-style textarea {
+ margin-bottom: 0;
+ height: 200px;
+}
+.contact-form p {
+ color: #474747;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .contact-form {
+ margin-top: 60px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .contact-form {
+ padding: 40px 20px;
+ }
+}
+.contact-form button {
+ font-size: 14px;
+ letter-spacing: 2px;
+ line-height: 1;
+ font-weight: 400;
+ text-transform: uppercase;
+}
+.contact-form button i {
+ font-size: 16px;
+ margin-left: 10px;
+}
+.btn {
+ padding: 0;
+ font-size: 16px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border: 0;
+ font-weight: 400;
+ line-height: 1;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.f-20 {
+ font-size: 30px;
+ font-weight: 600;
+}
+.btn-primary {
+ color: #fff;
+ border: 1px solid #036eb8;
+ background: #fff;
+ width: 216px;
+ height: 48px;
+ color: #036eb8;
+ z-index: 1;
+ position: relative;
+ overflow: hidden;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-primary::before {
+ position: absolute;
+ content: '';
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ background: #036eb8;
+ border: 1px solid #036eb8;
+ color: #fff;
+ z-index: -1;
+ -webkit-transition: 0.3s linear;
+ transition: 0.3s linear;
+ -webkit-transform: scale(0);
+ transform: scale(0);
+ border-radius: 50%;
+ width: 100%;
+ height: 100%;
+}
+.btn-primary:hover {
+ color: #fff;
+ -webkit-box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ box-shadow: -1px 10px 80px -15px rgba(0, 0, 0, 0.3);
+ background: 0;
+ -webkit-transform: translateY(-3px);
+ transform: translateY(-3px);
+}
+.btn-primary:hover::before {
+ -webkit-transform: scale(1.5);
+ transform: scale(1.5);
+}
+.btn-primary.blog-btn {
+ background: #036eb8;
+ width: 130px;
+ height: 40px;
+ font-size: 14px;
+ text-transform: uppercase;
+ font-weight: 400;
+}
+.btn-primary.blog-btn::before {
+ background: #036eb8;
+}
+.btn-check:focus + .btn,
+.btn:focus {
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+}
+.btn-check:focus + .btn-primary,
+.btn-primary:focus {
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border: 1px solid #036eb8;
+ color: #036eb8;
+}
+.btn-check:active + .btn-primary,
+.btn-check:checked + .btn-primary,
+.btn-primary.active,
+.btn-primary:active,
+.show > .btn-primary.dropdown-toggle {
+ outline: 0;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ border: 0;
+}
+.category-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.category-wrapper .category-inner {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ width: 180px;
+ height: 180px;
+ border: 2px solid #474747;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ border-radius: 50%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ position: relative;
+ margin: auto;
+}
+@media only screen and (max-width: 479px) {
+ .category-wrapper .category-inner {
+ width: 140px;
+ height: 140px;
+ }
+}
+.category-wrapper .category-inner:after {
+ content: '';
+ position: absolute;
+ top: -1px;
+ left: -1px;
+ right: -1px;
+ bottom: -1px;
+ border-radius: 100%;
+ z-index: -1;
+ border: 2px dashed #036eb8;
+ opacity: 0;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.category-wrapper .category-inner .category-single-item {
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center;
+ text-align: center;
+}
+.category-wrapper .category-inner .category-single-item img {
+ margin: auto;
+}
+@media only screen and (max-width: 479px) {
+ .category-wrapper .category-inner .category-single-item img {
+ max-width: 100%;
+ }
+}
+.category-wrapper .category-inner .category-single-item .title {
+ display: block;
+ font-family: Rubik, sans-serif;
+ font-weight: 600;
+ color: #474747;
+ margin: 12px 0 0;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+@media only screen and (max-width: 479px) {
+ .category-wrapper .category-inner .category-single-item .title {
+ font-size: 13px;
+ }
+}
+.category-wrapper .category-inner:hover {
+ border-color: transparent;
+}
+.category-wrapper .category-inner:hover:after {
+ opacity: 1;
+ -webkit-animation: spinAround 9s linear infinite;
+ animation: spinAround 9s linear infinite;
+}
+.category-wrapper .category-inner:hover .title {
+ color: #036eb8;
+}
+@-webkit-keyframes spinAround {
+ from {
+ -webkit-transform: rotate(0);
+ }
+ to {
+ -webkit-transform: rotate(360deg);
+ }
+}
+@keyframes spinAround {
+ from {
+ -webkit-transform: rotate(0);
+ transform: rotate(0);
+ }
+ to {
+ -webkit-transform: rotate(360deg);
+ transform: rotate(360deg);
+ }
+}
+.nav-center .product-tab-nav .nav-item {
+ display: inline-block;
+ vertical-align: top;
+ font-size: 18px;
+ text-transform: capitalize;
+ padding: 0;
+ cursor: pointer;
+ font-weight: 500;
+ -webkit-transition: all 0.3s ease;
+ transition: all 0.3s ease;
+}
+@media only screen and (max-width: 479px) {
+ .nav-center .product-tab-nav .nav-item {
+ margin: 0 0 20px 5px;
+ font-size: 16px;
+ }
+}
+.nav-center .product-tab-nav .nav-item:last-child {
+ margin-right: 0;
+}
+.nav-center .product-tab-nav .nav-item .nav-link {
+ color: #767676;
+}
+.nav-center .product-tab-nav .nav-item .nav-link span {
+ width: 131px;
+ height: 44px;
+ margin: 0;
+}
+@media only screen and (max-width: 575px) {
+ .nav-center .product-tab-nav .nav-item .nav-link span {
+ width: 115px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .nav-center .product-tab-nav .nav-item .nav-link span {
+ width: 80px;
+ }
+}
+.nav-center .product-tab-nav .nav-item .nav-link span::after {
+ background-image: url(../images/icons/tab-bg-2.png);
+}
+@media only screen and (max-width: 479px) {
+ .nav-center .product-tab-nav .nav-item .nav-link span::after {
+ background-size: contain;
+ }
+}
+.nav-center .product-tab-nav .nav-item.active,
+.nav-center .product-tab-nav .nav-item:hover {
+ color: #fff;
+}
+.nav-center .product-tab-nav .nav-item.active span::after,
+.nav-center .product-tab-nav .nav-item:hover span::after {
+ opacity: 1;
+}
+@media only screen and (max-width: 575px) {
+ .nav-center.nav-center-2 .product-tab-nav {
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .nav-center.nav-center-2 .product-tab-nav .nav-item {
+ margin: 0 0 0 5px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .nav-center.nav-center-2 .product-tab-nav .nav-item .nav-link span {
+ width: 100px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .nav-center.nav-center-2 .product-tab-nav .nav-item .nav-link span::after {
+ background-size: contain;
+ }
+}
+.mb-n-30px {
+ margin-bottom: -30px;
+}
+.product-tab-nav.nav {
+ -ms-flex-wrap: inherit;
+ flex-wrap: inherit;
+}
+.product-tab-nav .nav-item {
+ display: inline-block;
+ vertical-align: top;
+ font-size: 18px;
+ text-transform: capitalize;
+ padding: 0;
+ cursor: pointer;
+ font-weight: 500;
+ -webkit-transition: all 0.3s ease;
+ transition: all 0.3s ease;
+}
+.product-tab-nav .nav-item .nav-link {
+ color: #393939;
+ padding: 0;
+ position: relative;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.product-tab-nav .nav-item .nav-link span {
+ position: relative;
+ z-index: 1;
+ width: 100%;
+ height: 65px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin: 5px 0 0;
+}
+.product-tab-nav .nav-item .nav-link span::after {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ content: '';
+ background-image: url(../images/icons/tab-bg.png);
+ background-repeat: no-repeat;
+ background-position: center;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ width: 100%;
+ height: 100%;
+ z-index: -1;
+ opacity: 0;
+}
+.product-tab-nav .nav-item .nav-link.active,
+.product-tab-nav .nav-item .nav-link:hover {
+ color: #fff;
+}
+.product-tab-nav .nav-item .nav-link.active span::after,
+.product-tab-nav .nav-item .nav-link:hover span::after {
+ opacity: 1;
+}
+@media only screen and (max-width: 575px) {
+ .col-xs-6 {
+ width: 50%;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .col-xs-6 {
+ width: 100%;
+ }
+}
+.mt-60px {
+ padding-top: 56px;
+}
+@media only screen and (max-width: 479px) {
+ .mt-60px {
+ padding-top: 24px;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .grid-4-view .product .content .title a {
+ font-size: 14px;
+ }
+}
+.product {
+ position: relative;
+ background: #fff;
+ padding: 56px;
+}
+.updoanlod {
+ position: relative;
+ background: #fff;
+ padding: 24px;
+}
+.updoanlod img {
+ max-width: 100%;
+}
+.updoanlod-icon {
+ position: absolute;
+ padding: 80px;
+ margin-right: 2%;
+ text-align: center;
+}
+.contact {
+ padding: 48px;
+ background: #fff;
+ text-align: center;
+}
+.contact p {
+ text-align: center;
+ width: 100%;
+ padding-top: 40px;
+}
+.contact img {
+ max-width: 100%;
+}
+@media only screen and (max-width: 1000px) {
+ .contact {
+ padding: 24px;
+ background: none;
+ }
+ .contact img {
+ max-width: 50%;
+ }
+}
+@media only screen and (max-width: 750px) {
+ .content-desc-wrap {
+ padding: 0 24px;
+ margin-bottom: 2em;
+ font-size: 14px;
+ }
+ .updoanlod-icon {
+ position: absolute;
+ padding: 48px;
+ margin: 2%;
+ text-align: center;
+ }
+}
+.back-bg {
+ background: #f9f9f9;
+ position: relative;
+}
+.product .add-to-cart {
+ display: block;
+ width: 100%;
+ height: 64px;
+ line-height: 64px;
+ background: #036eb8;
+ text-align: center;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ font-size: 14px;
+ z-index: 11;
+ margin: auto;
+ font-weight: 400;
+ visibility: hidden;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ color: #fff;
+ opacity: 0;
+ text-transform: uppercase;
+ overflow: hidden;
+}
+@media only screen and (min-width: 320px) and (max-width: 1366px) {
+ .product {
+ position: relative;
+ background: #fff;
+ padding: 48px 12px;
+ }
+ .product .add-to-cart {
+ height: 32px;
+ line-height: 32px;
+ }
+}
+.product .add-to-cart:hover {
+ color: #fff;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.2);
+}
+.contact-area {
+ padding: 64px 0;
+}
+.product-bg {
+ background: #f5f5f5;
+}
+@media only screen and (max-width: 1400px) {
+ .product-bg {
+ padding-top: 2em;
+ }
+}
+.product .thumb {
+ position: relative;
+ overflow: hidden;
+}
+.product .thumb .image {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ text-align: center;
+}
+.product .thumb .image img {
+ z-index: 1;
+ max-width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.product .thumb .image img.hover-image {
+ position: absolute;
+ z-index: 2;
+ top: 0;
+ left: 20%;
+ opacity: 0;
+}
+.product .thumb .badges {
+ position: absolute;
+ z-index: 8;
+ top: 18px;
+ left: -2px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+}
+.product .thumb .badges span {
+ font-size: 12px;
+ line-height: 1.7;
+ display: block;
+ padding: 0 10px;
+ text-align: center;
+ text-transform: uppercase;
+ border-radius: 3px;
+ color: #fff;
+ font-weight: 500;
+}
+.product .thumb .badges span + span {
+ margin-top: 12px;
+}
+.product .thumb .badges span.new {
+ background-color: #000;
+}
+.product .thumb .badges span.sale {
+ background: #036eb8;
+}
+.product .thumb .actions {
+ position: absolute;
+ z-index: 9;
+ top: 18px;
+ right: 18px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.product .thumb .actions .action {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ width: 40px;
+ height: 40px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ text-decoration: none;
+ color: #000;
+ border-radius: 50%;
+ background-color: #eaeaea;
+ font-size: 24px;
+}
+.product .thumb .actions .action:hover {
+ color: #fff;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.2);
+ -webkit-transform: translateY(-1px);
+ transform: translateY(-1px);
+ background: #036eb8;
+}
+.product .thumb .actions .action + .action {
+ margin-top: 15px;
+}
+.product .thumb .actions .action:not(.wishlist) {
+ visibility: hidden;
+ -webkit-transform: translateY(20px);
+ transform: translateY(20px);
+ opacity: 0;
+}
+.product .thumb .actions .action.active {
+ background: #036eb8;
+}
+.product .content {
+ position: relative;
+ z-index: 10;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ background-color: #fff;
+}
+.product .content span {
+ color: #999;
+ font-size: 14px;
+ line-height: 18px;
+ height: 38px;
+ overflow: hidden;
+}
+.product .content .ratings {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ margin-bottom: 4px;
+}
+.product .content .ratings .rating-wrap {
+ font-size: 14px;
+ line-height: 1;
+ position: relative;
+ color: #e4e4e4;
+ white-space: nowrap;
+}
+.product .content .ratings .rating-wrap::before {
+ font-family: FontAwesome;
+ content: ' ';
+}
+.product .content .ratings .rating-wrap .star {
+ position: absolute;
+ top: 0;
+ left: 0;
+ overflow: hidden;
+ color: #ffde00;
+}
+.product .content .ratings .rating-wrap .star::before {
+ font-family: FontAwesome;
+ content: ' ';
+}
+.product .content .ratings .rating-num {
+ font-size: 14px;
+ line-height: 1;
+ margin-left: 6px;
+ color: #9f9e9e;
+ display: none;
+}
+.product .content .title {
+ font-size: 16px;
+ margin: 32px 0 15px;
+ font-family: Rubik, sans-serif;
+ max-height: 20px;
+ text-overflow: ellipsis; /*设置超出部分显示...*/
+ -o-text-overflow: ellipsis;
+ overflow: hidden;
+}
+.product .content .title a {
+ text-decoration: none;
+ color: #333;
+ font-size: 16px;
+ font-weight: bold;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 575px) {
+ .product .content .title a {
+ font-size: 14px;
+ }
+}
+.product .content .price {
+ font-size: 16px;
+ font-family: Rubik, sans-serif;
+ line-height: 1;
+ font-weight: 500;
+}
+.product .content .price:not(:last-child) {
+ margin-bottom: 20px;
+}
+.product .content .price span.new {
+ color: #393939;
+ font-weight: 500;
+}
+.product .content .price span.old {
+ font-size: 14px;
+ margin-left: 10px;
+ text-decoration: line-through;
+ color: #747474;
+}
+.product .content .btn {
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center;
+}
+.product:hover {
+ -webkit-transform: translateY(-10px);
+ -moz-transform: translateY(-10px);
+ -ms-transform: translateY(-10px);
+ transition: all 0.5s;
+ -webkit-transition: all 0.5s;
+ -ms-transition: all 0.5s;
+ cursor: pointer;
+}
+.product:hover .thumb .image img:not(:last-child) {
+ opacity: 0;
+}
+.product:hover .thumb .image img.hover-image {
+ opacity: 1;
+}
+.product:hover .thumb .actions .action {
+ visibility: visible;
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ opacity: 1;
+}
+.product:hover .content .title a {
+ color: #474747;
+}
+.product:hover .content .title a:hover {
+ color: #036eb8;
+}
+.product:hover .add-to-cart {
+ visibility: visible;
+ -webkit-transform: translateY(20px);
+ transform: translateY(20px);
+ opacity: 1;
+}
+.tab-content .tab-pane {
+ display: block;
+ overflow: hidden;
+ height: 0;
+ visibility: hidden;
+ max-width: 100%;
+ opacity: 0;
+}
+.tab-content .tab-pane.active {
+ height: auto;
+ visibility: visible;
+ opacity: 1;
+ overflow: visible;
+}
+.single-col {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 24.8%;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .single-col {
+ width: 100%;
+ }
+}
+.single-col .single-banner {
+ position: relative;
+ display: block;
+ overflow: hidden;
+ border-radius: 5px;
+}
+.single-col .single-banner img {
+ width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+
+.single-col .single-banner .banner-content {
+ position: absolute;
+ top: 0;
+ left: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding: 60px 30px;
+ width: 100%;
+ height: 100%;
+ line-height: 1;
+ -webkit-box-pack: end;
+ -ms-flex-pack: end;
+ justify-content: flex-end;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (max-width: 767px) {
+ .single-col .single-banner .banner-content {
+ padding: 40px 30px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .single-col .single-banner .banner-content {
+ padding: 40px 20px;
+ }
+}
+.single-col .single-banner .banner-content .category {
+ display: block;
+ font-size: 16px;
+ color: #414141;
+ font-weight: 500;
+ margin: 0 0 12px;
+}
+@media only screen and (max-width: 479px) {
+ .single-col .single-banner .banner-content .category {
+ margin: 0 0 5px;
+ }
+}
+.single-col .single-banner .banner-content .title {
+ font-size: 30px;
+ color: #424242;
+ font-weight: 500;
+ text-transform: capitalize;
+ display: block;
+ margin: 0 0 28px;
+ line-height: 43px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .single-col .single-banner .banner-content .title {
+ font-size: 24px;
+ line-height: 36px;
+ margin: 0 0 20px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .single-col .single-banner .banner-content .title {
+ font-size: 24px;
+ margin: 0 0 15px;
+ line-height: 32px;
+ }
+}
+.single-col .single-banner .banner-content .shop-link {
+ width: 120px;
+ height: 40px;
+ font-size: 14px;
+}
+.single-col.center-col {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50.3%;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .single-col.center-col {
+ width: 100%;
+ margin: 30px 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .single-col.center-col .banner-content {
+ padding: 12px 20px;
+ }
+}
+.plr-15px {
+ padding: 0 15px;
+}
+@media only screen and (max-width: 479px) {
+ .plr-15px {
+ padding: 0;
+ }
+}
+.banner-area-2 .single-banner {
+ position: relative;
+ overflow: hidden;
+ border-radius: 0;
+}
+.banner-area-2 .single-banner.nth-child-1 {
+ margin-right: 24px;
+}
+@media only screen and (max-width: 767px) {
+ .banner-area-2 .single-banner.nth-child-1 {
+ margin-right: 0;
+ }
+}
+.banner-area-2 .single-banner.nth-child-2 {
+ margin-bottom: 24px;
+}
+
+.banner-area-2 .single-banner img {
+ max-width: 100%;
+ width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.banner-area-2 .single-banner .banner-content {
+ position: absolute;
+ top: 0;
+ /* bottom: 0; */
+ left: 0;
+ right: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+.banner-area-2 .single-banner .banner-content.nth-child-1 {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.banner-area-2 .single-banner .banner-content.nth-child-2 {
+ left: 0;
+}
+
+.banner-area-2 .single-banner .banner-content.nth-child-2 .category {
+ color: #414141;
+}
+.banner-area-2 .single-banner .banner-content.nth-child-2 .title {
+ color: #fff;
+ font-size: 30px;
+ line-height: 43px;
+ font-weight: 600;
+ margin: 0 0 10px;
+ background: rgba(3, 110, 184, 0.6);
+ width: 100%;
+ text-align: center;
+ padding: 20px 0;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-2 .single-banner .banner-content.nth-child-2 .title {
+ font-size: 20px;
+ line-height: 30px;
+ margin: 0 0 5px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .banner-area-2 .single-banner .banner-content.nth-child-2 .title {
+ font-size: 20px;
+ line-height: 28px;
+ margin: 0;
+ }
+}
+.banner-area-2 .single-banner .banner-content.nth-child-3 {
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+}
+
+.banner-area-2 .single-banner .banner-content.nth-child-3 .category {
+ color: #414141;
+}
+.banner-area-2 .single-banner .banner-content.nth-child-3 .title {
+ color: #fff;
+ font-size: 30px;
+ line-height: 43px;
+ font-weight: 600;
+ margin: 0 0 10px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-2 .single-banner .banner-content.nth-child-3 .title {
+ font-size: 20px;
+ line-height: 30px;
+ margin: 0 0 5px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .banner-area-2 .single-banner .banner-content.nth-child-3 .title {
+ font-size: 20px;
+ line-height: 28px;
+ margin: 0;
+ }
+}
+.banner-area-2 .single-banner .banner-content .category {
+ display: block;
+ color: #fff;
+ font-size: 16px;
+ font-weight: 500;
+ margin: 0 0 3px;
+}
+.banner-area-2 .single-banner .banner-content .title {
+ color: #fff;
+ font-size: 36px;
+ line-height: 46px;
+ font-weight: 600;
+ margin: 0 0 10px;
+ background: rgba(3, 110, 184, 0.6);
+ width: 100%;
+ text-align: center;
+ padding: 20px 0;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-2 .single-banner .banner-content .title {
+ font-size: 24px;
+ line-height: 36px;
+ margin: 0 0 5px;
+ }
+}
+.banner-area-2 .single-banner .banner-content .shop-link {
+ font-size: 14px;
+ width: 120px;
+ height: 40px;
+ margin: 21px 0 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .banner-area-2 .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-2 .single-banner .banner-content .shop-link {
+ margin: 10px 0 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .banner-area-2 .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ font-size: 12px;
+ width: 100px;
+ height: 35px;
+ }
+ .banner-area-2 .single-banner .banner-content .title {
+ font-size: 20px;
+ }
+}
+.banner-area-2 .single-banner:hover img {
+ -webkit-transform: scale(1.1) rotate(3deg);
+ transform: scale(1.1) rotate(3deg);
+}
+.banner-area-3 .single-banner {
+ position: relative;
+ overflow: hidden;
+ border-radius: 0;
+}
+.banner-area-3 .single-banner img {
+ max-width: 100%;
+ width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.banner-area-3 .single-banner .banner-content {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: auto;
+ right: 40px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+.banner-area-3 .single-banner .banner-content .category {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ color: #fff;
+ font-size: 16px;
+ font-weight: 500;
+ margin: 0 0 15px;
+ background-image: url(/assets/images/banner/sticker-bg.png);
+ width: 80px;
+ height: 32px;
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-position: center;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ padding-left: 12px;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+.banner-area-3 .single-banner .banner-content .title {
+ color: #424242;
+ font-size: 30px;
+ line-height: 43px;
+ font-weight: 500;
+ margin: 0 0 10px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-3 .single-banner .banner-content .title {
+ font-size: 24px;
+ line-height: 36px;
+ margin: 0 0 5px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .banner-area-3 .single-banner .banner-content .title {
+ font-size: 20px;
+ line-height: 20px;
+ }
+ .banner-area-2 .single-banner .banner-content .title {
+ font-size: 20px;
+ line-height: 20px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .banner-area-3 .single-banner .banner-content .title {
+ font-size: 20px;
+ line-height: 28px;
+ margin: 0 0 5px;
+ }
+}
+.banner-area-3 .single-banner .banner-content .shop-link {
+ font-size: 14px;
+ width: 120px;
+ height: 40px;
+ margin: 21px 0 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .banner-area-3 .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .banner-area-3 .single-banner .banner-content .shop-link {
+ margin: 10px 0 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .banner-area-3 .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ font-size: 12px;
+ width: 100px;
+ height: 35px;
+ }
+}
+.banner-area-3 .single-banner:hover img {
+ -webkit-transform: scale(1.1) rotate(3deg);
+ transform: scale(1.1) rotate(3deg);
+}
+.slider-banner .single-banner {
+ position: relative;
+ overflow: hidden;
+ border-radius: 0;
+}
+.slider-banner .single-banner img {
+ max-width: 100%;
+ width: 100%;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .slider-banner .single-banner img {
+ height: 237.5px;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+ }
+}
+.slider-banner .single-banner .banner-content {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ left: 40px;
+ right: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+}
+.slider-banner .single-banner .banner-content .category {
+ display: block;
+ color: #fff;
+ font-size: 16px;
+ font-weight: 400;
+ margin: 0 0 3px;
+}
+.slider-banner .single-banner .banner-content .title {
+ color: #424242;
+ font-size: 30px;
+ line-height: 38px;
+ font-weight: 400;
+ margin: 0;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-banner .single-banner .banner-content .title {
+ font-size: 24px;
+ line-height: 36px;
+ margin: 0 0 5px;
+ }
+}
+.slider-banner .single-banner .banner-content .shop-link {
+ font-size: 14px;
+ width: 120px;
+ height: 40px;
+ margin: 21px 0 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .slider-banner .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-banner .single-banner .banner-content .shop-link {
+ margin: 10px 0 0;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .slider-banner .single-banner .banner-content .shop-link {
+ margin: 15px 0 0;
+ font-size: 12px;
+ width: 100px;
+ height: 35px;
+ }
+}
+.slider-banner .single-banner:hover img {
+ -webkit-transform: scale(1.1) rotate(3deg);
+ transform: scale(1.1) rotate(3deg);
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-banner .responsive-flex {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ padding: 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .slider-banner .responsive-flex .single-banner {
+ margin-top: 30px;
+ padding: 0 15px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .slider-banner .responsive-flex .single-banner img {
+ -webkit-transform: none;
+ transform: none;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .slider-banner .responsive-flex .single-banner {
+ margin-top: 30px;
+ }
+}
+.single-blog {
+ position: relative;
+}
+.single-blog .blog-image {
+ overflow: hidden;
+ border-radius: 20px;
+}
+.single-blog .blog-image img {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.single-blog:hover .blog-image img {
+ -webkit-transform: scale(1.1) rotate(3deg);
+ transform: scale(1.1) rotate(3deg);
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.single-blog .blog-text {
+ padding: 30px 0 0 0;
+}
+.single-blog .blog-text .blog-heading {
+ margin: 15px 0 21px 0;
+ font-size: 30px;
+ font-weight: 400;
+ line-height: 43px;
+}
+@media only screen and (min-width: 1200px) and (max-width: 1599px) {
+ .single-blog .blog-text .blog-heading {
+ font-size: 30px;
+ }
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .single-blog .blog-text .blog-heading {
+ font-size: 24px;
+ line-height: 36px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .single-blog .blog-text .blog-heading {
+ font-size: 21px;
+ line-height: 32px;
+ }
+}
+.single-blog .blog-text .blog-heading .blog-heading-link {
+ color: #424242;
+}
+.single-blog .blog-text .blog-heading .blog-heading-link:hover {
+ color: #036eb8;
+}
+.single-blog .blog-text .blog-detail-text {
+ margin: 10px 0;
+}
+.single-blog .blog-text p {
+ margin-bottom: 25px;
+}
+.single-blog .blog-athor-date span + span {
+ margin-left: 15px;
+}
+.single-blog .blog-athor-date span {
+ color: #adadad;
+}
+.single-blog .blog-athor-date span.blog-date {
+ color: #424242;
+}
+.single-blog .blog-athor-date a {
+ color: #036eb8;
+ font-weight: 400;
+ display: inline-block;
+ font-size: 16px;
+ position: relative;
+ padding: 0 5px;
+}
+.single-blog .blog-athor-date a::after {
+ position: absolute;
+ top: auto;
+ bottom: 6px;
+ right: -8px;
+ width: 6px;
+ height: 6px;
+ content: '';
+ background-color: #3d3d3d;
+ border-radius: 50%;
+}
+.single-blog .blog-athor-date a:hover {
+ color: #036eb8;
+}
+.single-blog .blog-athor-date a i {
+ color: #036eb8;
+ margin-right: 5px;
+}
+.blog-post-content-inner .blog-title {
+ font-size: 36px;
+ font-weight: 500;
+ margin: 15px 0 35px;
+ line-height: 1.4;
+ color: #2d2d2d;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .blog-post-content-inner .blog-title {
+ font-size: 28px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .blog-post-content-inner .blog-title {
+ font-size: 24px;
+ }
+}
+.blog-post-content-inner .blog-athor-date span + span {
+ margin-left: 30px;
+}
+.blog-post-content-inner .blog-athor-date span {
+ color: #adadad;
+ font-size: 18px;
+ font-weight: 500;
+}
+.blog-post-content-inner .blog-athor-date span.blog-date {
+ color: #424242;
+}
+.blog-post-content-inner .blog-athor-date a {
+ color: #036eb8;
+ font-weight: 400;
+ display: inline-block;
+ font-size: 18px;
+ position: relative;
+ padding: 0 5px;
+}
+.blog-post-content-inner .blog-athor-date a::after {
+ position: absolute;
+ top: auto;
+ bottom: 9px;
+ right: -19px;
+ width: 9px;
+ height: 9px;
+ content: '';
+ background-color: #3d3d3d;
+ border-radius: 50%;
+}
+.blog-post-content-inner .blog-athor-date a:hover {
+ color: #036eb8;
+}
+.blog-post-content-inner .blog-athor-date a i {
+ color: #036eb8;
+ margin-right: 5px;
+}
+.blog-post-content-inner .title {
+ font-size: 30px;
+ color: #2d2d2d;
+ margin: 20px 0 30px;
+ display: block;
+ font-weight: 400;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .blog-post-content-inner .title {
+ font-size: 28px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .blog-post-content-inner .title {
+ font-size: 24px;
+ }
+}
+.blog-post-content-inner P {
+ color: #525252;
+ line-height: 30px;
+ margin-bottom: 40px;
+}
+.blog-post-content-inner P + p {
+ margin-bottom: 40px;
+}
+.single-post-content .quate-speech-area {
+ position: relative;
+ min-height: 360px;
+ z-index: 2;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ margin: 0 0 50px;
+ z-index: 2;
+}
+.single-post-content .quate-speech-area .speecker-img {
+ position: absolute;
+ top: 0;
+ left: auto;
+ right: 0;
+ max-width: 100%;
+}
+@media only screen and (max-width: 575px) {
+ .single-post-content .quate-speech-area .speecker-img {
+ right: auto;
+ left: 50%;
+ -webkit-transform: translateX(-50%);
+ transform: translateX(-50%);
+ }
+}
+.single-post-content p.quate-speech {
+ padding: 40px 45px;
+ font-size: 24px;
+ line-height: 40px;
+ font-style: italic;
+ color: #fff;
+ background-color: #036eb8;
+ position: relative;
+ text-align: center;
+ margin: 40px 0;
+ font-weight: 300;
+ border-radius: 5px;
+ max-width: 585px;
+ overflow: hidden;
+ z-index: 1;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .single-post-content p.quate-speech {
+ font-size: 18px;
+ line-height: 32px;
+ padding: 35px 20px;
+ max-width: 370px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .single-post-content p.quate-speech {
+ font-size: 18px;
+ line-height: 32px;
+ padding: 30px 25px;
+ max-width: 300px;
+ }
+}
+@media only screen and (max-width: 575px) {
+ .single-post-content p.quate-speech {
+ padding: 30px 20px;
+ font-size: 18px;
+ line-height: 28px;
+ max-width: 100%;
+ }
+}
+.single-post-content p.quate-speech::after {
+ position: absolute;
+ top: auto;
+ left: auto;
+ right: -7px;
+ bottom: -7px;
+ content: '';
+ background-image: url(../images/blog-image/quate-icon.png);
+ background-repeat: no-repeat;
+ background-position: bottom right;
+ width: 72px;
+ height: 64px;
+ opacity: 0.1;
+}
+.single-post-content .title {
+ font-size: 30px;
+ color: #2d2d2d;
+ margin: 20px 0 30px;
+ display: block;
+ font-weight: 400;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .single-post-content .title {
+ font-size: 28px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .single-post-content .title {
+ font-size: 24px;
+ }
+}
+.single-post-content ul li + li {
+ margin-top: 20px;
+}
+.single-post-content ul li {
+ color: #525252;
+ font-weight: 500;
+ line-height: 30px;
+}
+.single-post-content P {
+ color: #525252;
+ line-height: 30px;
+ margin-bottom: 30px;
+}
+.single-post-content P + p {
+ margin-bottom: 40px;
+}
+.blog-sidebar .sidebar-widget {
+ background-color: #fff;
+ border-radius: 10px;
+ margin: 0 0 40px;
+ border: 1px solid #f3f3f3;
+}
+.blog-sidebar .sidebar-widget .sidebar-title {
+ font-size: 24px;
+ display: block;
+ text-transform: capitalize;
+ font-weight: 400;
+ color: #6c6c6c;
+ margin: 0 0 24px;
+ padding: 14px 0 15px 18px;
+ background: #f3f3f3;
+}
+.blog-sidebar .sidebar-widget + .sidebar-widget {
+ margin-top: 40px;
+}
+.blog-sidebar .search-widget {
+ padding-bottom: 23px;
+ padding-left: 20px;
+ padding-right: 30px;
+}
+.blog-sidebar form {
+ position: relative;
+}
+.blog-sidebar form input {
+ border: 1px solid #cfcfcf;
+ padding-right: 0;
+ font-size: 16px;
+ border-radius: 20px;
+ height: 45px;
+ padding-right: 55px;
+}
+.blog-sidebar form input:focus {
+ border-color: #036eb8;
+}
+.blog-sidebar form input::-webkit-input-placeholder {
+ color: #969696;
+}
+.blog-sidebar form input::-moz-placeholder {
+ color: #969696;
+}
+.blog-sidebar form input:-ms-input-placeholder {
+ color: #969696;
+}
+.blog-sidebar form input::-ms-input-placeholder {
+ color: #969696;
+}
+.blog-sidebar form input::placeholder {
+ color: #969696;
+}
+.blog-sidebar form button {
+ position: absolute;
+ width: 50px;
+ height: 45px;
+ left: auto;
+ right: 0;
+ font-size: 16px;
+ text-align: center;
+ background: 0;
+ color: #969696;
+ padding: 0;
+ border: 0;
+}
+.blog-sidebar form button:hover {
+ color: #036eb8;
+}
+.blog-sidebar .category-post {
+ padding-bottom: 23px;
+ padding-left: 20px;
+ padding-right: 30px;
+}
+.blog-sidebar .category-post li a {
+ color: #6a6a6a;
+ font-size: 16px;
+ display: inline-block;
+ margin-top: 18px;
+}
+.blog-sidebar .category-post li a:hover {
+ color: #036eb8;
+}
+.blog-sidebar .recent-post-widget {
+ padding-bottom: 23px;
+ padding-left: 20px;
+ padding-right: 30px;
+}
+.blog-sidebar .recent-post-widget .recent-single-post .thumb-side img {
+ width: 70px;
+ height: 70px;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+ border-radius: 10px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .blog-sidebar .recent-post-widget .recent-single-post .thumb-side img {
+ width: 70px;
+ }
+}
+.blog-sidebar .recent-post-widget .recent-single-post .media-side {
+ margin: 0 0 0 18px;
+ -ms-flex-item-align: center;
+ -ms-grid-row-align: center;
+ align-self: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ line-height: 1;
+}
+.blog-sidebar .recent-post-widget .recent-single-post .media-side a {
+ font-size: 17px;
+ font-weight: 400;
+ color: #424242;
+ line-height: 26px;
+}
+.blog-sidebar .recent-post-widget .recent-single-post .media-side a:hover {
+ color: #036eb8;
+}
+.blog-sidebar .recent-post-widget .recent-single-post .media-side span {
+ font-size: 16px;
+ color: #036eb8;
+ display: block;
+ margin: 0 0 10px;
+}
+.blog-sidebar .recent-post-widget .recent-single-post .media-side span i {
+ color: #036eb8;
+ margin-right: 5px;
+}
+.blog-sidebar .recent-post-widget .recent-single-post + .recent-single-post {
+ margin-top: 30px;
+}
+.blog-sidebar .sidebar-widget-tag {
+ padding-bottom: 23px;
+ padding-left: 20px;
+ padding-right: 30px;
+}
+.blog-sidebar .sidebar-widget-tag ul li {
+ line-height: 1;
+ display: inline-block;
+ margin: 8px 5px;
+}
+.blog-sidebar .sidebar-widget-tag ul li a {
+ display: block;
+ float: left;
+ padding: 8px 18px;
+ font-size: 16px;
+ color: #7e7e7e;
+ font-weight: 400;
+ border: 1px solid #f3f3f3;
+ border-radius: 5px;
+ background: 0;
+ text-transform: capitalize;
+}
+.blog-sidebar .sidebar-widget-tag ul li a:hover {
+ background-color: #036eb8;
+ color: #fff;
+ border-color: #036eb8;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .blog-sidebar .sidebar-widget-tag ul li a {
+ font-size: 14px;
+ }
+}
+.blog-post-audio {
+ line-height: 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .blog-post-audio.sidebar iframe {
+ height: 200px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .blog-post-audio.sidebar iframe {
+ height: 228px;
+ }
+}
+.blog-image img {
+ height: 100%;
+ width: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+}
+.blog-post-media {
+ overflow: hidden;
+}
+.blog-post-media .blog-image img {
+ height: 100%;
+ width: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+}
+.blog-post-media iframe {
+ border-radius: 20px;
+ height: 250px;
+ width: 100%;
+ position: relative;
+ border: 0;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .blog-post-media iframe {
+ height: 308px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .blog-post-media iframe {
+ height: 228px;
+ }
+}
+.blog-post-media .blog-post-video .thumb-image {
+ height: 100%;
+ width: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+}
+.blog-post-media .blog-post-video .icon {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ -webkit-transform: translate(-50%, -50%);
+ transform: translate(-50%, -50%);
+}
+.blog-post-media .blog-gallery .swiper-slide img {
+ width: 100%;
+ height: 100%;
+ -o-object-fit: cover;
+ object-fit: cover;
+ -o-object-position: center;
+ object-position: center;
+}
+.blog-single-tags-share {
+ padding-bottom: 60px;
+ line-height: 24px;
+ border-bottom: 2px solid #f3f3f3;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ padding-top: 20px;
+}
+@media only screen and (max-width: 575px) {
+ .blog-single-tags-share {
+ padding: 20px 20px;
+ }
+}
+.blog-single-tags-share .blog-single-tags {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+@media only screen and (max-width: 767px) {
+ .blog-single-tags-share .blog-single-tags {
+ margin-bottom: 30px;
+ }
+}
+.blog-single-tags-share span.title {
+ color: #2e2e2e;
+ font-size: 30px;
+}
+@media only screen and (max-width: 479px) {
+ .blog-single-tags-share span.title {
+ font-size: 20px;
+ }
+}
+.blog-single-tags-share span.title i {
+ margin-right: 30px;
+}
+@media only screen and (max-width: 479px) {
+ .blog-single-tags-share span.title i {
+ margin-right: 10px;
+ }
+}
+.blog-single-tags-share .tag-list {
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}
+.blog-single-tags-share .tag-list li {
+ display: inline-block;
+ margin-right: 20px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .blog-single-tags-share .tag-list li {
+ margin-right: 10px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .blog-single-tags-share .tag-list li {
+ margin-right: 10px;
+ }
+}
+.blog-single-tags-share .tag-list li a {
+ display: block;
+ float: left;
+ padding: 4px 18px;
+ font-size: 16px;
+ color: #7e7e7e;
+ font-weight: 400;
+ border: 1px solid #f3f3f3;
+ border-radius: 5px;
+ background: 0;
+ text-transform: capitalize;
+}
+@media only screen and (max-width: 479px) {
+ .blog-single-tags-share .tag-list li a {
+ padding: 4px 10px;
+ }
+}
+.blog-single-tags-share .tag-list li a:hover {
+ background-color: #036eb8;
+ color: #fff;
+ border-color: #036eb8;
+}
+.blog-single-tags-share .social li {
+ display: inline-block;
+ margin-left: 10px;
+}
+.blog-single-tags-share .social li a {
+ width: 36px;
+ height: 36px;
+ color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ font-size: 16px;
+ background-color: #000;
+ border-radius: 5px;
+}
+.blog-single-tags-share .social li a:hover {
+ background-color: #036eb8;
+}
+.comment-area {
+ line-height: 24px;
+ margin-top: 100px;
+ background-color: #fff;
+ border-radius: 10px;
+ border: 1px solid #f3f3f3;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area {
+ margin-top: 50px;
+ }
+}
+.comment-area .comment-heading {
+ font-size: 24px;
+ display: block;
+ text-transform: capitalize;
+ font-weight: 400;
+ color: #6c6c6c;
+ margin: 0 0 50px;
+ padding: 14px 0 15px 18px;
+ background: #f3f3f3;
+}
+@media only screen and (max-width: 575px) {
+ .comment-area .comment-heading {
+ font-size: 24px;
+ }
+}
+.comment-area .single-review {
+ padding-left: 30px;
+ padding-right: 30px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ margin: 0 0 60px;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area .single-review {
+ display: block;
+ }
+}
+.comment-area .single-review .review-img {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 90px;
+ flex: 0 0 90px;
+ margin: 0 15px 0 0;
+}
+.comment-area .single-review .review-img img {
+ border-radius: 10px;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area .single-review .review-img {
+ margin: 0 0 20px 0;
+ }
+}
+.comment-area .single-review .review-content {
+ padding-left: 15px;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area .single-review .review-content {
+ padding-left: 0;
+ }
+}
+.comment-area .single-review .review-content .review-top-wrap {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin: 0 0 20px;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.comment-area .single-review .review-content .review-top-wrap .review-left {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+}
+.comment-area .single-review .review-content .review-top-wrap .review-left .review-name .title {
+ font-size: 18px;
+ font-weight: 500;
+ color: #333;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area .single-review .review-content .review-top-wrap .review-left .review-name .title {
+ font-size: 20px;
+ }
+}
+.comment-area .single-review .review-content .review-top-wrap .review-left .review-name span {
+ font-weight: 400;
+ color: #666;
+}
+.comment-area .single-review .review-content .review-top-wrap .review-left a {
+ color: #474747;
+}
+.comment-area .single-review .review-content .review-top-wrap .review-left a:hover {
+ color: #036eb8;
+}
+.comment-area .single-review .review-content p {
+ margin: 0;
+ line-height: 30px;
+ color: #525252;
+}
+.comment-area .single-review .review-content .review-left a {
+ font-size: 16px;
+ color: #343434;
+ text-transform: uppercase;
+ font-weight: 400;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-pack: start;
+ -ms-flex-pack: start;
+ justify-content: flex-start;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ z-index: 1;
+ position: relative;
+ overflow: hidden;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ margin-top: 20px;
+}
+.comment-area .single-review .review-content .review-left a:hover {
+ color: #036eb8;
+}
+.comment-area .single-review .review-content .review-left a i {
+ font-size: 14px;
+ margin-right: 5px;
+}
+.comment-area .single-review.child-review {
+ margin-left: 70px;
+}
+@media only screen and (max-width: 767px) {
+ .comment-area .single-review.child-review {
+ margin-left: 0;
+ }
+}
+.blog-comment-form {
+ line-height: 24px;
+ margin-top: 100px;
+ background-color: #fff;
+ border-radius: 10px;
+ border: 1px solid #f3f3f3;
+}
+@media only screen and (max-width: 767px) {
+ .blog-comment-form {
+ margin-top: 50px;
+ }
+}
+.blog-comment-form .comment-heading {
+ font-size: 24px;
+ display: block;
+ text-transform: capitalize;
+ font-weight: 400;
+ color: #6c6c6c;
+ margin: 0 0 50px;
+ padding: 14px 0 15px 18px;
+ background: #f3f3f3;
+}
+@media only screen and (max-width: 575px) {
+ .blog-comment-form .comment-heading {
+ font-size: 24px;
+ }
+}
+.blog-comment-form .form-inner {
+ padding-left: 30px;
+ padding-right: 30px;
+ padding-bottom: 60px;
+}
+.blog-comment-form .single-form {
+ margin: 0 0 30px;
+}
+.blog-comment-form .single-form input {
+ border: 1px solid #d7d7d7;
+ font-size: 14px;
+ font-style: italic;
+}
+.blog-comment-form .single-form input::-webkit-input-placeholder {
+ color: #999;
+}
+.blog-comment-form .single-form input::-moz-placeholder {
+ color: #999;
+}
+.blog-comment-form .single-form input:-ms-input-placeholder {
+ color: #999;
+}
+.blog-comment-form .single-form input::-ms-input-placeholder {
+ color: #999;
+}
+.blog-comment-form .single-form input::placeholder {
+ color: #999;
+}
+.blog-comment-form .single-form input:focus {
+ border-color: #036eb8;
+}
+.blog-comment-form .single-form textarea {
+ height: 180px;
+ border: 1px solid #d7d7d7;
+}
+.blog-comment-form .single-form textarea:focus {
+ border-color: #036eb8;
+}
+.blog-comment-form .single-form button {
+ font-size: 14px;
+ letter-spacing: 2px;
+ line-height: 1;
+ font-weight: 400;
+ text-transform: uppercase;
+}
+.pro-pagination-style li {
+ display: inline-block;
+ height: 40px;
+ line-height: 40px;
+ background: #fff;
+ display: inline-block;
+ width: 40px;
+ border-radius: 5px;
+ text-align: center;
+ vertical-align: top;
+ font-size: 16px;
+}
+.pro-pagination-style li + li {
+ margin-left: 10px;
+}
+.pro-pagination-style a {
+ font-weight: 400;
+ color: #d5d5d5;
+ padding: 0;
+ height: 40px;
+ line-height: 40px;
+ background: #fff;
+ display: inline-block;
+ width: 40px;
+ border-radius: 5px;
+ text-align: center;
+ vertical-align: top;
+ font-size: 16px;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+ border-color: #d5d5d5;
+ font-weight: 500;
+}
+.pro-pagination-style a .fa {
+ font-size: 24px;
+}
+.pro-pagination-style li.active {
+ color: #fff;
+ background-color: #036eb8;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(234, 170, 133, 0.5);
+ box-shadow: 0 5px 15px 0 rgba(234, 170, 133, 0.5);
+ -webkit-transform: translateY(-1px);
+ transform: translateY(-1px);
+ border-color: #036eb8;
+}
+.pro-pagination-style li:hover {
+ color: #fff;
+ background-color: #036eb8;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(234, 170, 133, 0.5);
+ box-shadow: 0 5px 15px 0 rgba(234, 170, 133, 0.5);
+ -webkit-transform: translateY(-1px);
+ transform: translateY(-1px);
+ border-color: #036eb8;
+}
+.feature-area {
+ position: relative;
+ z-index: 1;
+ padding-bottom: 30px;
+}
+.feature-area.mt-n-65px {
+ margin-top: -65px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .feature-area.mt-n-65px {
+ margin-top: 65px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .feature-area.mt-n-65px {
+ margin-top: 65px;
+ }
+}
+.feature-wrapper {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -ms-flex-wrap: wrap;
+ flex-wrap: wrap;
+ position: relative;
+ -webkit-box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.08);
+ box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.08);
+ border-radius: 10px;
+ z-index: 1;
+}
+.feature-wrapper::after {
+ position: absolute;
+ top: 15px;
+ left: 0;
+ width: 95%;
+ height: 100%;
+ -webkit-box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.04);
+ box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.04);
+ content: '';
+ border-radius: 10px;
+ margin: auto;
+ right: 0;
+ z-index: -1;
+}
+.feature-wrapper::before {
+ position: absolute;
+ top: 30px;
+ left: 0;
+ width: 90%;
+ height: 100%;
+ -webkit-box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.02);
+ box-shadow: 0 24px 29px 0 rgba(0, 0, 0, 0.02);
+ content: '';
+ border-radius: 10px;
+ margin: auto;
+ right: 0;
+ z-index: -2;
+}
+.feature-wrapper .single-feture-col {
+ padding-right: 15px;
+ padding-left: 15px;
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+}
+@media only screen and (min-width: 1200px) and (max-width: 1599px), only screen and (min-width: 992px) and (max-width: 1199px) {
+ .feature-wrapper .single-feture-col {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .feature-wrapper .single-feture-col {
+ -webkit-box-flex: 0;
+ -ms-flex: 0 0 auto;
+ flex: 0 0 auto;
+ width: 50%;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .feature-wrapper .single-feture-col {
+ -ms-flex-negative: 0;
+ flex-shrink: 0;
+ width: 100%;
+ max-width: 100%;
+ }
+}
+.feature-wrapper .single-feture-col + .single-feture-col {
+ position: relative;
+}
+.feature-wrapper .single-feture-col + .single-feture-col::after {
+ position: absolute;
+ top: 50%;
+ left: -7.5px;
+ width: 2px;
+ height: 60px;
+ background-color: #e7e7e7;
+ content: '';
+ margin-top: -30px;
+}
+@media only screen and (max-width: 767px) {
+ .feature-wrapper .single-feture-col + .single-feture-col::after {
+ display: none;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .feature-wrapper .single-feture-col + .single-feture-col + .single-feture-col::after {
+ display: none;
+ }
+}
+.single-feature {
+ padding: 30px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ background-color: #fff;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .single-feature {
+ padding: 12px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .single-feature {
+ padding: 25px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .single-feature {
+ padding: 20px;
+ }
+}
+.single-feature .feature-icon {
+ width: 79px;
+ height: 70px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ border-radius: 50%;
+ margin-right: 20px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (max-width: 479px) {
+ .single-feature .feature-icon {
+ margin-right: 20px;
+ }
+}
+.single-feature .feature-content {
+ width: calc(100% - 99px);
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (max-width: 479px) {
+ .single-feature .feature-content {
+ width: calc(100% - 90px);
+ }
+}
+.single-feature .feature-content .title {
+ font-size: 24px;
+ color: #2e2e2e;
+ font-weight: 400;
+ margin: 0 0 3px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px),
+ only screen and (min-width: 768px) and (max-width: 991px),
+ only screen and (max-width: 479px) {
+ .single-feature .feature-content .title {
+ font-size: 20px;
+ }
+}
+.single-feature .feature-content .sub-title {
+ font-size: 16px;
+ color: #848484;
+ font-weight: 400;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px),
+ only screen and (min-width: 768px) and (max-width: 991px),
+ only screen and (max-width: 479px) {
+ .single-feature .feature-content .sub-title {
+ font-size: 14px;
+ }
+}
+.single-feature img {
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.single-feature:hover img {
+ -webkit-transform: scale(0.9) rotate(3deg);
+ transform: scale(0.9) rotate(3deg);
+}
+.slider-nav-style-1 {
+ position: relative;
+}
+.slider-nav-style-1 .swiper-button-next:after {
+ content: '';
+}
+.slider-nav-style-1 .swiper-button-prev:after {
+ content: '';
+}
+.slider-nav-style-1 .swiper-button-next:after,
+.slider-nav-style-1 .swiper-button-prev:after {
+ font-family: Pe-icon-7-stroke;
+ font-size: 40px;
+ text-transform: none !important;
+ letter-spacing: 0;
+ text-transform: none;
+ font-variant: initial;
+ line-height: 1;
+ outline: 0;
+}
+@media only screen and (max-width: 575px) {
+ .slider-nav-style-1 .swiper-button-next:after,
+ .slider-nav-style-1 .swiper-button-prev:after {
+ font-size: 24px;
+ }
+}
+.slider-nav-style-1.small-nav .swiper-button-next:after,
+.slider-nav-style-1.small-nav .swiper-button-prev:after {
+ font-size: 30px;
+}
+.small-nav.slider-nav-style-1.small-nav .swiper-button-next:after,
+.small-nav.slider-nav-style-1.small-nav .swiper-button-prev:after {
+ font-size: 24px;
+}
+.slider-nav-style-1 .swiper-buttons .swiper-button-next,
+.slider-nav-style-1 .swiper-buttons .swiper-button-prev {
+ position: absolute;
+ top: 50%;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ z-index: 9;
+ width: 50px;
+ height: 50px;
+ line-height: 50px;
+ opacity: 0;
+ visibility: hidden;
+ -webkit-transition: all 0.3s;
+ transition: all 0.3s;
+ margin: auto;
+ border-radius: 50%;
+ text-align: center;
+ -webkit-box-shadow: 0 3px 25.5px 4.5px rgba(0, 0, 0, 0.06);
+ box-shadow: 0 3px 25.5px 4.5px rgba(0, 0, 0, 0.06);
+ color: #000;
+ background-color: #fff;
+}
+@media only screen and (max-width: 575px) {
+ .slider-nav-style-1 .swiper-buttons .swiper-button-next,
+ .slider-nav-style-1 .swiper-buttons .swiper-button-prev {
+ width: 35px;
+ height: 35px;
+ line-height: 35px;
+ }
+}
+.slider-nav-style-1 .swiper-buttons .swiper-button-next:hover,
+.slider-nav-style-1 .swiper-buttons .swiper-button-prev:hover {
+ background-color: #036eb8;
+ color: #fff;
+ -webkit-box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.3);
+ box-shadow: 0 5px 15px 0 rgba(0, 0, 0, 0.3);
+}
+.slider-nav-style-1.small-nav .swiper-buttons .swiper-button-next,
+.slider-nav-style-1.small-nav .swiper-buttons .swiper-button-prev {
+ width: 40px;
+ height: 40px;
+ line-height: 40px;
+}
+.slider-nav-style-1.small-nav .swiper-buttons .swiper-button-next:hover,
+.slider-nav-style-1.small-nav .swiper-buttons .swiper-button-prev:hover {
+ background-color: #036eb8;
+ color: #fff;
+}
+.slider-nav-style-1 .swiper-button-prev {
+ outline: 0;
+ right: auto;
+ left: 30px;
+}
+@media only screen and (max-width: 767px) {
+ .slider-nav-style-1 .swiper-button-prev {
+ left: 15px;
+ }
+}
+.slider-nav-style-1.small-nav .swiper-button-prev {
+ outline: 0;
+ right: auto;
+ left: 10px;
+}
+@media only screen and (max-width: 767px) {
+ .slider-nav-style-1.small-nav .swiper-button-prev {
+ left: 5px;
+ }
+}
+.slider-nav-style-1 .swiper-button-next {
+ outline: 0;
+ left: auto;
+ right: 30px;
+}
+@media only screen and (max-width: 767px) {
+ .slider-nav-style-1 .swiper-button-next {
+ right: 15px;
+ }
+}
+.slider-nav-style-1.small-nav .swiper-button-next {
+ outline: 0;
+ left: auto;
+ right: 10px;
+}
+@media only screen and (max-width: 767px) {
+ .slider-nav-style-1.small-nav .swiper-button-next {
+ right: 5px;
+ }
+}
+.slider-nav-style-1:hover .swiper-button-next,
+.slider-nav-style-1:hover .swiper-button-prev {
+ opacity: 1;
+ visibility: visible;
+}
+.slider-nav-style-1:hover .swiper-button-next {
+ right: 50px;
+}
+@media only screen and (max-width: 575px) {
+ .slider-nav-style-1:hover .swiper-button-next {
+ right: 20px;
+ }
+}
+.slider-nav-style-1:hover .swiper-button-prev {
+ left: 50px;
+}
+@media only screen and (max-width: 575px) {
+ .slider-nav-style-1:hover .swiper-button-prev {
+ left: 20px;
+ }
+}
+.slider-nav-style-1.small-nav:hover .swiper-button-next {
+ right: 20px;
+}
+.slider-nav-style-1.small-nav:hover .swiper-button-prev {
+ left: 20px;
+}
+
+.breadcrumb-area {
+ position: relative;
+}
+.breadcrumb-area img {
+ max-width: 100%;
+}
+.breadcrumb-title {
+ position: absolute;
+ left: 12.5%;
+ top: 25%;
+ font-weight: 700;
+ font-size: 64px;
+ color: #fff;
+ margin: 0;
+}
+@media only screen and (max-width: 1366px) {
+ .breadcrumb-title {
+ left: 12.5%;
+ top: 25%;
+ font-size: 48px;
+ }
+}
+@media only screen and (max-width: 750px) {
+ .breadcrumb-title {
+ left: 2.5%;
+ top: 10%;
+ font-size: 32px;
+ }
+ .md-blank {
+ display: none;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .breadcrumb-area .breadcrumb-title {
+ font-size: 24px;
+ }
+}
+.breadcrumb-list li {
+ display: inline-block;
+ font-size: 14px;
+ font-weight: 500;
+ text-transform: capitalize;
+ margin: 24px 0 20px;
+}
+.breadcrumb-list span {
+ color: #b2b2b2;
+ padding: 0 8px;
+}
+.breadcrumb-list li a {
+ color: #4a4a4a;
+}
+.breadcrumb-list li a:hover {
+ color: #b2b2b2;
+}
+.breadcrumb-list li.active {
+ color: #b2b2b2;
+}
+.breadcrumb-item + .breadcrumb-item {
+ padding-left: 5px;
+}
+
+.page-pagination li {
+ display: inline-block;
+}
+.page-pagination li a {
+ font-weight: 500;
+ padding: 0 10px;
+ display: block;
+ text-align: center;
+ line-height: 41px;
+ min-width: 41px;
+ height: 41px;
+ text-transform: uppercase;
+ color: #ababab;
+ letter-spacing: 2px;
+ border-radius: 5px;
+}
+.page-pagination li a.current {
+ background: #f6f5f9;
+ color: #036eb8;
+}
+.page-pagination li a:hover {
+ color: #036eb8;
+}
+.deal-bg {
+ position: relative;
+ background-color: #e7e7e7;
+ background-position: center;
+ background-size: cover;
+ background-repeat: no-repeat;
+}
+.deal-bg.ptb-80px {
+ padding: 66px 0 80px;
+}
+.deal-bg-2 {
+ border-radius: 10px;
+ margin: 0 30px;
+}
+@media only screen and (max-width: 479px) {
+ .deal-bg-2 {
+ margin: 0;
+ }
+}
+.deal-image {
+ position: absolute;
+ left: auto;
+ right: 168px;
+ bottom: 28px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .deal-image {
+ right: 100px;
+ bottom: 0;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .deal-image {
+ right: 0;
+ width: 50%;
+ bottom: 0;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .deal-image {
+ margin: auto;
+ position: initial;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ }
+}
+.deal-image .discount {
+ width: 103px;
+ height: 103px;
+ color: #fff;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ background: #036eb8;
+ border-radius: 50%;
+ position: absolute;
+ bottom: 60px;
+ right: -30px;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .deal-image .discount {
+ right: 30px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .deal-image .discount {
+ bottom: 145px;
+ right: auto;
+ left: 68%;
+ }
+}
+.deal-image .discount h3 {
+ color: #fff;
+ font-weight: 500;
+}
+.deal-wrapper {
+ width: 1440px;
+ margin: auto;
+ line-height: 1;
+ position: absolute;
+ left: 12.5%;
+ color: #fff;
+ top: 15%;
+}
+.deal-inner img {
+ max-width: 100%;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .deal-wrapper {
+ width: 40%;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .deal-wrapper {
+ width: 50%;
+ padding-left: 40px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .deal-wrapper {
+ margin: auto;
+ width: 100%;
+ margin: 0 0 50px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .deal-wrapper {
+ padding-left: 30px;
+ }
+}
+.deal-wrapper p {
+ font-size: 32px;
+ color: #fff;
+}
+.deal-wrapper .title {
+ font-size: 64px;
+ color: #fff;
+ font-weight: 600;
+ margin: 0;
+ line-height: 82px;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px), only screen and (min-width: 768px) and (max-width: 991px) {
+ .deal-wrapper .title {
+ font-size: 48px;
+ line-height: 60px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .deal-wrapper .title {
+ font-size: 30px;
+ line-height: 40px;
+ }
+ .deal-wrapper p {
+ font-size: 20px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .deal-wrapper {
+ left: 3%;
+ }
+ .deal-wrapper .title {
+ font-size: 20px;
+ line-height: 30px;
+ }
+ .deal-wrapper p {
+ font-size: 16px;
+ }
+}
+.deal-wrapper .price {
+ font-size: 30px;
+ font-weight: 500;
+ margin-bottom: 55px;
+ margin-top: 22px;
+ color: #4a4a4a;
+ display: block;
+}
+@media only screen and (max-width: 575px) {
+ .deal-wrapper .price {
+ font-size: 24px;
+ margin-top: 15px;
+ margin-bottom: 40px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .deal-wrapper .price {
+ font-size: 20px;
+ margin-top: 10px;
+ margin-bottom: 30px;
+ }
+}
+.deal-wrapper .price .new {
+ color: #036eb8;
+}
+@media only screen and (min-width: 992px) and (max-width: 1199px) {
+ .deal-wrapper .price {
+ font-size: 24px;
+ margin-bottom: 40px;
+ margin-top: 15px;
+ }
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .deal-wrapper .price {
+ font-size: 20px;
+ margin-bottom: 40px;
+ margin-top: 20px;
+ }
+}
+.deal-wrapper a.btn-primary {
+ width: 140px;
+ height: 40px;
+ font-size: 14px;
+ text-transform: uppercase;
+ font-weight: 400;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px), only screen and (max-width: 767px) {
+ .testimonial-area.pb-40px {
+ padding-bottom: 0;
+ }
+}
+.testimonial-wrapper {
+ max-width: 570px;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin: auto;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-content {
+ text-align: center;
+ margin-top: 45px;
+ position: relative;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-content::after {
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ content: '';
+ background-image: url(../images/testimonial-image/quate-1.png);
+ background-repeat: no-repeat;
+ background-position: center;
+ width: 136px;
+ height: 117px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ margin-top: -58.5px;
+ margin-left: -68px;
+ z-index: -1;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-content p {
+ font-size: 30px;
+ line-height: 48px;
+ color: #565656;
+ font-style: italic;
+}
+@media only screen and (min-width: 768px) and (max-width: 991px) {
+ .testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-content p {
+ font-size: 24px;
+ line-height: 38px;
+ }
+}
+@media only screen and (max-width: 767px) {
+ .testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-content p {
+ font-size: 24px;
+ line-height: 38px;
+ }
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-author {
+ line-height: 1;
+ margin: 45px 0 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: horizontal;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: row;
+ flex-direction: row;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-author .author-img {
+ position: relative;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-author .author-name .name {
+ color: #393939;
+ font-size: 18px;
+ margin: 0 0 10px;
+ font-weight: 500;
+ text-transform: uppercase;
+}
+.testimonial-wrapper .swiper-wrapper .swiper-slide .testi-inner .testi-author .author-name .title {
+ color: grey;
+ font-size: 18px;
+ font-weight: 300;
+ text-transform: uppercase;
+}
+.testimonial-wrapper .swiper-button-next:after,
+.testimonial-wrapper .swiper-button-prev:after {
+ font-family: FontAwesome;
+ font-size: 24px;
+ color: #424242;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.testimonial-wrapper .swiper-button-prev:after {
+ content: '';
+}
+.testimonial-wrapper .swiper-button-next:after {
+ content: '';
+}
+.testimonial-wrapper .swiper-button-prev {
+ left: 25%;
+}
+@media only screen and (max-width: 575px) {
+ .testimonial-wrapper .swiper-button-prev {
+ left: 15%;
+ }
+}
+.testimonial-wrapper .swiper-button-next {
+ right: 25%;
+}
+@media only screen and (max-width: 575px) {
+ .testimonial-wrapper .swiper-button-next {
+ right: 15%;
+ }
+}
+.testimonial-wrapper .swiper-button-next,
+.testimonial-wrapper .swiper-button-prev {
+ top: 60px;
+}
+.testimonial-wrapper .swiper-button-next:hover:after,
+.testimonial-wrapper .swiper-button-prev:hover:after {
+ color: #036eb8;
+}
+.brand-slider {
+ border: 1px solid #e1e1e1;
+}
+.brand-slider .brand-slider-item {
+ position: relative;
+}
+.brand-slider .brand-slider-item::after {
+ position: absolute;
+ top: -20px;
+ left: 0;
+ width: 1px;
+ height: 250px;
+ content: '';
+ background-color: #e1e1e1;
+}
+.brand-slider .brand-slider-item a {
+ padding: 48px 0;
+ display: inline-block;
+}
+.brand-slider .brand-slider-item img {
+ filter: gray;
+ -webkit-filter: grayscale(1);
+ -webkit-transition: all 0.3s linear;
+ transition: all 0.3s linear;
+ margin: auto;
+ opacity: 0.5;
+}
+.brand-slider .brand-slider-item:hover img {
+ filter: none;
+ -webkit-filter: grayscale(0);
+ opacity: 1;
+}
+.brand-slider .brand-slider-item.swiper-slide-active::after {
+ display: none;
+}
+.modal-backdrop {
+ background-color: transparent;
+}
+.modal {
+ overflow: hidden !important;
+ padding-right: 0 !important;
+}
+.modal::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ margin: auto;
+ background-color: rgba(28, 28, 28, 0.5);
+ width: 100%;
+ height: 0;
+ padding-bottom: 100%;
+ border-radius: 100%;
+ -webkit-transform: scale(0.04) translateY(9999px);
+ transform: scale(0.04) translateY(9999px);
+ overflow: hidden;
+ z-index: 9;
+}
+.modal .modal-overlay {
+ overflow: auto;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: start;
+ -ms-flex-align: start;
+ align-items: flex-start;
+ width: 100%;
+ height: 100%;
+ position: relative;
+}
+.modal .modal-dialog {
+ top: 0 !important;
+ -webkit-transform: translateY(-50%);
+ transform: translateY(-50%);
+ -webkit-transition: all 0.55s ease, opacity 0.35s ease-in;
+ transition: all 0.55s ease, opacity 0.35s ease-in;
+ background-color: transparent;
+ width: 100%;
+ opacity: 0;
+ margin: auto;
+ z-index: 9999;
+}
+.modal.show::before {
+ -webkit-animation: menu-animation 0.8s ease-out forwards;
+ animation: menu-animation 0.8s ease-out forwards;
+ -webkit-transform: scale(2) translateY(0);
+ transform: scale(2) translateY(0);
+}
+.modal.show .modal-dialog {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ -webkit-transition-delay: 0.7s;
+ transition-delay: 0.7s;
+ opacity: 1;
+ top: 50%;
+}
+.modal.show .close-btn {
+ -webkit-transition-delay: 0.7s;
+ transition-delay: 0.7s;
+ opacity: 1;
+ top: 50px;
+}
+.modal.popup-login-style .modal-dialog,
+.modal.popup-search-style .modal-dialog {
+ max-width: 400px;
+ border-radius: 10px;
+ -webkit-box-shadow: 0 0 41px 1px rgba(0, 0, 0, 0.46);
+ box-shadow: 0 0 41px 1px rgba(0, 0, 0, 0.46);
+}
+@media only screen and (max-width: 575px) {
+ .modal.popup-login-style .modal-dialog,
+ .modal.popup-search-style .modal-dialog {
+ max-width: 380px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .modal.popup-login-style .modal-dialog,
+ .modal.popup-search-style .modal-dialog {
+ max-width: 330px;
+ }
+}
+.modal.popup-login-style .modal-dialog .modal-content,
+.modal.popup-search-style .modal-dialog .modal-content {
+ background: #fff;
+}
+.modal.popup-login-style .modal-dialog .modal-content .modal-body,
+.modal.popup-search-style .modal-dialog .modal-content .modal-body {
+ padding: 40px 20px 45px;
+}
+.close-btn {
+ position: absolute;
+ top: 0;
+ right: 50px;
+ color: #fff;
+ z-index: 9;
+ width: 40px;
+ height: 40px;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ font-size: 30px;
+ background: 0;
+ border: 1px solid #fff;
+ opacity: 0;
+ -webkit-transition: 0.5s;
+ transition: 0.5s;
+ padding: 0;
+}
+.login-content h2 {
+ font-weight: 700;
+ color: #fff;
+ font-size: 30px;
+ text-align: center;
+ margin: 0 0 48px;
+}
+.login-content h3 {
+ font-weight: 600;
+ color: #fff;
+ font-size: 14px;
+ text-transform: uppercase;
+ margin: 0 0 29px;
+}
+.login-content form > input {
+ width: 100%;
+ background-color: #fff;
+ padding: 1px 20px;
+ color: #000;
+ line-height: 47px;
+ border: 0;
+ border-radius: 5px;
+ margin-bottom: 25px;
+}
+.login-content form > input::-webkit-input-placeholder {
+ color: #000;
+ opacity: 1;
+}
+.login-content form > input::-moz-input-placeholder {
+ color: #000;
+ opacity: 1;
+}
+.login-content form .remember-forget-wrap {
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-pack: justify;
+ -ms-flex-pack: justify;
+ justify-content: space-between;
+ margin: 0 0 32px;
+}
+.login-content form .remember-forget-wrap .remember-wrap {
+ position: relative;
+}
+.login-content form .remember-forget-wrap .remember-wrap input {
+ position: absolute;
+ cursor: pointer;
+ z-index: 999;
+ width: 20px;
+ height: 20px;
+}
+.login-content form .remember-forget-wrap .remember-wrap p {
+ margin: 0 0 0 30px;
+ color: #fff;
+ font-size: 14px;
+}
+.login-content form .remember-forget-wrap .remember-wrap p a {
+ color: #036eb8;
+}
+.login-content form .remember-forget-wrap .forget-wrap a {
+ font-size: 14px;
+ color: #036eb8;
+}
+.login-content form button {
+ color: #fff;
+ font-weight: 600;
+ -webkit-transition: all 0.5s;
+ transition: all 0.5s;
+ background-color: #036eb8;
+ border-radius: 5px;
+ padding: 16px 20px;
+ border: 0;
+ text-transform: uppercase;
+ line-height: 1;
+}
+.login-content form button:hover {
+ background-color: #000;
+}
+.login-content form .member-register {
+ margin: 27px 0 0;
+}
+.login-content form .member-register p {
+ color: #999;
+ text-transform: uppercase;
+ font-weight: 600;
+ margin: 0;
+ font-size: 14px;
+}
+.login-content form .member-register p a {
+ color: #fff;
+ display: inline-block;
+ margin-left: 5px;
+ line-height: 1;
+ padding: 0 0 1px;
+ border-bottom: 1px solid #fff;
+}
+.modal .submit-btn {
+ position: absolute;
+ top: 0;
+ right: 0;
+ display: -webkit-box;
+ display: -ms-flexbox;
+ display: flex;
+ width: 60px;
+ height: 50px;
+ background: #036eb8;
+ color: #fff;
+ -webkit-box-pack: center;
+ -ms-flex-pack: center;
+ justify-content: center;
+ -webkit-box-align: center;
+ -ms-flex-align: center;
+ align-items: center;
+ -webkit-box-orient: vertical;
+ -webkit-box-direction: normal;
+ -ms-flex-direction: column;
+ flex-direction: column;
+ border: 0;
+ outline: 0;
+ font-size: 20px;
+ border-radius: 0 5px 5px 0;
+ -webkit-transition: all 0.3s ease 0s;
+ transition: all 0.3s ease 0s;
+}
+.modal .submit-btn:hover {
+ background-color: #000;
+}
+.modal h2 {
+ font-size: 24px;
+ font-weight: 700;
+ color: #333;
+ margin: 0 0 30px;
+}
+.modal.fade .modal-dialog {
+ -webkit-transition-delay: 0.7s;
+ transition-delay: 0.7s;
+}
+.modal-2.fade .modal-dialog {
+ -webkit-transition-delay: 0.7s;
+ transition-delay: 0.7s;
+ -webkit-transition: opacity 0.7s;
+ transition: opacity 0.7s;
+}
+.modal-2.fade.show::before {
+ -webkit-animation: menu-animation 0.8s ease-out forwards;
+ animation: menu-animation 0.8s ease-out forwards;
+ -webkit-transform: scale(2) translateY(0);
+ transform: scale(2) translateY(0);
+}
+.modal-2.fade.show .modal-dialog {
+ -webkit-transform: translateY(0);
+ transform: translateY(0);
+ -webkit-transition-delay: 0.7s;
+ transition-delay: 0.7s;
+ opacity: 1;
+ top: 50%;
+}
+.modal-2 h2 {
+ color: #747474;
+ font-size: 30px;
+ text-transform: capitalize;
+ line-height: 1;
+ font-weight: 500;
+ margin: 0 0 18px 0;
+}
+@media only screen and (max-width: 479px) {
+ .modal-2 h2 {
+ font-size: 24px;
+ }
+}
+@media only screen and (max-width: 479px) {
+ .modal-2 .product-details-content .pro-details-quality .pro-details-cart .add-cart {
+ font-size: 12px;
+ }
+}
+.modal-open .modal-2 {
+ overflow-x: hidden !important;
+ overflow-y: auto !important;
+}
+@-webkit-keyframes menu-animation {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.04) translateY(300%);
+ transform: scale(0.04) translateY(300%);
+ }
+ 40% {
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ -webkit-transition: ease-out;
+ transition: ease-out;
+ }
+ 40% {
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale(0.02) translateY(0);
+ transform: scale(0.02) translateY(0);
+ }
+ 61% {
+ opacity: 1;
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ }
+ 99.9% {
+ opacity: 1;
+ height: 0;
+ padding-bottom: 100%;
+ border-radius: 100%;
+ }
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale(2) translateY(0);
+ transform: scale(2) translateY(0);
+ height: 100%;
+ padding-bottom: 0;
+ border-radius: 0;
+ }
+}
+@keyframes menu-animation {
+ 0% {
+ opacity: 0;
+ -webkit-transform: scale(0.04) translateY(300%);
+ transform: scale(0.04) translateY(300%);
+ }
+ 40% {
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ -webkit-transition: ease-out;
+ transition: ease-out;
+ }
+ 40% {
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ }
+ 60% {
+ opacity: 1;
+ -webkit-transform: scale(0.02) translateY(0);
+ transform: scale(0.02) translateY(0);
+ }
+ 61% {
+ opacity: 1;
+ -webkit-transform: scale(0.04) translateY(0);
+ transform: scale(0.04) translateY(0);
+ }
+ 99.9% {
+ opacity: 1;
+ height: 0;
+ padding-bottom: 100%;
+ border-radius: 100%;
+ }
+ 100% {
+ opacity: 1;
+ -webkit-transform: scale(2) translateY(0);
+ transform: scale(2) translateY(0);
+ height: 100%;
+ padding-bottom: 0;
+ border-radius: 0;
+ }
+}
+/*list列表*/
+/* 必要布局样式css */
+.cation-bg {
+ background: #f5f5f5;
+}
+.cation-content {
+ margin: 0 auto;
+ padding: 32px 0 24px;
+}
+@media only screen and (max-width: 750px) {
+ .cation-bg {
+ display: none;
+ }
+}
+
+.cation-middle {
+ line-height: 48px;
+ background: #fff;
+ padding: 10px 20px 10px 30px;
+ font-size: 14px;
+ border: 1px solid #eee;
+}
+
+.cation-list {
+ overflow: hidden;
+}
+
+.cation-list dt {
+ float: left;
+ width: 64px;
+ font-weight: 100;
+ line-height: 48px;
+ position: relative;
+ color: #999;
+ text-align: center;
+}
+
+.cation-list dd {
+ border-bottom: 1px dotted #e0e0e0;
+ margin-left: 64px;
+ overflow: hidden;
+}
+
+.cation-list dd a {
+ color: #333;
+ font-size: 14px;
+ line-height: 14px;
+ height: 14px;
+ float: left;
+ border-right: 1px solid #e0e0e0;
+ padding: 0 18px;
+ margin: 17px 0;
+}
+.cation-all dd a.on,
+.cation-list dd a.on,
+.cation-list a:hover,
+.cation-all a:hover {
+ color: #036eb8;
+}
+
+.cation-list dd a:last-child {
+ border-right: 0 none;
+}
+
+.cation-list:last-of-type dd {
+ border-bottom: 0 none;
+}
+
+.cation-all {
+ overflow: hidden;
+ background: #fff;
+ border-bottom: 1px solid #eee;
+}
+
+.cation-all dt {
+ float: left;
+ width: 64px;
+ font-weight: 100;
+ line-height: 48px;
+ position: relative;
+ color: #999;
+ text-align: center;
+ border-bottom: 1px dotted #e0e0e0;
+}
+
+.cation-all dd {
+ overflow: hidden;
+}
+
+.cation-all dd a {
+ color: #333;
+ font-size: 14px;
+ line-height: 14px;
+ height: 14px;
+ float: left;
+ border-right: 1px solid #e0e0e0;
+ padding: 0 18px;
+ margin: 17px 0;
+}
+.list-bg-non {
+ background: #fff;
+}
+.list-non {
+ padding: 100px 0;
+ font-size: 20px;
+ text-align: center;
+}
+/*07/27修改*/
+@media only screen and (max-width: 767px) {
+ .header-logo img {
+ width: 80%;
+ }
+}
+/*07/29修改*/
+@media only screen and (max-width: 575px) {
+ .img-none {
+ display: none;
+ }
+ .row {
+ --bs-gutter-x: 0;
+ }
+}
diff --git a/public/assets/css/vendor/vendor.min.css b/public/assets/css/vendor/vendor.min.css
new file mode 100644
index 0000000..9b56973
--- /dev/null
+++ b/public/assets/css/vendor/vendor.min.css
@@ -0,0 +1,12348 @@
+@charset "UTF-8"; /*!
+ * Bootstrap v5.0.0-beta3 (https://getbootstrap.com/)
+ * Copyright 2011-2021 The Bootstrap Authors
+ * Copyright 2011-2021 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
+ */
+:root {
+ --bs-blue: #0d6efd;
+ --bs-indigo: #6610f2;
+ --bs-purple: #6f42c1;
+ --bs-pink: #d63384;
+ --bs-red: #dc3545;
+ --bs-orange: #fd7e14;
+ --bs-yellow: #ffc107;
+ --bs-green: #198754;
+ --bs-teal: #20c997;
+ --bs-cyan: #0dcaf0;
+ --bs-white: #fff;
+ --bs-gray: #6c757d;
+ --bs-gray-dark: #343a40;
+ --bs-primary: #0d6efd;
+ --bs-secondary: #6c757d;
+ --bs-success: #198754;
+ --bs-info: #0dcaf0;
+ --bs-warning: #ffc107;
+ --bs-danger: #dc3545;
+ --bs-light: #f8f9fa;
+ --bs-dark: #212529;
+ --bs-font-sans-serif: system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, 'Noto Sans', 'Liberation Sans', sans-serif,
+ 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+ --bs-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
+ --bs-gradient: linear-gradient(180deg, rgba(255, 255, 255, 0.15), rgba(255, 255, 255, 0));
+}
+*,
+::after,
+::before {
+ box-sizing: border-box;
+}
+@media (prefers-reduced-motion: no-preference) {
+ :root {
+ scroll-behavior: none;
+ }
+}
+body {
+ margin: 0;
+ font-family: var(--bs-font-sans-serif);
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ background-color: #fff;
+ -webkit-text-size-adjust: 100%;
+ -webkit-tap-highlight-color: transparent;
+}
+hr {
+ margin: 1rem 0;
+ color: inherit;
+ background-color: currentColor;
+ border: 0;
+ opacity: 0.25;
+}
+hr:not([size]) {
+ height: 1px;
+}
+.h1,
+.h2,
+.h3,
+.h4,
+.h5,
+.h6,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ font-weight: 500;
+ line-height: 1.2;
+}
+.h1,
+h1 {
+ font-size: calc(1.375rem+1.5vw);
+}
+@media (min-width: 1200px) {
+ .h1,
+ h1 {
+ font-size: 2.5rem;
+ }
+}
+.h2,
+h2 {
+ font-size: calc(1.325rem+0.9vw);
+}
+@media (min-width: 1200px) {
+ .h2,
+ h2 {
+ font-size: 2rem;
+ }
+}
+.h3,
+h3 {
+ font-size: calc(1.3rem+0.6vw);
+}
+@media (min-width: 1200px) {
+ .h3,
+ h3 {
+ font-size: 1.75rem;
+ }
+}
+.h4,
+h4 {
+ font-size: calc(1.275rem+0.3vw);
+}
+@media (min-width: 1200px) {
+ .h4,
+ h4 {
+ font-size: 1.5rem;
+ }
+}
+.h5,
+h5 {
+ font-size: 1.25rem;
+}
+.h6,
+h6 {
+ font-size: 1rem;
+}
+p {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+abbr[data-bs-original-title],
+abbr[title] {
+ -webkit-text-decoration: underline dotted;
+ text-decoration: underline dotted;
+ cursor: help;
+ -webkit-text-decoration-skip-ink: none;
+ text-decoration-skip-ink: none;
+}
+address {
+ margin-bottom: 1rem;
+ font-style: normal;
+ line-height: inherit;
+}
+ol,
+ul {
+ padding-left: 2rem;
+}
+dl,
+ol,
+ul {
+ margin-top: 0;
+ margin-bottom: 1rem;
+}
+ol ol,
+ol ul,
+ul ol,
+ul ul {
+ margin-bottom: 0;
+}
+b,
+strong {
+ font-weight: bolder;
+}
+.small,
+small {
+ font-size: 0.875em;
+}
+.mark,
+mark {
+ padding: 0.2em;
+ background-color: #fcf8e3;
+}
+sub,
+sup {
+ position: relative;
+ font-size: 0.75em;
+ line-height: 0;
+ vertical-align: baseline;
+}
+sub {
+ bottom: -0.25em;
+}
+sup {
+ top: -0.5em;
+}
+a {
+ color: #0d6efd;
+ text-decoration: underline;
+}
+a:hover {
+ color: #0a58ca;
+}
+a:not([href]):not([class]),
+a:not([href]):not([class]):hover {
+ color: inherit;
+ text-decoration: none;
+}
+code,
+kbd,
+pre,
+samp {
+ font-family: var(--bs-font-monospace);
+ font-size: 1em;
+ direction: ltr;
+ unicode-bidi: bidi-override;
+}
+pre {
+ display: block;
+ margin-top: 0;
+ margin-bottom: 1rem;
+ overflow: auto;
+ font-size: 0.875em;
+}
+pre code {
+ font-size: inherit;
+ color: inherit;
+ word-break: normal;
+}
+code {
+ font-size: 0.875em;
+ color: #d63384;
+ word-wrap: break-word;
+}
+a > code {
+ color: inherit;
+}
+kbd {
+ padding: 0.2rem 0.4rem;
+ font-size: 0.875em;
+ color: #fff;
+ background-color: #212529;
+ border-radius: 0.2rem;
+}
+kbd kbd {
+ padding: 0;
+ font-size: 1em;
+ font-weight: 700;
+}
+figure {
+ margin: 0 0 1rem;
+}
+img,
+svg {
+ vertical-align: middle;
+}
+table {
+ caption-side: bottom;
+ border-collapse: collapse;
+}
+caption {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ color: #6c757d;
+ text-align: left;
+}
+th {
+ text-align: inherit;
+ text-align: -webkit-match-parent;
+}
+tbody,
+td,
+tfoot,
+th,
+thead,
+tr {
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+}
+label {
+ display: inline-block;
+}
+button {
+ border-radius: 0;
+}
+button:focus:not(:focus-visible) {
+ outline: 0;
+}
+button,
+input,
+optgroup,
+select,
+textarea {
+ margin: 0;
+ font-family: inherit;
+ font-size: inherit;
+ line-height: inherit;
+}
+button,
+select {
+ text-transform: none;
+}
+[role='button'] {
+ cursor: pointer;
+}
+select {
+ word-wrap: normal;
+}
+select:disabled {
+ opacity: 1;
+}
+[list]::-webkit-calendar-picker-indicator {
+ display: none;
+}
+[type='button'],
+[type='reset'],
+[type='submit'],
+button {
+ -webkit-appearance: button;
+}
+[type='button']:not(:disabled),
+[type='reset']:not(:disabled),
+[type='submit']:not(:disabled),
+button:not(:disabled) {
+ cursor: pointer;
+}
+::-moz-focus-inner {
+ padding: 0;
+ border-style: none;
+}
+textarea {
+ resize: vertical;
+}
+fieldset {
+ min-width: 0;
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+legend {
+ float: left;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 0.5rem;
+ font-size: calc(1.275rem+0.3vw);
+ line-height: inherit;
+}
+@media (min-width: 1200px) {
+ legend {
+ font-size: 1.5rem;
+ }
+}
+legend + * {
+ clear: left;
+}
+::-webkit-datetime-edit-day-field,
+::-webkit-datetime-edit-fields-wrapper,
+::-webkit-datetime-edit-hour-field,
+::-webkit-datetime-edit-minute,
+::-webkit-datetime-edit-month-field,
+::-webkit-datetime-edit-text,
+::-webkit-datetime-edit-year-field {
+ padding: 0;
+}
+::-webkit-inner-spin-button {
+ height: auto;
+}
+[type='search'] {
+ outline-offset: -2px;
+ -webkit-appearance: textfield;
+}
+::-webkit-search-decoration {
+ -webkit-appearance: none;
+}
+::-webkit-color-swatch-wrapper {
+ padding: 0;
+}
+::file-selector-button {
+ font: inherit;
+}
+::-webkit-file-upload-button {
+ font: inherit;
+ -webkit-appearance: button;
+}
+output {
+ display: inline-block;
+}
+iframe {
+ border: 0;
+}
+summary {
+ display: list-item;
+ cursor: pointer;
+}
+progress {
+ vertical-align: baseline;
+}
+[hidden] {
+ display: none !important;
+}
+.lead {
+ font-size: 1.25rem;
+ font-weight: 300;
+}
+.display-1 {
+ font-size: calc(1.625rem+4.5vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-1 {
+ font-size: 5rem;
+ }
+}
+.display-2 {
+ font-size: calc(1.575rem+3.9vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-2 {
+ font-size: 4.5rem;
+ }
+}
+.display-3 {
+ font-size: calc(1.525rem+3.3vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-3 {
+ font-size: 4rem;
+ }
+}
+.display-4 {
+ font-size: calc(1.475rem+2.7vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-4 {
+ font-size: 3.5rem;
+ }
+}
+.display-5 {
+ font-size: calc(1.425rem+2.1vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-5 {
+ font-size: 3rem;
+ }
+}
+.display-6 {
+ font-size: calc(1.375rem+1.5vw);
+ font-weight: 300;
+ line-height: 1.2;
+}
+@media (min-width: 1200px) {
+ .display-6 {
+ font-size: 2.5rem;
+ }
+}
+.list-unstyled {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline {
+ padding-left: 0;
+ list-style: none;
+}
+.list-inline-item {
+ display: inline-block;
+}
+.list-inline-item:not(:last-child) {
+ margin-right: 0.5rem;
+}
+.initialism {
+ font-size: 0.875em;
+ text-transform: uppercase;
+}
+.blockquote {
+ margin-bottom: 1rem;
+ font-size: 1.25rem;
+}
+.blockquote > :last-child {
+ margin-bottom: 0;
+}
+.blockquote-footer {
+ margin-top: -1rem;
+ margin-bottom: 1rem;
+ font-size: 0.875em;
+ color: #6c757d;
+}
+.blockquote-footer::before {
+ content: '— ';
+}
+.img-fluid {
+ max-width: 100%;
+ height: auto;
+}
+.img-thumbnail {
+ padding: 0.25rem;
+ background-color: #fff;
+ border: 1px solid #dee2e6;
+ border-radius: 0.25rem;
+ max-width: 100%;
+ height: auto;
+}
+.figure {
+ display: inline-block;
+}
+.figure-img {
+ margin-bottom: 0.5rem;
+ line-height: 1;
+}
+.figure-caption {
+ font-size: 0.875em;
+ color: #6c757d;
+}
+.container,
+.container-fluid,
+.container-lg,
+.container-md,
+.container-sm,
+.container-xl,
+.container-xxl {
+ width: 100%;
+ padding-right: var(--bs-gutter-x, 0.75rem);
+ padding-left: var(--bs-gutter-x, 0.75rem);
+ margin-right: auto;
+ margin-left: auto;
+ padding: 0 12px;
+}
+@media (min-width: 576px) {
+ .container,
+ .container-sm {
+ max-width: 100%;
+ }
+}
+@media (min-width: 768px) {
+ .container,
+ .container-md,
+ .container-sm {
+ max-width: 720px;
+ }
+}
+@media (min-width: 992px) {
+ .container,
+ .container-lg,
+ .container-md,
+ .container-sm {
+ max-width: 960px;
+ }
+}
+@media (min-width: 1200px) {
+ .container,
+ .container-lg,
+ .container-md,
+ .container-sm,
+ .container-xl {
+ max-width: 1200px;
+ }
+}
+@media (min-width: 1440px) {
+ .container,
+ .container-lg,
+ .container-md,
+ .container-sm,
+ .container-xl,
+ .container-xxl {
+ max-width: 1440px;
+ padding: 0;
+ }
+}
+.cate-list {
+ width: 70%;
+ margin: auto;
+}
+.cate-list li {
+ width: 31.5%;
+ display: inline-block;
+ text-align: center;
+ padding: 36px 0 0;
+}
+.cate-list li img {
+ max-width: 50%;
+}
+.cate-list li p {
+ color: #333;
+ font-size: 14px;
+ padding-top: 12px;
+}
+@media (min-width: 400px) and (max-width: 1000px) {
+ .cate-list {
+ width: 98%;
+ margin: auto;
+ }
+ .cate-list li {
+ width: 24%;
+ padding: 16px 0 0;
+ }
+}
+@media (min-width: 320px) and (max-width: 399px) {
+ .cate-list {
+ width: 98%;
+ margin: auto;
+ }
+ .cate-list li {
+ width: 31.8%;
+ padding: 16px 0 0;
+ }
+}
+.cate-list li p:hover {
+ color: #036eb8;
+}
+.cate-list li:hover {
+ -webkit-transform: translateY(-10px);
+ -moz-transform: translateY(-10px);
+ -ms-transform: translateY(-10px);
+ transition: all 0.5s;
+ -webkit-transition: all 0.5s;
+ -ms-transition: all 0.5s;
+}
+.row {
+ --bs-gutter-x: 1.5rem;
+ --bs-gutter-y: 0;
+ display: flex;
+ flex-wrap: wrap;
+ margin-top: calc(var(--bs-gutter-y) * -1);
+ margin-right: calc(var(--bs-gutter-x) / -2);
+ margin-left: calc(var(--bs-gutter-x) / -2);
+}
+.row > * {
+ flex-shrink: 0;
+ width: 100%;
+ max-width: 100%;
+ padding-right: calc(var(--bs-gutter-x) / 2);
+ padding-left: calc(var(--bs-gutter-x) / 2);
+ margin-top: var(--bs-gutter-y);
+}
+.col {
+ flex: 1 0 0;
+}
+.row-cols-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+}
+.row-cols-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+}
+.row-cols-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+}
+.row-cols-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+}
+.row-cols-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+}
+.row-cols-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+}
+.row-cols-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+}
+.col-auto {
+ flex: 0 0 auto;
+ width: auto;
+}
+.col-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+}
+.col-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+}
+.col-3 {
+ flex: 0 0 auto;
+ width: 25%;
+}
+.col-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+}
+.col-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+}
+.col-6 {
+ flex: 0 0 auto;
+ width: 50%;
+}
+.col-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+}
+.col-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+}
+.col-9 {
+ flex: 0 0 auto;
+ width: 75%;
+}
+.col-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+}
+.col-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+}
+.col-12 {
+ flex: 0 0 auto;
+ width: 100%;
+}
+.offset-1 {
+ margin-left: 8.3333333333%;
+}
+.offset-2 {
+ margin-left: 16.6666666667%;
+}
+.offset-3 {
+ margin-left: 25%;
+}
+.offset-4 {
+ margin-left: 33.3333333333%;
+}
+.offset-5 {
+ margin-left: 41.6666666667%;
+}
+.offset-6 {
+ margin-left: 50%;
+}
+.offset-7 {
+ margin-left: 58.3333333333%;
+}
+.offset-8 {
+ margin-left: 66.6666666667%;
+}
+.offset-9 {
+ margin-left: 75%;
+}
+.offset-10 {
+ margin-left: 83.3333333333%;
+}
+.offset-11 {
+ margin-left: 91.6666666667%;
+}
+.g-0,
+.gx-0 {
+ --bs-gutter-x: 0;
+}
+.g-0,
+.gy-0 {
+ --bs-gutter-y: 0;
+}
+.g-1,
+.gx-1 {
+ --bs-gutter-x: 0.25rem;
+}
+.g-1,
+.gy-1 {
+ --bs-gutter-y: 0.25rem;
+}
+.g-2,
+.gx-2 {
+ --bs-gutter-x: 0.5rem;
+}
+.g-2,
+.gy-2 {
+ --bs-gutter-y: 0.5rem;
+}
+.g-3,
+.gx-3 {
+ --bs-gutter-x: 1rem;
+}
+.g-3,
+.gy-3 {
+ --bs-gutter-y: 1rem;
+}
+.g-4,
+.gx-4 {
+ --bs-gutter-x: 1.5rem;
+}
+.g-4,
+.gy-4 {
+ --bs-gutter-y: 1.5rem;
+}
+.g-5,
+.gx-5 {
+ --bs-gutter-x: 3rem;
+}
+.g-5,
+.gy-5 {
+ --bs-gutter-y: 3rem;
+}
+@media (min-width: 320px) {
+ .col-sm {
+ flex: 1 0 0;
+ }
+ .row-cols-sm-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .row-cols-sm-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .row-cols-sm-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .row-cols-sm-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .row-cols-sm-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .row-cols-sm-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+ .row-cols-sm-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-sm-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .col-sm-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+ }
+ .col-sm-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-sm-3 {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .col-sm-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .col-sm-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+ }
+ .col-sm-6 {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .col-sm-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+ }
+ .col-sm-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+ }
+ .col-sm-9 {
+ flex: 0 0 auto;
+ width: 75%;
+ }
+ .col-sm-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+ }
+ .col-sm-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+ }
+ .col-sm-12 {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .offset-sm-0 {
+ margin-left: 0;
+ }
+ .offset-sm-1 {
+ margin-left: 8.3333333333%;
+ }
+ .offset-sm-2 {
+ margin-left: 16.6666666667%;
+ }
+ .offset-sm-3 {
+ margin-left: 25%;
+ }
+ .offset-sm-4 {
+ margin-left: 33.3333333333%;
+ }
+ .offset-sm-5 {
+ margin-left: 41.6666666667%;
+ }
+ .offset-sm-6 {
+ margin-left: 50%;
+ }
+ .offset-sm-7 {
+ margin-left: 58.3333333333%;
+ }
+ .offset-sm-8 {
+ margin-left: 66.6666666667%;
+ }
+ .offset-sm-9 {
+ margin-left: 75%;
+ }
+ .offset-sm-10 {
+ margin-left: 83.3333333333%;
+ }
+ .offset-sm-11 {
+ margin-left: 91.6666666667%;
+ }
+ .g-sm-0,
+ .gx-sm-0 {
+ --bs-gutter-x: 0;
+ }
+ .g-sm-0,
+ .gy-sm-0 {
+ --bs-gutter-y: 0;
+ }
+ .g-sm-1,
+ .gx-sm-1 {
+ --bs-gutter-x: 0.25rem;
+ }
+ .g-sm-1,
+ .gy-sm-1 {
+ --bs-gutter-y: 0.25rem;
+ }
+ .g-sm-2,
+ .gx-sm-2 {
+ --bs-gutter-x: 0.5rem;
+ }
+ .g-sm-2,
+ .gy-sm-2 {
+ --bs-gutter-y: 0.5rem;
+ }
+ .g-sm-3,
+ .gx-sm-3 {
+ --bs-gutter-x: 1rem;
+ }
+ .g-sm-3,
+ .gy-sm-3 {
+ --bs-gutter-y: 1rem;
+ }
+ .g-sm-4,
+ .gx-sm-4 {
+ --bs-gutter-x: 1.5rem;
+ }
+ .g-sm-4,
+ .gy-sm-4 {
+ --bs-gutter-y: 1.5rem;
+ }
+ .g-sm-5,
+ .gx-sm-5 {
+ --bs-gutter-x: 3rem;
+ }
+ .g-sm-5,
+ .gy-sm-5 {
+ --bs-gutter-y: 3rem;
+ }
+}
+@media (min-width: 768px) {
+ .col-md {
+ flex: 1 0 0;
+ }
+ .row-cols-md-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .row-cols-md-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .row-cols-md-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .row-cols-md-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .row-cols-md-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .row-cols-md-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+ .row-cols-md-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-md-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .col-md-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+ }
+ .col-md-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-md-3 {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .col-md-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .col-md-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+ }
+ .col-md-6 {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .col-md-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+ }
+ .col-md-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+ }
+ .col-md-9 {
+ flex: 0 0 auto;
+ width: 75%;
+ }
+ .col-md-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+ }
+ .col-md-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+ }
+ .col-md-12 {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .offset-md-0 {
+ margin-left: 0;
+ }
+ .offset-md-1 {
+ margin-left: 8.3333333333%;
+ }
+ .offset-md-2 {
+ margin-left: 16.6666666667%;
+ }
+ .offset-md-3 {
+ margin-left: 25%;
+ }
+ .offset-md-4 {
+ margin-left: 33.3333333333%;
+ }
+ .offset-md-5 {
+ margin-left: 41.6666666667%;
+ }
+ .offset-md-6 {
+ margin-left: 50%;
+ }
+ .offset-md-7 {
+ margin-left: 58.3333333333%;
+ }
+ .offset-md-8 {
+ margin-left: 66.6666666667%;
+ }
+ .offset-md-9 {
+ margin-left: 75%;
+ }
+ .offset-md-10 {
+ margin-left: 83.3333333333%;
+ }
+ .offset-md-11 {
+ margin-left: 91.6666666667%;
+ }
+ .g-md-0,
+ .gx-md-0 {
+ --bs-gutter-x: 0;
+ }
+ .g-md-0,
+ .gy-md-0 {
+ --bs-gutter-y: 0;
+ }
+ .g-md-1,
+ .gx-md-1 {
+ --bs-gutter-x: 0.25rem;
+ }
+ .g-md-1,
+ .gy-md-1 {
+ --bs-gutter-y: 0.25rem;
+ }
+ .g-md-2,
+ .gx-md-2 {
+ --bs-gutter-x: 0.5rem;
+ }
+ .g-md-2,
+ .gy-md-2 {
+ --bs-gutter-y: 0.5rem;
+ }
+ .g-md-3,
+ .gx-md-3 {
+ --bs-gutter-x: 1rem;
+ }
+ .g-md-3,
+ .gy-md-3 {
+ --bs-gutter-y: 1rem;
+ }
+ .g-md-4,
+ .gx-md-4 {
+ --bs-gutter-x: 1.5rem;
+ }
+ .g-md-4,
+ .gy-md-4 {
+ --bs-gutter-y: 1.5rem;
+ }
+ .g-md-5,
+ .gx-md-5 {
+ --bs-gutter-x: 3rem;
+ }
+ .g-md-5,
+ .gy-md-5 {
+ --bs-gutter-y: 3rem;
+ }
+}
+@media (min-width: 992px) {
+ .col-lg {
+ flex: 1 0 0;
+ }
+ .row-cols-lg-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .row-cols-lg-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .row-cols-lg-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .row-cols-lg-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .row-cols-lg-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .row-cols-lg-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+ .row-cols-lg-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-lg-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .col-lg-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+ }
+ .col-lg-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-lg-3 {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .col-lg-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .col-lg-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+ }
+ .col-lg-6 {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .col-lg-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+ }
+ .col-lg-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+ }
+ .col-lg-9 {
+ flex: 0 0 auto;
+ width: 75%;
+ }
+ .col-lg-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+ }
+ .col-lg-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+ }
+ .col-lg-12 {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .offset-lg-0 {
+ margin-left: 0;
+ }
+ .offset-lg-1 {
+ margin-left: 8.3333333333%;
+ }
+ .offset-lg-2 {
+ margin-left: 16.6666666667%;
+ }
+ .offset-lg-3 {
+ margin-left: 25%;
+ }
+ .offset-lg-4 {
+ margin-left: 33.3333333333%;
+ }
+ .offset-lg-5 {
+ margin-left: 41.6666666667%;
+ }
+ .offset-lg-6 {
+ margin-left: 50%;
+ }
+ .offset-lg-7 {
+ margin-left: 58.3333333333%;
+ }
+ .offset-lg-8 {
+ margin-left: 66.6666666667%;
+ }
+ .offset-lg-9 {
+ margin-left: 75%;
+ }
+ .offset-lg-10 {
+ margin-left: 83.3333333333%;
+ }
+ .offset-lg-11 {
+ margin-left: 91.6666666667%;
+ }
+ .g-lg-0,
+ .gx-lg-0 {
+ --bs-gutter-x: 0;
+ }
+ .g-lg-0,
+ .gy-lg-0 {
+ --bs-gutter-y: 0;
+ }
+ .g-lg-1,
+ .gx-lg-1 {
+ --bs-gutter-x: 0.25rem;
+ }
+ .g-lg-1,
+ .gy-lg-1 {
+ --bs-gutter-y: 0.25rem;
+ }
+ .g-lg-2,
+ .gx-lg-2 {
+ --bs-gutter-x: 0.5rem;
+ }
+ .g-lg-2,
+ .gy-lg-2 {
+ --bs-gutter-y: 0.5rem;
+ }
+ .g-lg-3,
+ .gx-lg-3 {
+ --bs-gutter-x: 1rem;
+ }
+ .g-lg-3,
+ .gy-lg-3 {
+ --bs-gutter-y: 1rem;
+ }
+ .g-lg-4,
+ .gx-lg-4 {
+ --bs-gutter-x: 1.5rem;
+ }
+ .g-lg-4,
+ .gy-lg-4 {
+ --bs-gutter-y: 1.5rem;
+ }
+ .g-lg-5,
+ .gx-lg-5 {
+ --bs-gutter-x: 3rem;
+ }
+ .g-lg-5,
+ .gy-lg-5 {
+ --bs-gutter-y: 3rem;
+ }
+}
+@media (min-width: 1200px) {
+ .col-xl {
+ flex: 1 0 0;
+ }
+ .row-cols-xl-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .row-cols-xl-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .row-cols-xl-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .row-cols-xl-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .row-cols-xl-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .row-cols-xl-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+ .row-cols-xl-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-xl-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .col-xl-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+ }
+ .col-xl-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-xl-3 {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .col-xl-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .col-xl-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+ }
+ .col-xl-6 {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .col-xl-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+ }
+ .col-xl-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+ }
+ .col-xl-9 {
+ flex: 0 0 auto;
+ width: 75%;
+ }
+ .col-xl-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+ }
+ .col-xl-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+ }
+ .col-xl-12 {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .offset-xl-0 {
+ margin-left: 0;
+ }
+ .offset-xl-1 {
+ margin-left: 8.3333333333%;
+ }
+ .offset-xl-2 {
+ margin-left: 16.6666666667%;
+ }
+ .offset-xl-3 {
+ margin-left: 25%;
+ }
+ .offset-xl-4 {
+ margin-left: 33.3333333333%;
+ }
+ .offset-xl-5 {
+ margin-left: 41.6666666667%;
+ }
+ .offset-xl-6 {
+ margin-left: 50%;
+ }
+ .offset-xl-7 {
+ margin-left: 58.3333333333%;
+ }
+ .offset-xl-8 {
+ margin-left: 66.6666666667%;
+ }
+ .offset-xl-9 {
+ margin-left: 75%;
+ }
+ .offset-xl-10 {
+ margin-left: 83.3333333333%;
+ }
+ .offset-xl-11 {
+ margin-left: 91.6666666667%;
+ }
+ .g-xl-0,
+ .gx-xl-0 {
+ --bs-gutter-x: 0;
+ }
+ .g-xl-0,
+ .gy-xl-0 {
+ --bs-gutter-y: 0;
+ }
+ .g-xl-1,
+ .gx-xl-1 {
+ --bs-gutter-x: 0.25rem;
+ }
+ .g-xl-1,
+ .gy-xl-1 {
+ --bs-gutter-y: 0.25rem;
+ }
+ .g-xl-2,
+ .gx-xl-2 {
+ --bs-gutter-x: 0.5rem;
+ }
+ .g-xl-2,
+ .gy-xl-2 {
+ --bs-gutter-y: 0.5rem;
+ }
+ .g-xl-3,
+ .gx-xl-3 {
+ --bs-gutter-x: 1rem;
+ }
+ .g-xl-3,
+ .gy-xl-3 {
+ --bs-gutter-y: 1rem;
+ }
+ .g-xl-4,
+ .gx-xl-4 {
+ --bs-gutter-x: 1.5rem;
+ }
+ .g-xl-4,
+ .gy-xl-4 {
+ --bs-gutter-y: 1.5rem;
+ }
+ .g-xl-5,
+ .gx-xl-5 {
+ --bs-gutter-x: 3rem;
+ }
+ .g-xl-5,
+ .gy-xl-5 {
+ --bs-gutter-y: 3rem;
+ }
+}
+@media (min-width: 1400px) {
+ .col-xxl {
+ flex: 1 0 0;
+ }
+ .row-cols-xxl-auto > * {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .row-cols-xxl-1 > * {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .row-cols-xxl-2 > * {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .row-cols-xxl-3 > * {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .row-cols-xxl-4 > * {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .row-cols-xxl-5 > * {
+ flex: 0 0 auto;
+ width: 20%;
+ }
+ .row-cols-xxl-6 > * {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-xxl-auto {
+ flex: 0 0 auto;
+ width: auto;
+ }
+ .col-xxl-1 {
+ flex: 0 0 auto;
+ width: 8.3333333333%;
+ }
+ .col-xxl-2 {
+ flex: 0 0 auto;
+ width: 16.6666666667%;
+ }
+ .col-xxl-3 {
+ flex: 0 0 auto;
+ width: 25%;
+ }
+ .col-xxl-4 {
+ flex: 0 0 auto;
+ width: 33.3333333333%;
+ }
+ .col-xxl-5 {
+ flex: 0 0 auto;
+ width: 41.6666666667%;
+ }
+ .col-xxl-6 {
+ flex: 0 0 auto;
+ width: 50%;
+ }
+ .col-xxl-7 {
+ flex: 0 0 auto;
+ width: 58.3333333333%;
+ }
+ .col-xxl-8 {
+ flex: 0 0 auto;
+ width: 66.6666666667%;
+ }
+ .col-xxl-9 {
+ flex: 0 0 auto;
+ width: 75%;
+ }
+ .col-xxl-10 {
+ flex: 0 0 auto;
+ width: 83.3333333333%;
+ }
+ .col-xxl-11 {
+ flex: 0 0 auto;
+ width: 91.6666666667%;
+ }
+ .col-xxl-12 {
+ flex: 0 0 auto;
+ width: 100%;
+ }
+ .offset-xxl-0 {
+ margin-left: 0;
+ }
+ .offset-xxl-1 {
+ margin-left: 8.3333333333%;
+ }
+ .offset-xxl-2 {
+ margin-left: 16.6666666667%;
+ }
+ .offset-xxl-3 {
+ margin-left: 25%;
+ }
+ .offset-xxl-4 {
+ margin-left: 33.3333333333%;
+ }
+ .offset-xxl-5 {
+ margin-left: 41.6666666667%;
+ }
+ .offset-xxl-6 {
+ margin-left: 50%;
+ }
+ .offset-xxl-7 {
+ margin-left: 58.3333333333%;
+ }
+ .offset-xxl-8 {
+ margin-left: 66.6666666667%;
+ }
+ .offset-xxl-9 {
+ margin-left: 75%;
+ }
+ .offset-xxl-10 {
+ margin-left: 83.3333333333%;
+ }
+ .offset-xxl-11 {
+ margin-left: 91.6666666667%;
+ }
+ .g-xxl-0,
+ .gx-xxl-0 {
+ --bs-gutter-x: 0;
+ }
+ .g-xxl-0,
+ .gy-xxl-0 {
+ --bs-gutter-y: 0;
+ }
+ .g-xxl-1,
+ .gx-xxl-1 {
+ --bs-gutter-x: 0.25rem;
+ }
+ .g-xxl-1,
+ .gy-xxl-1 {
+ --bs-gutter-y: 0.25rem;
+ }
+ .g-xxl-2,
+ .gx-xxl-2 {
+ --bs-gutter-x: 0.5rem;
+ }
+ .g-xxl-2,
+ .gy-xxl-2 {
+ --bs-gutter-y: 0.5rem;
+ }
+ .g-xxl-3,
+ .gx-xxl-3 {
+ --bs-gutter-x: 1rem;
+ }
+ .g-xxl-3,
+ .gy-xxl-3 {
+ --bs-gutter-y: 1rem;
+ }
+ .g-xxl-4,
+ .gx-xxl-4 {
+ --bs-gutter-x: 1.5rem;
+ }
+ .g-xxl-4,
+ .gy-xxl-4 {
+ --bs-gutter-y: 1.5rem;
+ }
+ .g-xxl-5,
+ .gx-xxl-5 {
+ --bs-gutter-x: 3rem;
+ }
+ .g-xxl-5,
+ .gy-xxl-5 {
+ --bs-gutter-y: 3rem;
+ }
+}
+.table {
+ --bs-table-bg: transparent;
+ --bs-table-striped-color: #212529;
+ --bs-table-striped-bg: rgba(0, 0, 0, 0.05);
+ --bs-table-active-color: #212529;
+ --bs-table-active-bg: rgba(0, 0, 0, 0.1);
+ --bs-table-hover-color: #212529;
+ --bs-table-hover-bg: rgba(0, 0, 0, 0.075);
+ width: 100%;
+ margin-bottom: 1rem;
+ color: #212529;
+ vertical-align: top;
+ border-color: #dee2e6;
+}
+.table > :not(caption) > * > * {
+ padding: 0.5rem 0.5rem;
+ background-color: var(--bs-table-bg);
+ border-bottom-width: 1px;
+ box-shadow: inset 0 0 0 9999px var(--bs-table-accent-bg);
+}
+.table > tbody {
+ vertical-align: inherit;
+}
+.table > thead {
+ vertical-align: bottom;
+}
+.table > :not(:last-child) > :last-child > * {
+ border-bottom-color: currentColor;
+}
+.caption-top {
+ caption-side: top;
+}
+.table-sm > :not(caption) > * > * {
+ padding: 0.25rem 0.25rem;
+}
+.table-bordered > :not(caption) > * {
+ border-width: 1px 0;
+}
+.table-bordered > :not(caption) > * > * {
+ border-width: 0 1px;
+}
+.table-borderless > :not(caption) > * > * {
+ border-bottom-width: 0;
+}
+.table-striped > tbody > tr:nth-of-type(odd) {
+ --bs-table-accent-bg: var(--bs-table-striped-bg);
+ color: var(--bs-table-striped-color);
+}
+.table-active {
+ --bs-table-accent-bg: var(--bs-table-active-bg);
+ color: var(--bs-table-active-color);
+}
+.table-hover > tbody > tr:hover {
+ --bs-table-accent-bg: var(--bs-table-hover-bg);
+ color: var(--bs-table-hover-color);
+}
+.table-primary {
+ --bs-table-bg: #cfe2ff;
+ --bs-table-striped-bg: #c5d7f2;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #bacbe6;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #bfd1ec;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #bacbe6;
+}
+.table-secondary {
+ --bs-table-bg: #e2e3e5;
+ --bs-table-striped-bg: #d7d8da;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #cbccce;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #d1d2d4;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #cbccce;
+}
+.table-success {
+ --bs-table-bg: #d1e7dd;
+ --bs-table-striped-bg: #c7dbd2;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #bcd0c7;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #c1d6cc;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #bcd0c7;
+}
+.table-info {
+ --bs-table-bg: #cff4fc;
+ --bs-table-striped-bg: #c5e8ef;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #badce3;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #bfe2e9;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #badce3;
+}
+.table-warning {
+ --bs-table-bg: #fff3cd;
+ --bs-table-striped-bg: #f2e7c3;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #e6dbb9;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #ece1be;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #e6dbb9;
+}
+.table-danger {
+ --bs-table-bg: #f8d7da;
+ --bs-table-striped-bg: #eccccf;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #dfc2c4;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #e5c7ca;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #dfc2c4;
+}
+.table-light {
+ --bs-table-bg: #f8f9fa;
+ --bs-table-striped-bg: #ecedee;
+ --bs-table-striped-color: #000;
+ --bs-table-active-bg: #dfe0e1;
+ --bs-table-active-color: #000;
+ --bs-table-hover-bg: #e5e6e7;
+ --bs-table-hover-color: #000;
+ color: #000;
+ border-color: #dfe0e1;
+}
+.table-dark {
+ --bs-table-bg: #212529;
+ --bs-table-striped-bg: #2c3034;
+ --bs-table-striped-color: #fff;
+ --bs-table-active-bg: #373b3e;
+ --bs-table-active-color: #fff;
+ --bs-table-hover-bg: #323539;
+ --bs-table-hover-color: #fff;
+ color: #fff;
+ border-color: #373b3e;
+}
+.table-responsive {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+}
+@media (max-width: 575.98px) {
+ .table-responsive-sm {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+@media (max-width: 767.98px) {
+ .table-responsive-md {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+@media (max-width: 991.98px) {
+ .table-responsive-lg {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+@media (max-width: 1199.98px) {
+ .table-responsive-xl {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+@media (max-width: 1399.98px) {
+ .table-responsive-xxl {
+ overflow-x: auto;
+ -webkit-overflow-scrolling: touch;
+ }
+}
+.form-label {
+ margin-bottom: 0.5rem;
+}
+.col-form-label {
+ padding-top: calc(0.375rem+1px);
+ padding-bottom: calc(0.375rem+1px);
+ margin-bottom: 0;
+ font-size: inherit;
+ line-height: 1.5;
+}
+.col-form-label-lg {
+ padding-top: calc(0.5rem+1px);
+ padding-bottom: calc(0.5rem+1px);
+ font-size: 1.25rem;
+}
+.col-form-label-sm {
+ padding-top: calc(0.25rem+1px);
+ padding-bottom: calc(0.25rem+1px);
+ font-size: 0.875rem;
+}
+.form-text {
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: #6c757d;
+}
+.form-control {
+ display: block;
+ width: 100%;
+ padding: 0.375rem 0.75rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid #ced4da;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border-radius: 0.25rem;
+ transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-control {
+ transition: none;
+ }
+}
+.form-control[type='file'] {
+ overflow: hidden;
+}
+.form-control[type='file']:not(:disabled):not([readonly]) {
+ cursor: pointer;
+}
+.form-control:focus {
+ color: #212529;
+ background-color: #fff;
+ border-color: #86b7fe;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-control::-webkit-date-and-time-value {
+ height: 1.5em;
+}
+.form-control::-moz-placeholder {
+ color: #6c757d;
+ opacity: 1;
+}
+.form-control::placeholder {
+ color: #6c757d;
+ opacity: 1;
+}
+.form-control:disabled,
+.form-control[readonly] {
+ background-color: #e9ecef;
+ opacity: 1;
+}
+.form-control::file-selector-button {
+ padding: 0.375rem 0.75rem;
+ margin: -0.375rem -0.75rem;
+ -webkit-margin-end: 0.75rem;
+ margin-inline-end: 0.75rem;
+ color: #212529;
+ background-color: #e9ecef;
+ pointer-events: none;
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+ border-inline-end-width: 1px;
+ border-radius: 0;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-control::file-selector-button {
+ transition: none;
+ }
+}
+.form-control:hover:not(:disabled):not([readonly])::file-selector-button {
+ background-color: #dde0e3;
+}
+.form-control::-webkit-file-upload-button {
+ padding: 0.375rem 0.75rem;
+ margin: -0.375rem -0.75rem;
+ -webkit-margin-end: 0.75rem;
+ margin-inline-end: 0.75rem;
+ color: #212529;
+ background-color: #e9ecef;
+ pointer-events: none;
+ border-color: inherit;
+ border-style: solid;
+ border-width: 0;
+ border-inline-end-width: 1px;
+ border-radius: 0;
+ -webkit-transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out,
+ box-shadow 0.15s ease-in-out;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-control::-webkit-file-upload-button {
+ -webkit-transition: none;
+ transition: none;
+ }
+}
+.form-control:hover:not(:disabled):not([readonly])::-webkit-file-upload-button {
+ background-color: #dde0e3;
+}
+.form-control-plaintext {
+ display: block;
+ width: 100%;
+ padding: 0.375rem 0;
+ margin-bottom: 0;
+ line-height: 1.5;
+ color: #212529;
+ background-color: transparent;
+ border: solid transparent;
+ border-width: 1px 0;
+}
+.form-control-plaintext.form-control-lg,
+.form-control-plaintext.form-control-sm {
+ padding-right: 0;
+ padding-left: 0;
+}
+.form-control-sm {
+ min-height: calc(1.5em+0.5rem+2px);
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+.form-control-sm::file-selector-button {
+ padding: 0.25rem 0.5rem;
+ margin: -0.25rem -0.5rem;
+ -webkit-margin-end: 0.5rem;
+ margin-inline-end: 0.5rem;
+}
+.form-control-sm::-webkit-file-upload-button {
+ padding: 0.25rem 0.5rem;
+ margin: -0.25rem -0.5rem;
+ -webkit-margin-end: 0.5rem;
+ margin-inline-end: 0.5rem;
+}
+.form-control-lg {
+ min-height: calc(1.5em+1rem+2px);
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+.form-control-lg::file-selector-button {
+ padding: 0.5rem 1rem;
+ margin: -0.5rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+}
+.form-control-lg::-webkit-file-upload-button {
+ padding: 0.5rem 1rem;
+ margin: -0.5rem -1rem;
+ -webkit-margin-end: 1rem;
+ margin-inline-end: 1rem;
+}
+textarea.form-control {
+ min-height: calc(1.5em+0.75rem+2px);
+}
+textarea.form-control-sm {
+ min-height: calc(1.5em+0.5rem+2px);
+}
+textarea.form-control-lg {
+ min-height: calc(1.5em+1rem+2px);
+}
+.form-control-color {
+ max-width: 3rem;
+ height: auto;
+ padding: 0.375rem;
+}
+.form-control-color:not(:disabled):not([readonly]) {
+ cursor: pointer;
+}
+.form-control-color::-moz-color-swatch {
+ height: 1.5em;
+ border-radius: 0.25rem;
+}
+.form-control-color::-webkit-color-swatch {
+ height: 1.5em;
+ border-radius: 0.25rem;
+}
+.form-select {
+ display: block;
+ width: 100%;
+ padding: 0.375rem 2.25rem 0.375rem 0.75rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ background-color: #fff;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right 0.75rem center;
+ background-size: 16px 12px;
+ border: 1px solid #ced4da;
+ border-radius: 0.25rem;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+.form-select:focus {
+ border-color: #86b7fe;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-select[multiple],
+.form-select[size]:not([size='1']) {
+ padding-right: 0.75rem;
+ background-image: none;
+}
+.form-select:disabled {
+ background-color: #e9ecef;
+}
+.form-select:-moz-focusring {
+ color: transparent;
+ text-shadow: 0 0 0 #212529;
+}
+.form-select-sm {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem;
+ padding-left: 0.5rem;
+ font-size: 0.875rem;
+}
+.form-select-lg {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+ padding-left: 1rem;
+ font-size: 1.25rem;
+}
+.form-check {
+ display: block;
+ min-height: 1.5rem;
+ padding-left: 1.5em;
+ margin-bottom: 0.125rem;
+}
+.form-check .form-check-input {
+ float: left;
+ margin-left: -1.5em;
+}
+.form-check-input {
+ width: 1em;
+ height: 1em;
+ margin-top: 0.25em;
+ vertical-align: top;
+ background-color: #fff;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: contain;
+ border: 1px solid rgba(0, 0, 0, 0.25);
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ -webkit-print-color-adjust: exact;
+ color-adjust: exact;
+}
+.form-check-input[type='checkbox'] {
+ border-radius: 0.25em;
+}
+.form-check-input[type='radio'] {
+ border-radius: 50%;
+}
+.form-check-input:active {
+ filter: brightness(90%);
+}
+.form-check-input:focus {
+ border-color: #86b7fe;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-check-input:checked {
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+.form-check-input:checked[type='checkbox'] {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e");
+}
+.form-check-input:checked[type='radio'] {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='%23fff'/%3e%3c/svg%3e");
+}
+.form-check-input[type='checkbox']:indeterminate {
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='%23fff' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10h8'/%3e%3c/svg%3e");
+}
+.form-check-input:disabled {
+ pointer-events: none;
+ filter: none;
+ opacity: 0.5;
+}
+.form-check-input:disabled ~ .form-check-label,
+.form-check-input[disabled] ~ .form-check-label {
+ opacity: 0.5;
+}
+.form-switch {
+ padding-left: 2.5em;
+}
+.form-switch .form-check-input {
+ width: 2em;
+ margin-left: -2.5em;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='rgba%280, 0, 0, 0.25%29'/%3e%3c/svg%3e");
+ background-position: left center;
+ border-radius: 2em;
+ transition: background-position 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-switch .form-check-input {
+ transition: none;
+ }
+}
+.form-switch .form-check-input:focus {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%2386b7fe'/%3e%3c/svg%3e");
+}
+.form-switch .form-check-input:checked {
+ background-position: right center;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23fff'/%3e%3c/svg%3e");
+}
+.form-check-inline {
+ display: inline-block;
+ margin-right: 1rem;
+}
+.btn-check {
+ position: absolute;
+ clip: rect(0, 0, 0, 0);
+ pointer-events: none;
+}
+.btn-check:disabled + .btn,
+.btn-check[disabled] + .btn {
+ pointer-events: none;
+ filter: none;
+ opacity: 0.65;
+}
+.form-range {
+ width: 100%;
+ height: 1.5rem;
+ padding: 0;
+ background-color: transparent;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+}
+.form-range:focus {
+ outline: 0;
+}
+.form-range:focus::-webkit-slider-thumb {
+ box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-range:focus::-moz-range-thumb {
+ box-shadow: 0 0 0 1px #fff, 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.form-range::-moz-focus-outer {
+ border: 0;
+}
+.form-range::-webkit-slider-thumb {
+ width: 1rem;
+ height: 1rem;
+ margin-top: -0.25rem;
+ background-color: #0d6efd;
+ border: 0;
+ border-radius: 1rem;
+ -webkit-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ -webkit-appearance: none;
+ appearance: none;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-range::-webkit-slider-thumb {
+ -webkit-transition: none;
+ transition: none;
+ }
+}
+.form-range::-webkit-slider-thumb:active {
+ background-color: #b6d4fe;
+}
+.form-range::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 0.5rem;
+ color: transparent;
+ cursor: pointer;
+ background-color: #dee2e6;
+ border-color: transparent;
+ border-radius: 1rem;
+}
+.form-range::-moz-range-thumb {
+ width: 1rem;
+ height: 1rem;
+ background-color: #0d6efd;
+ border: 0;
+ border-radius: 1rem;
+ -moz-transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+ -moz-appearance: none;
+ appearance: none;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-range::-moz-range-thumb {
+ -moz-transition: none;
+ transition: none;
+ }
+}
+.form-range::-moz-range-thumb:active {
+ background-color: #b6d4fe;
+}
+.form-range::-moz-range-track {
+ width: 100%;
+ height: 0.5rem;
+ color: transparent;
+ cursor: pointer;
+ background-color: #dee2e6;
+ border-color: transparent;
+ border-radius: 1rem;
+}
+.form-range:disabled {
+ pointer-events: none;
+}
+.form-range:disabled::-webkit-slider-thumb {
+ background-color: #adb5bd;
+}
+.form-range:disabled::-moz-range-thumb {
+ background-color: #adb5bd;
+}
+.form-floating {
+ position: relative;
+}
+.form-floating > .form-control,
+.form-floating > .form-select {
+ height: calc(3.5rem+2px);
+ padding: 1rem 0.75rem;
+}
+.form-floating > label {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 100%;
+ padding: 1rem 0.75rem;
+ pointer-events: none;
+ border: 1px solid transparent;
+ transform-origin: 0 0;
+ transition: opacity 0.1s ease-in-out, transform 0.1s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .form-floating > label {
+ transition: none;
+ }
+}
+.form-floating > .form-control::-moz-placeholder {
+ color: transparent;
+}
+.form-floating > .form-control::placeholder {
+ color: transparent;
+}
+.form-floating > .form-control:not(:-moz-placeholder-shown) {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:focus,
+.form-floating > .form-control:not(:placeholder-shown) {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:-webkit-autofill {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+.form-floating > .form-select {
+ padding-top: 1.625rem;
+ padding-bottom: 0.625rem;
+}
+.form-floating > .form-control:not(:-moz-placeholder-shown) ~ label {
+ opacity: 0.65;
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.form-floating > .form-control:focus ~ label,
+.form-floating > .form-control:not(:placeholder-shown) ~ label,
+.form-floating > .form-select ~ label {
+ opacity: 0.65;
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.form-floating > .form-control:-webkit-autofill ~ label {
+ opacity: 0.65;
+ transform: scale(0.85) translateY(-0.5rem) translateX(0.15rem);
+}
+.input-group {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: stretch;
+ width: 100%;
+}
+.input-group > .form-control,
+.input-group > .form-select {
+ position: relative;
+ flex: 1 1 auto;
+ width: 1%;
+ min-width: 0;
+}
+.input-group > .form-control:focus,
+.input-group > .form-select:focus {
+ z-index: 3;
+}
+.input-group .btn {
+ position: relative;
+ z-index: 2;
+}
+.input-group .btn:focus {
+ z-index: 3;
+}
+.input-group-text {
+ display: flex;
+ align-items: center;
+ padding: 0.375rem 0.75rem;
+ font-size: 1rem;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ text-align: center;
+ white-space: nowrap;
+ background-color: #e9ecef;
+ border: 1px solid #ced4da;
+ border-radius: 0.25rem;
+}
+.input-group-lg > .btn,
+.input-group-lg > .form-control,
+.input-group-lg > .form-select,
+.input-group-lg > .input-group-text {
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+.input-group-sm > .btn,
+.input-group-sm > .form-control,
+.input-group-sm > .form-select,
+.input-group-sm > .input-group-text {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+.input-group-lg > .form-select,
+.input-group-sm > .form-select {
+ padding-right: 3rem;
+}
+.input-group:not(.has-validation) > .dropdown-toggle:nth-last-child(n + 3),
+.input-group:not(.has-validation) > :not(:last-child):not(.dropdown-toggle):not(.dropdown-menu) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group.has-validation > .dropdown-toggle:nth-last-child(n + 4),
+.input-group.has-validation > :nth-last-child(n + 3):not(.dropdown-toggle):not(.dropdown-menu) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.input-group
+ > :not(:first-child):not(.dropdown-menu):not(.valid-tooltip):not(.valid-feedback):not(.invalid-tooltip):not(.invalid-feedback) {
+ margin-left: -1px;
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.valid-feedback {
+ display: none;
+ width: 100%;
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: #198754;
+}
+.valid-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ max-width: 100%;
+ padding: 0.25rem 0.5rem;
+ margin-top: 0.1rem;
+ font-size: 0.875rem;
+ color: #fff;
+ background-color: rgba(25, 135, 84, 0.9);
+ border-radius: 0.25rem;
+}
+.is-valid ~ .valid-feedback,
+.is-valid ~ .valid-tooltip,
+.was-validated :valid ~ .valid-feedback,
+.was-validated :valid ~ .valid-tooltip {
+ display: block;
+}
+.form-control.is-valid,
+.was-validated .form-control:valid {
+ border-color: #198754;
+ padding-right: calc(1.5em+0.75rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375em+0.1875rem) center;
+ background-size: calc(0.75em+0.375rem) calc(0.75em+0.375rem);
+}
+.form-control.is-valid:focus,
+.was-validated .form-control:valid:focus {
+ border-color: #198754;
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
+}
+.was-validated textarea.form-control:valid,
+textarea.form-control.is-valid {
+ padding-right: calc(1.5em+0.75rem);
+ background-position: top calc(0.375em+0.1875rem) right calc(0.375em+0.1875rem);
+}
+.form-select.is-valid,
+.was-validated .form-select:valid {
+ border-color: #198754;
+ padding-right: 4.125rem;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
+ url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3e%3cpath fill='%23198754' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
+ background-position: right 0.75rem center, center right 2.25rem;
+ background-size: 16px 12px, calc(0.75em+0.375rem) calc(0.75em+0.375rem);
+}
+.form-select.is-valid:focus,
+.was-validated .form-select:valid:focus {
+ border-color: #198754;
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
+}
+.form-check-input.is-valid,
+.was-validated .form-check-input:valid {
+ border-color: #198754;
+}
+.form-check-input.is-valid:checked,
+.was-validated .form-check-input:valid:checked {
+ background-color: #198754;
+}
+.form-check-input.is-valid:focus,
+.was-validated .form-check-input:valid:focus {
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.25);
+}
+.form-check-input.is-valid ~ .form-check-label,
+.was-validated .form-check-input:valid ~ .form-check-label {
+ color: #198754;
+}
+.form-check-inline .form-check-input ~ .valid-feedback {
+ margin-left: 0.5em;
+}
+.input-group .form-control.is-valid,
+.input-group .form-select.is-valid,
+.was-validated .input-group .form-control:valid,
+.was-validated .input-group .form-select:valid {
+ z-index: 3;
+}
+.invalid-feedback {
+ display: none;
+ width: 100%;
+ margin-top: 0.25rem;
+ font-size: 0.875em;
+ color: #dc3545;
+}
+.invalid-tooltip {
+ position: absolute;
+ top: 100%;
+ z-index: 5;
+ display: none;
+ max-width: 100%;
+ padding: 0.25rem 0.5rem;
+ margin-top: 0.1rem;
+ font-size: 0.875rem;
+ color: #fff;
+ background-color: rgba(220, 53, 69, 0.9);
+ border-radius: 0.25rem;
+}
+.is-invalid ~ .invalid-feedback,
+.is-invalid ~ .invalid-tooltip,
+.was-validated :invalid ~ .invalid-feedback,
+.was-validated :invalid ~ .invalid-tooltip {
+ display: block;
+}
+.form-control.is-invalid,
+.was-validated .form-control:invalid {
+ border-color: #dc3545;
+ padding-right: calc(1.5em+0.75rem);
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-position: right calc(0.375em+0.1875rem) center;
+ background-size: calc(0.75em+0.375rem) calc(0.75em+0.375rem);
+}
+.form-control.is-invalid:focus,
+.was-validated .form-control:invalid:focus {
+ border-color: #dc3545;
+ box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+.was-validated textarea.form-control:invalid,
+textarea.form-control.is-invalid {
+ padding-right: calc(1.5em+0.75rem);
+ background-position: top calc(0.375em+0.1875rem) right calc(0.375em+0.1875rem);
+}
+.form-select.is-invalid,
+.was-validated .form-select:invalid {
+ border-color: #dc3545;
+ padding-right: 4.125rem;
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23343a40' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='M2 5l6 6 6-6'/%3e%3c/svg%3e"),
+ url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12' width='12' height='12' fill='none' stroke='%23dc3545'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3e%3c/svg%3e");
+ background-position: right 0.75rem center, center right 2.25rem;
+ background-size: 16px 12px, calc(0.75em+0.375rem) calc(0.75em+0.375rem);
+}
+.form-select.is-invalid:focus,
+.was-validated .form-select:invalid:focus {
+ border-color: #dc3545;
+ box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+.form-check-input.is-invalid,
+.was-validated .form-check-input:invalid {
+ border-color: #dc3545;
+}
+.form-check-input.is-invalid:checked,
+.was-validated .form-check-input:invalid:checked {
+ background-color: #dc3545;
+}
+.form-check-input.is-invalid:focus,
+.was-validated .form-check-input:invalid:focus {
+ box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25);
+}
+.form-check-input.is-invalid ~ .form-check-label,
+.was-validated .form-check-input:invalid ~ .form-check-label {
+ color: #dc3545;
+}
+.form-check-inline .form-check-input ~ .invalid-feedback {
+ margin-left: 0.5em;
+}
+.input-group .form-control.is-invalid,
+.input-group .form-select.is-invalid,
+.was-validated .input-group .form-control:invalid,
+.was-validated .input-group .form-select:invalid {
+ z-index: 3;
+}
+.btn {
+ display: inline-block;
+ font-weight: 400;
+ line-height: 1.5;
+ color: #212529;
+ text-align: center;
+ text-decoration: none;
+ vertical-align: middle;
+ cursor: pointer;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ background-color: transparent;
+ border: 1px solid transparent;
+ padding: 0.375rem 0.75rem;
+ font-size: 1rem;
+ border-radius: 0.25rem;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .btn {
+ transition: none;
+ }
+}
+.btn:hover {
+ color: #212529;
+}
+.btn-check:focus + .btn,
+.btn:focus {
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.btn.disabled,
+.btn:disabled,
+fieldset:disabled .btn {
+ pointer-events: none;
+ opacity: 0.65;
+}
+
+.btn-secondary {
+ color: #fff;
+ background-color: #6c757d;
+ border-color: #6c757d;
+}
+.btn-secondary:hover {
+ color: #fff;
+ background-color: #5c636a;
+ border-color: #565e64;
+}
+.btn-check:focus + .btn-secondary,
+.btn-secondary:focus {
+ color: #fff;
+ background-color: #5c636a;
+ border-color: #565e64;
+ box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);
+}
+.btn-check:active + .btn-secondary,
+.btn-check:checked + .btn-secondary,
+.btn-secondary.active,
+.btn-secondary:active,
+.show > .btn-secondary.dropdown-toggle {
+ color: #fff;
+ background-color: #565e64;
+ border-color: #51585e;
+}
+.btn-check:active + .btn-secondary:focus,
+.btn-check:checked + .btn-secondary:focus,
+.btn-secondary.active:focus,
+.btn-secondary:active:focus,
+.show > .btn-secondary.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(130, 138, 145, 0.5);
+}
+.btn-secondary.disabled,
+.btn-secondary:disabled {
+ color: #fff;
+ background-color: #6c757d;
+ border-color: #6c757d;
+}
+.btn-success {
+ color: #fff;
+ background-color: #198754;
+ border-color: #198754;
+}
+.btn-success:hover {
+ color: #fff;
+ background-color: #157347;
+ border-color: #146c43;
+}
+.btn-check:focus + .btn-success,
+.btn-success:focus {
+ color: #fff;
+ background-color: #157347;
+ border-color: #146c43;
+ box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);
+}
+.btn-check:active + .btn-success,
+.btn-check:checked + .btn-success,
+.btn-success.active,
+.btn-success:active,
+.show > .btn-success.dropdown-toggle {
+ color: #fff;
+ background-color: #146c43;
+ border-color: #13653f;
+}
+.btn-check:active + .btn-success:focus,
+.btn-check:checked + .btn-success:focus,
+.btn-success.active:focus,
+.btn-success:active:focus,
+.show > .btn-success.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(60, 153, 110, 0.5);
+}
+.btn-success.disabled,
+.btn-success:disabled {
+ color: #fff;
+ background-color: #198754;
+ border-color: #198754;
+}
+.btn-info {
+ color: #000;
+ background-color: #0dcaf0;
+ border-color: #0dcaf0;
+}
+.btn-info:hover {
+ color: #000;
+ background-color: #31d2f2;
+ border-color: #25cff2;
+}
+.btn-check:focus + .btn-info,
+.btn-info:focus {
+ color: #000;
+ background-color: #31d2f2;
+ border-color: #25cff2;
+ box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);
+}
+.btn-check:active + .btn-info,
+.btn-check:checked + .btn-info,
+.btn-info.active,
+.btn-info:active,
+.show > .btn-info.dropdown-toggle {
+ color: #000;
+ background-color: #3dd5f3;
+ border-color: #25cff2;
+}
+.btn-check:active + .btn-info:focus,
+.btn-check:checked + .btn-info:focus,
+.btn-info.active:focus,
+.btn-info:active:focus,
+.show > .btn-info.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(11, 172, 204, 0.5);
+}
+.btn-info.disabled,
+.btn-info:disabled {
+ color: #000;
+ background-color: #0dcaf0;
+ border-color: #0dcaf0;
+}
+.btn-warning {
+ color: #000;
+ background-color: #ffc107;
+ border-color: #ffc107;
+}
+.btn-warning:hover {
+ color: #000;
+ background-color: #ffca2c;
+ border-color: #ffc720;
+}
+.btn-check:focus + .btn-warning,
+.btn-warning:focus {
+ color: #000;
+ background-color: #ffca2c;
+ border-color: #ffc720;
+ box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);
+}
+.btn-check:active + .btn-warning,
+.btn-check:checked + .btn-warning,
+.btn-warning.active,
+.btn-warning:active,
+.show > .btn-warning.dropdown-toggle {
+ color: #000;
+ background-color: #ffcd39;
+ border-color: #ffc720;
+}
+.btn-check:active + .btn-warning:focus,
+.btn-check:checked + .btn-warning:focus,
+.btn-warning.active:focus,
+.btn-warning:active:focus,
+.show > .btn-warning.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(217, 164, 6, 0.5);
+}
+.btn-warning.disabled,
+.btn-warning:disabled {
+ color: #000;
+ background-color: #ffc107;
+ border-color: #ffc107;
+}
+.btn-danger {
+ color: #fff;
+ background-color: #dc3545;
+ border-color: #dc3545;
+}
+.btn-danger:hover {
+ color: #fff;
+ background-color: #bb2d3b;
+ border-color: #b02a37;
+}
+.btn-check:focus + .btn-danger,
+.btn-danger:focus {
+ color: #fff;
+ background-color: #bb2d3b;
+ border-color: #b02a37;
+ box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);
+}
+.btn-check:active + .btn-danger,
+.btn-check:checked + .btn-danger,
+.btn-danger.active,
+.btn-danger:active,
+.show > .btn-danger.dropdown-toggle {
+ color: #fff;
+ background-color: #b02a37;
+ border-color: #a52834;
+}
+.btn-check:active + .btn-danger:focus,
+.btn-check:checked + .btn-danger:focus,
+.btn-danger.active:focus,
+.btn-danger:active:focus,
+.show > .btn-danger.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(225, 83, 97, 0.5);
+}
+.btn-danger.disabled,
+.btn-danger:disabled {
+ color: #fff;
+ background-color: #dc3545;
+ border-color: #dc3545;
+}
+.btn-light {
+ color: #000;
+ background-color: #f8f9fa;
+ border-color: #f8f9fa;
+}
+.btn-light:hover {
+ color: #000;
+ background-color: #f9fafb;
+ border-color: #f9fafb;
+}
+.btn-check:focus + .btn-light,
+.btn-light:focus {
+ color: #000;
+ background-color: #f9fafb;
+ border-color: #f9fafb;
+ box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);
+}
+.btn-check:active + .btn-light,
+.btn-check:checked + .btn-light,
+.btn-light.active,
+.btn-light:active,
+.show > .btn-light.dropdown-toggle {
+ color: #000;
+ background-color: #f9fafb;
+ border-color: #f9fafb;
+}
+.btn-check:active + .btn-light:focus,
+.btn-check:checked + .btn-light:focus,
+.btn-light.active:focus,
+.btn-light:active:focus,
+.show > .btn-light.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(211, 212, 213, 0.5);
+}
+.btn-light.disabled,
+.btn-light:disabled {
+ color: #000;
+ background-color: #f8f9fa;
+ border-color: #f8f9fa;
+}
+.btn-dark {
+ color: #fff;
+ background-color: #212529;
+ border-color: #212529;
+}
+.btn-dark:hover {
+ color: #fff;
+ background-color: #1c1f23;
+ border-color: #1a1e21;
+}
+.btn-check:focus + .btn-dark,
+.btn-dark:focus {
+ color: #fff;
+ background-color: #1c1f23;
+ border-color: #1a1e21;
+ box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);
+}
+.btn-check:active + .btn-dark,
+.btn-check:checked + .btn-dark,
+.btn-dark.active,
+.btn-dark:active,
+.show > .btn-dark.dropdown-toggle {
+ color: #fff;
+ background-color: #1a1e21;
+ border-color: #191c1f;
+}
+.btn-check:active + .btn-dark:focus,
+.btn-check:checked + .btn-dark:focus,
+.btn-dark.active:focus,
+.btn-dark:active:focus,
+.show > .btn-dark.dropdown-toggle:focus {
+ box-shadow: 0 0 0 0.25rem rgba(66, 70, 73, 0.5);
+}
+.btn-dark.disabled,
+.btn-dark:disabled {
+ color: #fff;
+ background-color: #212529;
+ border-color: #212529;
+}
+.btn-outline-primary {
+ color: #0d6efd;
+ border-color: #0d6efd;
+}
+.btn-outline-primary:hover {
+ color: #fff;
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+.btn-check:focus + .btn-outline-primary,
+.btn-outline-primary:focus {
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);
+}
+.btn-check:active + .btn-outline-primary,
+.btn-check:checked + .btn-outline-primary,
+.btn-outline-primary.active,
+.btn-outline-primary.dropdown-toggle.show,
+.btn-outline-primary:active {
+ color: #fff;
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+.btn-check:active + .btn-outline-primary:focus,
+.btn-check:checked + .btn-outline-primary:focus,
+.btn-outline-primary.active:focus,
+.btn-outline-primary.dropdown-toggle.show:focus,
+.btn-outline-primary:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.5);
+}
+.btn-outline-primary.disabled,
+.btn-outline-primary:disabled {
+ color: #0d6efd;
+ background-color: transparent;
+}
+.btn-outline-secondary {
+ color: #6c757d;
+ border-color: #6c757d;
+}
+.btn-outline-secondary:hover {
+ color: #fff;
+ background-color: #6c757d;
+ border-color: #6c757d;
+}
+.btn-check:focus + .btn-outline-secondary,
+.btn-outline-secondary:focus {
+ box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);
+}
+.btn-check:active + .btn-outline-secondary,
+.btn-check:checked + .btn-outline-secondary,
+.btn-outline-secondary.active,
+.btn-outline-secondary.dropdown-toggle.show,
+.btn-outline-secondary:active {
+ color: #fff;
+ background-color: #6c757d;
+ border-color: #6c757d;
+}
+.btn-check:active + .btn-outline-secondary:focus,
+.btn-check:checked + .btn-outline-secondary:focus,
+.btn-outline-secondary.active:focus,
+.btn-outline-secondary.dropdown-toggle.show:focus,
+.btn-outline-secondary:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(108, 117, 125, 0.5);
+}
+.btn-outline-secondary.disabled,
+.btn-outline-secondary:disabled {
+ color: #6c757d;
+ background-color: transparent;
+}
+.btn-outline-success {
+ color: #198754;
+ border-color: #198754;
+}
+.btn-outline-success:hover {
+ color: #fff;
+ background-color: #198754;
+ border-color: #198754;
+}
+.btn-check:focus + .btn-outline-success,
+.btn-outline-success:focus {
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);
+}
+.btn-check:active + .btn-outline-success,
+.btn-check:checked + .btn-outline-success,
+.btn-outline-success.active,
+.btn-outline-success.dropdown-toggle.show,
+.btn-outline-success:active {
+ color: #fff;
+ background-color: #198754;
+ border-color: #198754;
+}
+.btn-check:active + .btn-outline-success:focus,
+.btn-check:checked + .btn-outline-success:focus,
+.btn-outline-success.active:focus,
+.btn-outline-success.dropdown-toggle.show:focus,
+.btn-outline-success:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(25, 135, 84, 0.5);
+}
+.btn-outline-success.disabled,
+.btn-outline-success:disabled {
+ color: #198754;
+ background-color: transparent;
+}
+.btn-outline-info {
+ color: #0dcaf0;
+ border-color: #0dcaf0;
+}
+.btn-outline-info:hover {
+ color: #000;
+ background-color: #0dcaf0;
+ border-color: #0dcaf0;
+}
+.btn-check:focus + .btn-outline-info,
+.btn-outline-info:focus {
+ box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);
+}
+.btn-check:active + .btn-outline-info,
+.btn-check:checked + .btn-outline-info,
+.btn-outline-info.active,
+.btn-outline-info.dropdown-toggle.show,
+.btn-outline-info:active {
+ color: #000;
+ background-color: #0dcaf0;
+ border-color: #0dcaf0;
+}
+.btn-check:active + .btn-outline-info:focus,
+.btn-check:checked + .btn-outline-info:focus,
+.btn-outline-info.active:focus,
+.btn-outline-info.dropdown-toggle.show:focus,
+.btn-outline-info:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(13, 202, 240, 0.5);
+}
+.btn-outline-info.disabled,
+.btn-outline-info:disabled {
+ color: #0dcaf0;
+ background-color: transparent;
+}
+.btn-outline-warning {
+ color: #ffc107;
+ border-color: #ffc107;
+}
+.btn-outline-warning:hover {
+ color: #000;
+ background-color: #ffc107;
+ border-color: #ffc107;
+}
+.btn-check:focus + .btn-outline-warning,
+.btn-outline-warning:focus {
+ box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);
+}
+.btn-check:active + .btn-outline-warning,
+.btn-check:checked + .btn-outline-warning,
+.btn-outline-warning.active,
+.btn-outline-warning.dropdown-toggle.show,
+.btn-outline-warning:active {
+ color: #000;
+ background-color: #ffc107;
+ border-color: #ffc107;
+}
+.btn-check:active + .btn-outline-warning:focus,
+.btn-check:checked + .btn-outline-warning:focus,
+.btn-outline-warning.active:focus,
+.btn-outline-warning.dropdown-toggle.show:focus,
+.btn-outline-warning:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(255, 193, 7, 0.5);
+}
+.btn-outline-warning.disabled,
+.btn-outline-warning:disabled {
+ color: #ffc107;
+ background-color: transparent;
+}
+.btn-outline-danger {
+ color: #dc3545;
+ border-color: #dc3545;
+}
+.btn-outline-danger:hover {
+ color: #fff;
+ background-color: #dc3545;
+ border-color: #dc3545;
+}
+.btn-check:focus + .btn-outline-danger,
+.btn-outline-danger:focus {
+ box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);
+}
+.btn-check:active + .btn-outline-danger,
+.btn-check:checked + .btn-outline-danger,
+.btn-outline-danger.active,
+.btn-outline-danger.dropdown-toggle.show,
+.btn-outline-danger:active {
+ color: #fff;
+ background-color: #dc3545;
+ border-color: #dc3545;
+}
+.btn-check:active + .btn-outline-danger:focus,
+.btn-check:checked + .btn-outline-danger:focus,
+.btn-outline-danger.active:focus,
+.btn-outline-danger.dropdown-toggle.show:focus,
+.btn-outline-danger:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.5);
+}
+.btn-outline-danger.disabled,
+.btn-outline-danger:disabled {
+ color: #dc3545;
+ background-color: transparent;
+}
+.btn-outline-light {
+ color: #f8f9fa;
+ border-color: #f8f9fa;
+}
+.btn-outline-light:hover {
+ color: #000;
+ background-color: #f8f9fa;
+ border-color: #f8f9fa;
+}
+.btn-check:focus + .btn-outline-light,
+.btn-outline-light:focus {
+ box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);
+}
+.btn-check:active + .btn-outline-light,
+.btn-check:checked + .btn-outline-light,
+.btn-outline-light.active,
+.btn-outline-light.dropdown-toggle.show,
+.btn-outline-light:active {
+ color: #000;
+ background-color: #f8f9fa;
+ border-color: #f8f9fa;
+}
+.btn-check:active + .btn-outline-light:focus,
+.btn-check:checked + .btn-outline-light:focus,
+.btn-outline-light.active:focus,
+.btn-outline-light.dropdown-toggle.show:focus,
+.btn-outline-light:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(248, 249, 250, 0.5);
+}
+.btn-outline-light.disabled,
+.btn-outline-light:disabled {
+ color: #f8f9fa;
+ background-color: transparent;
+}
+.btn-outline-dark {
+ color: #212529;
+ border-color: #212529;
+}
+.btn-outline-dark:hover {
+ color: #fff;
+ background-color: #212529;
+ border-color: #212529;
+}
+.btn-check:focus + .btn-outline-dark,
+.btn-outline-dark:focus {
+ box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);
+}
+.btn-check:active + .btn-outline-dark,
+.btn-check:checked + .btn-outline-dark,
+.btn-outline-dark.active,
+.btn-outline-dark.dropdown-toggle.show,
+.btn-outline-dark:active {
+ color: #fff;
+ background-color: #212529;
+ border-color: #212529;
+}
+.btn-check:active + .btn-outline-dark:focus,
+.btn-check:checked + .btn-outline-dark:focus,
+.btn-outline-dark.active:focus,
+.btn-outline-dark.dropdown-toggle.show:focus,
+.btn-outline-dark:active:focus {
+ box-shadow: 0 0 0 0.25rem rgba(33, 37, 41, 0.5);
+}
+.btn-outline-dark.disabled,
+.btn-outline-dark:disabled {
+ color: #212529;
+ background-color: transparent;
+}
+.btn-link {
+ font-weight: 400;
+ color: #0d6efd;
+ text-decoration: underline;
+}
+.btn-link:hover {
+ color: #0a58ca;
+}
+.btn-link.disabled,
+.btn-link:disabled {
+ color: #6c757d;
+}
+.btn-group-lg > .btn,
+.btn-lg {
+ padding: 0.5rem 1rem;
+ font-size: 1.25rem;
+ border-radius: 0.3rem;
+}
+.btn-group-sm > .btn,
+.btn-sm {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+ border-radius: 0.2rem;
+}
+.fade {
+ transition: opacity 0.15s linear;
+}
+@media (prefers-reduced-motion: reduce) {
+ .fade {
+ transition: none;
+ }
+}
+.fade:not(.show) {
+ opacity: 0;
+}
+.collapse:not(.show) {
+ display: none;
+}
+.collapsing {
+ height: 0;
+ overflow: hidden;
+ transition: height 0.35s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+ .collapsing {
+ transition: none;
+ }
+}
+.dropdown,
+.dropend,
+.dropstart,
+.dropup {
+ position: relative;
+}
+.dropdown-toggle {
+ white-space: nowrap;
+}
+.dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: '';
+ border-top: 0.3em solid;
+ border-right: 0.3em solid transparent;
+ border-bottom: 0;
+ border-left: 0.3em solid transparent;
+}
+.dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ z-index: 1000;
+ display: none;
+ min-width: 10rem;
+ padding: 0.5rem 0;
+ margin: 0;
+ font-size: 1rem;
+ color: #212529;
+ text-align: left;
+ list-style: none;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ border-radius: 0.25rem;
+}
+.dropdown-menu[data-bs-popper] {
+ left: 0;
+ margin-top: 0.125rem;
+}
+.dropdown-menu-start {
+ --bs-position: start;
+}
+.dropdown-menu-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+}
+.dropdown-menu-end {
+ --bs-position: end;
+}
+.dropdown-menu-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+}
+@media (min-width: 576px) {
+ .dropdown-menu-sm-start {
+ --bs-position: start;
+ }
+ .dropdown-menu-sm-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ .dropdown-menu-sm-end {
+ --bs-position: end;
+ }
+ .dropdown-menu-sm-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+@media (min-width: 768px) {
+ .dropdown-menu-md-start {
+ --bs-position: start;
+ }
+ .dropdown-menu-md-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ .dropdown-menu-md-end {
+ --bs-position: end;
+ }
+ .dropdown-menu-md-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+@media (min-width: 992px) {
+ .dropdown-menu-lg-start {
+ --bs-position: start;
+ }
+ .dropdown-menu-lg-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ .dropdown-menu-lg-end {
+ --bs-position: end;
+ }
+ .dropdown-menu-lg-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+@media (min-width: 1200px) {
+ .dropdown-menu-xl-start {
+ --bs-position: start;
+ }
+ .dropdown-menu-xl-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ .dropdown-menu-xl-end {
+ --bs-position: end;
+ }
+ .dropdown-menu-xl-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+@media (min-width: 1400px) {
+ .dropdown-menu-xxl-start {
+ --bs-position: start;
+ }
+ .dropdown-menu-xxl-start[data-bs-popper] {
+ right: auto;
+ left: 0;
+ }
+ .dropdown-menu-xxl-end {
+ --bs-position: end;
+ }
+ .dropdown-menu-xxl-end[data-bs-popper] {
+ right: 0;
+ left: auto;
+ }
+}
+.dropup .dropdown-menu[data-bs-popper] {
+ top: auto;
+ bottom: 100%;
+ margin-top: 0;
+ margin-bottom: 0.125rem;
+}
+.dropup .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: '';
+ border-top: 0;
+ border-right: 0.3em solid transparent;
+ border-bottom: 0.3em solid;
+ border-left: 0.3em solid transparent;
+}
+.dropup .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+.dropend .dropdown-menu {
+ top: 0;
+ right: auto;
+ left: 100%;
+}
+.dropend .dropdown-menu[data-bs-popper] {
+ margin-top: 0;
+ margin-left: 0.125rem;
+}
+.dropend .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: '';
+ border-top: 0.3em solid transparent;
+ border-right: 0;
+ border-bottom: 0.3em solid transparent;
+ border-left: 0.3em solid;
+}
+.dropend .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+.dropend .dropdown-toggle::after {
+ vertical-align: 0;
+}
+.dropstart .dropdown-menu {
+ top: 0;
+ right: 100%;
+ left: auto;
+}
+.dropstart .dropdown-menu[data-bs-popper] {
+ margin-top: 0;
+ margin-right: 0.125rem;
+}
+.dropstart .dropdown-toggle::after {
+ display: inline-block;
+ margin-left: 0.255em;
+ vertical-align: 0.255em;
+ content: '';
+}
+.dropstart .dropdown-toggle::after {
+ display: none;
+}
+.dropstart .dropdown-toggle::before {
+ display: inline-block;
+ margin-right: 0.255em;
+ vertical-align: 0.255em;
+ content: '';
+ border-top: 0.3em solid transparent;
+ border-right: 0.3em solid;
+ border-bottom: 0.3em solid transparent;
+}
+.dropstart .dropdown-toggle:empty::after {
+ margin-left: 0;
+}
+.dropstart .dropdown-toggle::before {
+ vertical-align: 0;
+}
+.dropdown-divider {
+ height: 0;
+ margin: 0.5rem 0;
+ overflow: hidden;
+ border-top: 1px solid rgba(0, 0, 0, 0.15);
+}
+.dropdown-item {
+ display: block;
+ width: 100%;
+ padding: 0.25rem 1rem;
+ clear: both;
+ font-weight: 400;
+ color: #212529;
+ text-align: inherit;
+ text-decoration: none;
+ white-space: nowrap;
+ background-color: transparent;
+ border: 0;
+}
+.dropdown-item:focus,
+.dropdown-item:hover {
+ color: #1e2125;
+ background-color: #e9ecef;
+}
+.dropdown-item.active,
+.dropdown-item:active {
+ color: #fff;
+ text-decoration: none;
+ background-color: #0d6efd;
+}
+.dropdown-item.disabled,
+.dropdown-item:disabled {
+ color: #adb5bd;
+ pointer-events: none;
+ background-color: transparent;
+}
+.dropdown-menu.show {
+ display: block;
+}
+.dropdown-header {
+ display: block;
+ padding: 0.5rem 1rem;
+ margin-bottom: 0;
+ font-size: 0.875rem;
+ color: #6c757d;
+ white-space: nowrap;
+}
+.dropdown-item-text {
+ display: block;
+ padding: 0.25rem 1rem;
+ color: #212529;
+}
+.dropdown-menu-dark {
+ color: #dee2e6;
+ background-color: #343a40;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+.dropdown-menu-dark .dropdown-item {
+ color: #dee2e6;
+}
+.dropdown-menu-dark .dropdown-item:focus,
+.dropdown-menu-dark .dropdown-item:hover {
+ color: #fff;
+ background-color: rgba(255, 255, 255, 0.15);
+}
+.dropdown-menu-dark .dropdown-item.active,
+.dropdown-menu-dark .dropdown-item:active {
+ color: #fff;
+ background-color: #0d6efd;
+}
+.dropdown-menu-dark .dropdown-item.disabled,
+.dropdown-menu-dark .dropdown-item:disabled {
+ color: #adb5bd;
+}
+.dropdown-menu-dark .dropdown-divider {
+ border-color: rgba(0, 0, 0, 0.15);
+}
+.dropdown-menu-dark .dropdown-item-text {
+ color: #dee2e6;
+}
+.dropdown-menu-dark .dropdown-header {
+ color: #adb5bd;
+}
+.btn-group,
+.btn-group-vertical {
+ position: relative;
+ display: inline-flex;
+ vertical-align: middle;
+}
+.btn-group-vertical > .btn,
+.btn-group > .btn {
+ position: relative;
+ flex: 1 1 auto;
+}
+.btn-group-vertical > .btn-check:checked + .btn,
+.btn-group-vertical > .btn-check:focus + .btn,
+.btn-group-vertical > .btn.active,
+.btn-group-vertical > .btn:active,
+.btn-group-vertical > .btn:focus,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn-check:checked + .btn,
+.btn-group > .btn-check:focus + .btn,
+.btn-group > .btn.active,
+.btn-group > .btn:active,
+.btn-group > .btn:focus,
+.btn-group > .btn:hover {
+ z-index: 1;
+}
+.btn-toolbar {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: flex-start;
+}
+.btn-toolbar .input-group {
+ width: auto;
+}
+.btn-group > .btn-group:not(:first-child),
+.btn-group > .btn:not(:first-child) {
+ margin-left: -1px;
+}
+.btn-group > .btn-group:not(:last-child) > .btn,
+.btn-group > .btn:not(:last-child):not(.dropdown-toggle) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+}
+.btn-group > .btn-group:not(:first-child) > .btn,
+.btn-group > .btn:nth-child(n + 3),
+.btn-group > :not(.btn-check) + .btn {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.dropdown-toggle-split {
+ padding-right: 0.5625rem;
+ padding-left: 0.5625rem;
+}
+.dropdown-toggle-split::after,
+.dropend .dropdown-toggle-split::after,
+.dropup .dropdown-toggle-split::after {
+ margin-left: 0;
+}
+.dropstart .dropdown-toggle-split::before {
+ margin-right: 0;
+}
+.btn-group-sm > .btn + .dropdown-toggle-split,
+.btn-sm + .dropdown-toggle-split {
+ padding-right: 0.375rem;
+ padding-left: 0.375rem;
+}
+.btn-group-lg > .btn + .dropdown-toggle-split,
+.btn-lg + .dropdown-toggle-split {
+ padding-right: 0.75rem;
+ padding-left: 0.75rem;
+}
+.btn-group-vertical {
+ flex-direction: column;
+ align-items: flex-start;
+ justify-content: center;
+}
+.btn-group-vertical > .btn,
+.btn-group-vertical > .btn-group {
+ width: 100%;
+}
+.btn-group-vertical > .btn-group:not(:first-child),
+.btn-group-vertical > .btn:not(:first-child) {
+ margin-top: -1px;
+}
+.btn-group-vertical > .btn-group:not(:last-child) > .btn,
+.btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle) {
+ border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
+}
+.btn-group-vertical > .btn-group:not(:first-child) > .btn,
+.btn-group-vertical > .btn ~ .btn {
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.nav {
+ display: flex;
+ flex-wrap: wrap;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.nav-link {
+ display: block;
+ padding: 0.5rem 1rem;
+ text-decoration: none;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .nav-link {
+ transition: none;
+ }
+}
+.nav-link.disabled {
+ color: #6c757d;
+ pointer-events: none;
+ cursor: default;
+}
+.nav-tabs {
+ border-bottom: 1px solid #dee2e6;
+}
+.nav-tabs .nav-link {
+ margin-bottom: -1px;
+ background: 0;
+ border: 1px solid transparent;
+ border-top-left-radius: 0.25rem;
+ border-top-right-radius: 0.25rem;
+}
+.nav-tabs .nav-link:focus,
+.nav-tabs .nav-link:hover {
+ border-color: #e9ecef #e9ecef #dee2e6;
+ isolation: isolate;
+}
+.nav-tabs .nav-link.disabled {
+ color: #6c757d;
+ background-color: transparent;
+ border-color: transparent;
+}
+.nav-tabs .nav-item.show .nav-link,
+.nav-tabs .nav-link.active {
+ color: #495057;
+ background-color: #fff;
+ border-color: #dee2e6 #dee2e6 #fff;
+}
+.nav-tabs .dropdown-menu {
+ margin-top: -1px;
+ border-top-left-radius: 0;
+ border-top-right-radius: 0;
+}
+.nav-pills .nav-link {
+ background: 0;
+ border: 0;
+ border-radius: 0.25rem;
+}
+.nav-pills .nav-link.active,
+.nav-pills .show > .nav-link {
+ color: #fff;
+ background-color: #0d6efd;
+}
+.nav-fill .nav-item,
+.nav-fill > .nav-link {
+ flex: 1 1 auto;
+ text-align: center;
+}
+.nav-justified .nav-item,
+.nav-justified > .nav-link {
+ flex-basis: 0;
+ flex-grow: 1;
+ text-align: center;
+}
+.nav-fill .nav-item .nav-link,
+.nav-justified .nav-item .nav-link {
+ width: 100%;
+}
+.tab-content > .tab-pane {
+ display: none;
+}
+.tab-content > .active {
+ display: block;
+}
+.navbar {
+ position: relative;
+ display: flex;
+ flex-wrap: wrap;
+ align-items: center;
+ justify-content: space-between;
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+.navbar > .container,
+.navbar > .container-fluid,
+.navbar > .container-lg,
+.navbar > .container-md,
+.navbar > .container-sm,
+.navbar > .container-xl,
+.navbar > .container-xxl {
+ display: flex;
+ flex-wrap: inherit;
+ align-items: center;
+ justify-content: space-between;
+}
+.navbar-brand {
+ padding-top: 0.3125rem;
+ padding-bottom: 0.3125rem;
+ margin-right: 1rem;
+ font-size: 1.25rem;
+ text-decoration: none;
+ white-space: nowrap;
+}
+.navbar-nav {
+ display: flex;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ list-style: none;
+}
+.navbar-nav .nav-link {
+ padding-right: 0;
+ padding-left: 0;
+}
+.navbar-nav .dropdown-menu {
+ position: static;
+}
+.navbar-text {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem;
+}
+.navbar-collapse {
+ flex-basis: 100%;
+ flex-grow: 1;
+ align-items: center;
+}
+.navbar-toggler {
+ padding: 0.25rem 0.75rem;
+ font-size: 1.25rem;
+ line-height: 1;
+ background-color: transparent;
+ border: 1px solid transparent;
+ border-radius: 0.25rem;
+ transition: box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .navbar-toggler {
+ transition: none;
+ }
+}
+.navbar-toggler:hover {
+ text-decoration: none;
+}
+.navbar-toggler:focus {
+ text-decoration: none;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem;
+}
+.navbar-toggler-icon {
+ display: inline-block;
+ width: 1.5em;
+ height: 1.5em;
+ vertical-align: middle;
+ background-repeat: no-repeat;
+ background-position: center;
+ background-size: 100%;
+}
+.navbar-nav-scroll {
+ max-height: var(--bs-scroll-height, 75vh);
+ overflow-y: auto;
+}
+@media (min-width: 576px) {
+ .navbar-expand-sm {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ }
+ .navbar-expand-sm .navbar-nav {
+ flex-direction: row;
+ }
+ .navbar-expand-sm .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+ .navbar-expand-sm .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
+ .navbar-expand-sm .navbar-nav-scroll {
+ overflow: visible;
+ }
+ .navbar-expand-sm .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+ }
+ .navbar-expand-sm .navbar-toggler {
+ display: none;
+ }
+}
+@media (min-width: 768px) {
+ .navbar-expand-md {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ }
+ .navbar-expand-md .navbar-nav {
+ flex-direction: row;
+ }
+ .navbar-expand-md .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+ .navbar-expand-md .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
+ .navbar-expand-md .navbar-nav-scroll {
+ overflow: visible;
+ }
+ .navbar-expand-md .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+ }
+ .navbar-expand-md .navbar-toggler {
+ display: none;
+ }
+}
+@media (min-width: 992px) {
+ .navbar-expand-lg {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ }
+ .navbar-expand-lg .navbar-nav {
+ flex-direction: row;
+ }
+ .navbar-expand-lg .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+ .navbar-expand-lg .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
+ .navbar-expand-lg .navbar-nav-scroll {
+ overflow: visible;
+ }
+ .navbar-expand-lg .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+ }
+ .navbar-expand-lg .navbar-toggler {
+ display: none;
+ }
+}
+@media (min-width: 1200px) {
+ .navbar-expand-xl {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ }
+ .navbar-expand-xl .navbar-nav {
+ flex-direction: row;
+ }
+ .navbar-expand-xl .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+ .navbar-expand-xl .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
+ .navbar-expand-xl .navbar-nav-scroll {
+ overflow: visible;
+ }
+ .navbar-expand-xl .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+ }
+ .navbar-expand-xl .navbar-toggler {
+ display: none;
+ }
+}
+@media (min-width: 1400px) {
+ .navbar-expand-xxl {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ }
+ .navbar-expand-xxl .navbar-nav {
+ flex-direction: row;
+ }
+ .navbar-expand-xxl .navbar-nav .dropdown-menu {
+ position: absolute;
+ }
+ .navbar-expand-xxl .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+ }
+ .navbar-expand-xxl .navbar-nav-scroll {
+ overflow: visible;
+ }
+ .navbar-expand-xxl .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+ }
+ .navbar-expand-xxl .navbar-toggler {
+ display: none;
+ }
+}
+.navbar-expand {
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+}
+.navbar-expand .navbar-nav {
+ flex-direction: row;
+}
+.navbar-expand .navbar-nav .dropdown-menu {
+ position: absolute;
+}
+.navbar-expand .navbar-nav .nav-link {
+ padding-right: 0.5rem;
+ padding-left: 0.5rem;
+}
+.navbar-expand .navbar-nav-scroll {
+ overflow: visible;
+}
+.navbar-expand .navbar-collapse {
+ display: flex !important;
+ flex-basis: auto;
+}
+.navbar-expand .navbar-toggler {
+ display: none;
+}
+.navbar-light .navbar-brand {
+ color: rgba(0, 0, 0, 0.9);
+}
+.navbar-light .navbar-brand:focus,
+.navbar-light .navbar-brand:hover {
+ color: rgba(0, 0, 0, 0.9);
+}
+.navbar-light .navbar-nav .nav-link {
+ color: rgba(0, 0, 0, 0.55);
+}
+.navbar-light .navbar-nav .nav-link:focus,
+.navbar-light .navbar-nav .nav-link:hover {
+ color: rgba(0, 0, 0, 0.7);
+}
+.navbar-light .navbar-nav .nav-link.disabled {
+ color: rgba(0, 0, 0, 0.3);
+}
+.navbar-light .navbar-nav .nav-link.active,
+.navbar-light .navbar-nav .show > .nav-link {
+ color: rgba(0, 0, 0, 0.9);
+}
+.navbar-light .navbar-toggler {
+ color: rgba(0, 0, 0, 0.55);
+ border-color: rgba(0, 0, 0, 0.1);
+}
+.navbar-light .navbar-toggler-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%280, 0, 0, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
+}
+.navbar-light .navbar-text {
+ color: rgba(0, 0, 0, 0.55);
+}
+.navbar-light .navbar-text a,
+.navbar-light .navbar-text a:focus,
+.navbar-light .navbar-text a:hover {
+ color: rgba(0, 0, 0, 0.9);
+}
+.navbar-dark .navbar-brand {
+ color: #fff;
+}
+.navbar-dark .navbar-brand:focus,
+.navbar-dark .navbar-brand:hover {
+ color: #fff;
+}
+.navbar-dark .navbar-nav .nav-link {
+ color: rgba(255, 255, 255, 0.55);
+}
+.navbar-dark .navbar-nav .nav-link:focus,
+.navbar-dark .navbar-nav .nav-link:hover {
+ color: rgba(255, 255, 255, 0.75);
+}
+.navbar-dark .navbar-nav .nav-link.disabled {
+ color: rgba(255, 255, 255, 0.25);
+}
+.navbar-dark .navbar-nav .nav-link.active,
+.navbar-dark .navbar-nav .show > .nav-link {
+ color: #fff;
+}
+.navbar-dark .navbar-toggler {
+ color: rgba(255, 255, 255, 0.55);
+ border-color: rgba(255, 255, 255, 0.1);
+}
+.navbar-dark .navbar-toggler-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255, 255, 255, 0.55%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
+}
+.navbar-dark .navbar-text {
+ color: rgba(255, 255, 255, 0.55);
+}
+.navbar-dark .navbar-text a,
+.navbar-dark .navbar-text a:focus,
+.navbar-dark .navbar-text a:hover {
+ color: #fff;
+}
+.card {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ min-width: 0;
+ word-wrap: break-word;
+ background-color: #fff;
+ background-clip: border-box;
+ border: 1px solid rgba(0, 0, 0, 0.125);
+ border-radius: 0.25rem;
+}
+.card > hr {
+ margin-right: 0;
+ margin-left: 0;
+}
+.card > .list-group {
+ border-top: inherit;
+ border-bottom: inherit;
+}
+.card > .list-group:first-child {
+ border-top-width: 0;
+ border-top-left-radius: calc(0.25rem - 1px);
+ border-top-right-radius: calc(0.25rem - 1px);
+}
+.card > .list-group:last-child {
+ border-bottom-width: 0;
+ border-bottom-right-radius: calc(0.25rem - 1px);
+ border-bottom-left-radius: calc(0.25rem - 1px);
+}
+.card > .card-header + .list-group,
+.card > .list-group + .card-footer {
+ border-top: 0;
+}
+.card-body {
+ flex: 1 1 auto;
+ padding: 1rem 1rem;
+}
+.card-title {
+ margin-bottom: 0.5rem;
+}
+.card-subtitle {
+ margin-top: -0.25rem;
+ margin-bottom: 0;
+}
+.card-text:last-child {
+ margin-bottom: 0;
+}
+.card-link:hover {
+ text-decoration: none;
+}
+.card-link + .card-link {
+ margin-left: 1rem;
+}
+.card-header {
+ padding: 0.5rem 1rem;
+ margin-bottom: 0;
+ background-color: rgba(0, 0, 0, 0.03);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.125);
+}
+.card-header:first-child {
+ border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
+}
+.card-footer {
+ padding: 0.5rem 1rem;
+ background-color: rgba(0, 0, 0, 0.03);
+ border-top: 1px solid rgba(0, 0, 0, 0.125);
+}
+.card-footer:last-child {
+ border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);
+}
+.card-header-tabs {
+ margin-right: -0.5rem;
+ margin-bottom: -0.5rem;
+ margin-left: -0.5rem;
+ border-bottom: 0;
+}
+.card-header-pills {
+ margin-right: -0.5rem;
+ margin-left: -0.5rem;
+}
+.card-img-overlay {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: 1rem;
+ border-radius: calc(0.25rem - 1px);
+}
+.card-img,
+.card-img-bottom,
+.card-img-top {
+ width: 100%;
+}
+.card-img,
+.card-img-top {
+ border-top-left-radius: calc(0.25rem - 1px);
+ border-top-right-radius: calc(0.25rem - 1px);
+}
+.card-img,
+.card-img-bottom {
+ border-bottom-right-radius: calc(0.25rem - 1px);
+ border-bottom-left-radius: calc(0.25rem - 1px);
+}
+.card-group > .card {
+ margin-bottom: 0.75rem;
+}
+@media (min-width: 576px) {
+ .card-group {
+ display: flex;
+ flex-flow: row wrap;
+ }
+ .card-group > .card {
+ flex: 1 0 0;
+ margin-bottom: 0;
+ }
+ .card-group > .card + .card {
+ margin-left: 0;
+ border-left: 0;
+ }
+ .card-group > .card:not(:last-child) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+ .card-group > .card:not(:last-child) .card-header,
+ .card-group > .card:not(:last-child) .card-img-top {
+ border-top-right-radius: 0;
+ }
+ .card-group > .card:not(:last-child) .card-footer,
+ .card-group > .card:not(:last-child) .card-img-bottom {
+ border-bottom-right-radius: 0;
+ }
+ .card-group > .card:not(:first-child) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+ .card-group > .card:not(:first-child) .card-header,
+ .card-group > .card:not(:first-child) .card-img-top {
+ border-top-left-radius: 0;
+ }
+ .card-group > .card:not(:first-child) .card-footer,
+ .card-group > .card:not(:first-child) .card-img-bottom {
+ border-bottom-left-radius: 0;
+ }
+}
+.accordion-button {
+ position: relative;
+ display: flex;
+ align-items: center;
+ width: 100%;
+ padding: 1rem 1.25rem;
+ font-size: 1rem;
+ color: #212529;
+ text-align: left;
+ background-color: #fff;
+ border: 0;
+ border-radius: 0;
+ overflow-anchor: none;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out,
+ border-radius 0.15s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+ .accordion-button {
+ transition: none;
+ }
+}
+.accordion-button:not(.collapsed) {
+ color: #0c63e4;
+ background-color: #e7f1ff;
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.125);
+}
+.accordion-button:not(.collapsed)::after {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%230c63e4'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+ transform: rotate(180deg);
+}
+.accordion-button::after {
+ flex-shrink: 0;
+ width: 1.25rem;
+ height: 1.25rem;
+ margin-left: auto;
+ content: '';
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23212529'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+ background-repeat: no-repeat;
+ background-size: 1.25rem;
+ transition: transform 0.2s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .accordion-button::after {
+ transition: none;
+ }
+}
+.accordion-button:hover {
+ z-index: 2;
+}
+.accordion-button:focus {
+ z-index: 3;
+ border-color: #86b7fe;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.accordion-header {
+ margin-bottom: 0;
+}
+.accordion-item {
+ margin-bottom: -1px;
+ background-color: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.125);
+}
+.accordion-item:first-of-type {
+ border-top-left-radius: 0.25rem;
+ border-top-right-radius: 0.25rem;
+}
+.accordion-item:first-of-type .accordion-button {
+ border-top-left-radius: calc(0.25rem - 1px);
+ border-top-right-radius: calc(0.25rem - 1px);
+}
+.accordion-item:last-of-type {
+ margin-bottom: 0;
+ border-bottom-right-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
+}
+.accordion-item:last-of-type .accordion-button.collapsed {
+ border-bottom-right-radius: calc(0.25rem - 1px);
+ border-bottom-left-radius: calc(0.25rem - 1px);
+}
+.accordion-item:last-of-type .accordion-collapse {
+ border-bottom-right-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
+}
+.accordion-body {
+ padding: 1rem 1.25rem;
+}
+.accordion-flush .accordion-collapse {
+ border-width: 0;
+}
+.accordion-flush .accordion-item {
+ border-right: 0;
+ border-left: 0;
+ border-radius: 0;
+}
+.accordion-flush .accordion-item:first-child {
+ border-top: 0;
+}
+.accordion-flush .accordion-item:last-child {
+ border-bottom: 0;
+}
+.accordion-flush .accordion-item .accordion-button {
+ border-radius: 0;
+}
+.breadcrumb {
+ display: flex;
+ flex-wrap: wrap;
+ padding: 0;
+ margin-bottom: 1rem;
+ list-style: none;
+}
+.breadcrumb-item + .breadcrumb-item {
+ padding-left: 0.5rem;
+}
+
+.breadcrumb-item.active {
+ color: #6c757d;
+}
+.pagination {
+ /* display: flex; */
+ padding-left: 0;
+ list-style: none;
+}
+.page-link {
+ position: relative;
+ display: block;
+ color: #0d6efd;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid #dee2e6;
+ transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .page-link {
+ transition: none;
+ }
+}
+.page-link:hover {
+ z-index: 2;
+ color: #0a58ca;
+ background-color: #e9ecef;
+ border-color: #dee2e6;
+}
+.page-link:focus {
+ z-index: 3;
+ color: #0a58ca;
+ background-color: #e9ecef;
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+}
+.page-item:not(:first-child) .page-link {
+ margin-left: -1px;
+}
+.page-item.active .page-link {
+ z-index: 3;
+ color: #fff;
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+.page-item.disabled .page-link {
+ color: #6c757d;
+ pointer-events: none;
+ background-color: #fff;
+ border-color: #dee2e6;
+}
+.page-link {
+ padding: 0.375rem 0.75rem;
+}
+.page-item:first-child .page-link {
+ border-top-left-radius: 0.25rem;
+ border-bottom-left-radius: 0.25rem;
+}
+.page-item:last-child .page-link {
+ border-top-right-radius: 0.25rem;
+ border-bottom-right-radius: 0.25rem;
+}
+.pagination-lg .page-link {
+ padding: 0.75rem 1.5rem;
+ font-size: 1.25rem;
+}
+.pagination-lg .page-item:first-child .page-link {
+ border-top-left-radius: 0.3rem;
+ border-bottom-left-radius: 0.3rem;
+}
+.pagination-lg .page-item:last-child .page-link {
+ border-top-right-radius: 0.3rem;
+ border-bottom-right-radius: 0.3rem;
+}
+.pagination-sm .page-link {
+ padding: 0.25rem 0.5rem;
+ font-size: 0.875rem;
+}
+.pagination-sm .page-item:first-child .page-link {
+ border-top-left-radius: 0.2rem;
+ border-bottom-left-radius: 0.2rem;
+}
+.pagination-sm .page-item:last-child .page-link {
+ border-top-right-radius: 0.2rem;
+ border-bottom-right-radius: 0.2rem;
+}
+.badge {
+ display: inline-block;
+ padding: 0.35em 0.65em;
+ font-size: 0.75em;
+ font-weight: 700;
+ line-height: 1;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ vertical-align: baseline;
+ border-radius: 0.25rem;
+}
+.badge:empty {
+ display: none;
+}
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+.alert {
+ position: relative;
+ padding: 1rem 1rem;
+ margin-bottom: 1rem;
+ border: 1px solid transparent;
+ border-radius: 0.25rem;
+}
+.alert-heading {
+ color: inherit;
+}
+.alert-link {
+ font-weight: 700;
+}
+.alert-dismissible {
+ padding-right: 3rem;
+}
+.alert-dismissible .btn-close {
+ position: absolute;
+ top: 0;
+ right: 0;
+ z-index: 2;
+ padding: 1.25rem 1rem;
+}
+.alert-primary {
+ color: #084298;
+ background-color: #cfe2ff;
+ border-color: #b6d4fe;
+}
+.alert-primary .alert-link {
+ color: #06357a;
+}
+.alert-secondary {
+ color: #41464b;
+ background-color: #e2e3e5;
+ border-color: #d3d6d8;
+}
+.alert-secondary .alert-link {
+ color: #34383c;
+}
+.alert-success {
+ color: #0f5132;
+ background-color: #d1e7dd;
+ border-color: #badbcc;
+}
+.alert-success .alert-link {
+ color: #0c4128;
+}
+.alert-info {
+ color: #055160;
+ background-color: #cff4fc;
+ border-color: #b6effb;
+}
+.alert-info .alert-link {
+ color: #04414d;
+}
+.alert-warning {
+ color: #664d03;
+ background-color: #fff3cd;
+ border-color: #ffecb5;
+}
+.alert-warning .alert-link {
+ color: #523e02;
+}
+.alert-danger {
+ color: #842029;
+ background-color: #f8d7da;
+ border-color: #f5c2c7;
+}
+.alert-danger .alert-link {
+ color: #6a1a21;
+}
+.alert-light {
+ color: #636464;
+ background-color: #fefefe;
+ border-color: #fdfdfe;
+}
+.alert-light .alert-link {
+ color: #4f5050;
+}
+.alert-dark {
+ color: #141619;
+ background-color: #d3d3d4;
+ border-color: #bcbebf;
+}
+.alert-dark .alert-link {
+ color: #101214;
+}
+@-webkit-keyframes progress-bar-stripes {
+ 0% {
+ background-position-x: 1rem;
+ }
+}
+@keyframes progress-bar-stripes {
+ 0% {
+ background-position-x: 1rem;
+ }
+}
+.progress {
+ display: flex;
+ height: 1rem;
+ overflow: hidden;
+ font-size: 0.75rem;
+ background-color: #e9ecef;
+ border-radius: 0.25rem;
+}
+.progress-bar {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ overflow: hidden;
+ color: #fff;
+ text-align: center;
+ white-space: nowrap;
+ background-color: #0d6efd;
+ transition: width 0.6s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+ .progress-bar {
+ transition: none;
+ }
+}
+.progress-bar-striped {
+ background-image: linear-gradient(
+ 45deg,
+ rgba(255, 255, 255, 0.15) 25%,
+ transparent 25%,
+ transparent 50%,
+ rgba(255, 255, 255, 0.15) 50%,
+ rgba(255, 255, 255, 0.15) 75%,
+ transparent 75%,
+ transparent
+ );
+ background-size: 1rem 1rem;
+}
+.progress-bar-animated {
+ -webkit-animation: 1s linear infinite progress-bar-stripes;
+ animation: 1s linear infinite progress-bar-stripes;
+}
+@media (prefers-reduced-motion: reduce) {
+ .progress-bar-animated {
+ -webkit-animation: none;
+ animation: none;
+ }
+}
+.list-group {
+ display: flex;
+ flex-direction: column;
+ padding-left: 0;
+ margin-bottom: 0;
+ border-radius: 0.25rem;
+}
+.list-group-numbered {
+ list-style-type: none;
+ counter-reset: section;
+}
+.list-group-numbered > li::before {
+ content: counters(section, '.') '. ';
+ counter-increment: section;
+}
+.list-group-item-action {
+ width: 100%;
+ color: #495057;
+ text-align: inherit;
+}
+.list-group-item-action:focus,
+.list-group-item-action:hover {
+ z-index: 1;
+ color: #495057;
+ text-decoration: none;
+ background-color: #f8f9fa;
+}
+.list-group-item-action:active {
+ color: #212529;
+ background-color: #e9ecef;
+}
+.list-group-item {
+ position: relative;
+ display: block;
+ padding: 0.5rem 1rem;
+ color: #212529;
+ text-decoration: none;
+ background-color: #fff;
+ border: 1px solid rgba(0, 0, 0, 0.125);
+}
+.list-group-item:first-child {
+ border-top-left-radius: inherit;
+ border-top-right-radius: inherit;
+}
+.list-group-item:last-child {
+ border-bottom-right-radius: inherit;
+ border-bottom-left-radius: inherit;
+}
+.list-group-item.disabled,
+.list-group-item:disabled {
+ color: #6c757d;
+ pointer-events: none;
+ background-color: #fff;
+}
+.list-group-item.active {
+ z-index: 2;
+ color: #fff;
+ background-color: #0d6efd;
+ border-color: #0d6efd;
+}
+.list-group-item + .list-group-item {
+ border-top-width: 0;
+}
+.list-group-item + .list-group-item.active {
+ margin-top: -1px;
+ border-top-width: 1px;
+}
+.list-group-horizontal {
+ flex-direction: row;
+}
+.list-group-horizontal > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+}
+.list-group-horizontal > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+}
+.list-group-horizontal > .list-group-item.active {
+ margin-top: 0;
+}
+.list-group-horizontal > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+}
+.list-group-horizontal > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+}
+@media (min-width: 576px) {
+ .list-group-horizontal-sm {
+ flex-direction: row;
+ }
+ .list-group-horizontal-sm > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ }
+ .list-group-horizontal-sm > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+ }
+ .list-group-horizontal-sm > .list-group-item.active {
+ margin-top: 0;
+ }
+ .list-group-horizontal-sm > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+ }
+ .list-group-horizontal-sm > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+ }
+}
+@media (min-width: 768px) {
+ .list-group-horizontal-md {
+ flex-direction: row;
+ }
+ .list-group-horizontal-md > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ }
+ .list-group-horizontal-md > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+ }
+ .list-group-horizontal-md > .list-group-item.active {
+ margin-top: 0;
+ }
+ .list-group-horizontal-md > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+ }
+ .list-group-horizontal-md > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+ }
+}
+@media (min-width: 992px) {
+ .list-group-horizontal-lg {
+ flex-direction: row;
+ }
+ .list-group-horizontal-lg > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ }
+ .list-group-horizontal-lg > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+ }
+ .list-group-horizontal-lg > .list-group-item.active {
+ margin-top: 0;
+ }
+ .list-group-horizontal-lg > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+ }
+ .list-group-horizontal-lg > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+ }
+}
+@media (min-width: 1200px) {
+ .list-group-horizontal-xl {
+ flex-direction: row;
+ }
+ .list-group-horizontal-xl > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ }
+ .list-group-horizontal-xl > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+ }
+ .list-group-horizontal-xl > .list-group-item.active {
+ margin-top: 0;
+ }
+ .list-group-horizontal-xl > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+ }
+ .list-group-horizontal-xl > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+ }
+}
+@media (min-width: 1400px) {
+ .list-group-horizontal-xxl {
+ flex-direction: row;
+ }
+ .list-group-horizontal-xxl > .list-group-item:first-child {
+ border-bottom-left-radius: 0.25rem;
+ border-top-right-radius: 0;
+ }
+ .list-group-horizontal-xxl > .list-group-item:last-child {
+ border-top-right-radius: 0.25rem;
+ border-bottom-left-radius: 0;
+ }
+ .list-group-horizontal-xxl > .list-group-item.active {
+ margin-top: 0;
+ }
+ .list-group-horizontal-xxl > .list-group-item + .list-group-item {
+ border-top-width: 1px;
+ border-left-width: 0;
+ }
+ .list-group-horizontal-xxl > .list-group-item + .list-group-item.active {
+ margin-left: -1px;
+ border-left-width: 1px;
+ }
+}
+.list-group-flush {
+ border-radius: 0;
+}
+.list-group-flush > .list-group-item {
+ border-width: 0 0 1px;
+}
+.list-group-flush > .list-group-item:last-child {
+ border-bottom-width: 0;
+}
+.list-group-item-primary {
+ color: #084298;
+ background-color: #cfe2ff;
+}
+.list-group-item-primary.list-group-item-action:focus,
+.list-group-item-primary.list-group-item-action:hover {
+ color: #084298;
+ background-color: #bacbe6;
+}
+.list-group-item-primary.list-group-item-action.active {
+ color: #fff;
+ background-color: #084298;
+ border-color: #084298;
+}
+.list-group-item-secondary {
+ color: #41464b;
+ background-color: #e2e3e5;
+}
+.list-group-item-secondary.list-group-item-action:focus,
+.list-group-item-secondary.list-group-item-action:hover {
+ color: #41464b;
+ background-color: #cbccce;
+}
+.list-group-item-secondary.list-group-item-action.active {
+ color: #fff;
+ background-color: #41464b;
+ border-color: #41464b;
+}
+.list-group-item-success {
+ color: #0f5132;
+ background-color: #d1e7dd;
+}
+.list-group-item-success.list-group-item-action:focus,
+.list-group-item-success.list-group-item-action:hover {
+ color: #0f5132;
+ background-color: #bcd0c7;
+}
+.list-group-item-success.list-group-item-action.active {
+ color: #fff;
+ background-color: #0f5132;
+ border-color: #0f5132;
+}
+.list-group-item-info {
+ color: #055160;
+ background-color: #cff4fc;
+}
+.list-group-item-info.list-group-item-action:focus,
+.list-group-item-info.list-group-item-action:hover {
+ color: #055160;
+ background-color: #badce3;
+}
+.list-group-item-info.list-group-item-action.active {
+ color: #fff;
+ background-color: #055160;
+ border-color: #055160;
+}
+.list-group-item-warning {
+ color: #664d03;
+ background-color: #fff3cd;
+}
+.list-group-item-warning.list-group-item-action:focus,
+.list-group-item-warning.list-group-item-action:hover {
+ color: #664d03;
+ background-color: #e6dbb9;
+}
+.list-group-item-warning.list-group-item-action.active {
+ color: #fff;
+ background-color: #664d03;
+ border-color: #664d03;
+}
+.list-group-item-danger {
+ color: #842029;
+ background-color: #f8d7da;
+}
+.list-group-item-danger.list-group-item-action:focus,
+.list-group-item-danger.list-group-item-action:hover {
+ color: #842029;
+ background-color: #dfc2c4;
+}
+.list-group-item-danger.list-group-item-action.active {
+ color: #fff;
+ background-color: #842029;
+ border-color: #842029;
+}
+.list-group-item-light {
+ color: #636464;
+ background-color: #fefefe;
+}
+.list-group-item-light.list-group-item-action:focus,
+.list-group-item-light.list-group-item-action:hover {
+ color: #636464;
+ background-color: #e5e5e5;
+}
+.list-group-item-light.list-group-item-action.active {
+ color: #fff;
+ background-color: #636464;
+ border-color: #636464;
+}
+.list-group-item-dark {
+ color: #141619;
+ background-color: #d3d3d4;
+}
+.list-group-item-dark.list-group-item-action:focus,
+.list-group-item-dark.list-group-item-action:hover {
+ color: #141619;
+ background-color: #bebebf;
+}
+.list-group-item-dark.list-group-item-action.active {
+ color: #fff;
+ background-color: #141619;
+ border-color: #141619;
+}
+.btn-close {
+ box-sizing: content-box;
+ width: 1em;
+ height: 1em;
+ padding: 0.25em 0.25em;
+ color: #000;
+ background: transparent
+ url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23000'%3e%3cpath d='M.293.293a1 1 0 011.414 0L8 6.586 14.293.293a1 1 0 111.414 1.414L9.414 8l6.293 6.293a1 1 0 01-1.414 1.414L8 9.414l-6.293 6.293a1 1 0 01-1.414-1.414L6.586 8 .293 1.707a1 1 0 010-1.414z'/%3e%3c/svg%3e")
+ center/1em auto no-repeat;
+ border: 0;
+ border-radius: 0.25rem;
+ opacity: 0.5;
+}
+.btn-close:hover {
+ color: #000;
+ text-decoration: none;
+ opacity: 0.75;
+}
+.btn-close:focus {
+ outline: 0;
+ box-shadow: 0 0 0 0.25rem rgba(13, 110, 253, 0.25);
+ opacity: 1;
+}
+.btn-close.disabled,
+.btn-close:disabled {
+ pointer-events: none;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ user-select: none;
+ opacity: 0.25;
+}
+.btn-close-white {
+ filter: invert(1) grayscale(100%) brightness(200%);
+}
+.toast {
+ width: 350px;
+ max-width: 100%;
+ font-size: 0.875rem;
+ pointer-events: auto;
+ background-color: rgba(255, 255, 255, 0.85);
+ background-clip: padding-box;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15);
+ border-radius: 0.25rem;
+}
+.toast:not(.showing):not(.show) {
+ opacity: 0;
+}
+.toast.hide {
+ display: none;
+}
+.toast-container {
+ width: -webkit-max-content;
+ width: -moz-max-content;
+ width: max-content;
+ max-width: 100%;
+ pointer-events: none;
+}
+.toast-container > :not(:last-child) {
+ margin-bottom: 0.75rem;
+}
+.toast-header {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem 0.75rem;
+ color: #6c757d;
+ background-color: rgba(255, 255, 255, 0.85);
+ background-clip: padding-box;
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
+ border-top-left-radius: calc(0.25rem - 1px);
+ border-top-right-radius: calc(0.25rem - 1px);
+}
+.toast-header .btn-close {
+ margin-right: -0.375rem;
+ margin-left: 0.75rem;
+}
+.toast-body {
+ padding: 0.75rem;
+ word-wrap: break-word;
+}
+.modal-open {
+ overflow: hidden;
+}
+.modal-open .modal {
+ overflow-x: hidden;
+ overflow-y: auto;
+}
+.modal {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1060;
+ display: none;
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+ outline: 0;
+}
+.modal-dialog {
+ position: relative;
+ width: auto;
+ margin: 0.5rem;
+ pointer-events: none;
+}
+.modal.fade .modal-dialog {
+ transition: transform 0.3s ease-out;
+ transform: translate(0, -50px);
+}
+@media (prefers-reduced-motion: reduce) {
+ .modal.fade .modal-dialog {
+ transition: none;
+ }
+}
+.modal.show .modal-dialog {
+ transform: none;
+}
+.modal.modal-static .modal-dialog {
+ transform: scale(1.02);
+}
+.modal-dialog-scrollable {
+ height: calc(100% - 1rem);
+}
+.modal-dialog-scrollable .modal-content {
+ max-height: 100%;
+ overflow: hidden;
+}
+.modal-dialog-scrollable .modal-body {
+ overflow-y: auto;
+}
+.modal-dialog-centered {
+ display: flex;
+ align-items: center;
+ min-height: calc(100% - 1rem);
+}
+.modal-content {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ pointer-events: auto;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 0.3rem;
+ outline: 0;
+}
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1050;
+ width: 100vw;
+ height: 100vh;
+ background-color: #000;
+}
+.modal-backdrop.fade {
+ opacity: 0;
+}
+.modal-backdrop.show {
+ opacity: 0.5;
+}
+.modal-header {
+ display: flex;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: space-between;
+ padding: 1rem 1rem;
+ border-bottom: 1px solid #dee2e6;
+ border-top-left-radius: calc(0.3rem - 1px);
+ border-top-right-radius: calc(0.3rem - 1px);
+}
+.modal-header .btn-close {
+ padding: 0.5rem 0.5rem;
+ margin: -0.5rem -0.5rem -0.5rem auto;
+}
+.modal-title {
+ margin-bottom: 0;
+ line-height: 1.5;
+}
+.modal-body {
+ position: relative;
+ flex: 1 1 auto;
+ padding: 1rem;
+}
+.modal-footer {
+ display: flex;
+ flex-wrap: wrap;
+ flex-shrink: 0;
+ align-items: center;
+ justify-content: flex-end;
+ padding: 0.75rem;
+ border-top: 1px solid #dee2e6;
+ border-bottom-right-radius: calc(0.3rem - 1px);
+ border-bottom-left-radius: calc(0.3rem - 1px);
+}
+.modal-footer > * {
+ margin: 0.25rem;
+}
+.modal-scrollbar-measure {
+ position: absolute;
+ top: -9999px;
+ width: 50px;
+ height: 50px;
+ overflow: scroll;
+}
+@media (min-width: 576px) {
+ .modal-dialog {
+ max-width: 500px;
+ margin: 1.75rem auto;
+ }
+ .modal-dialog-scrollable {
+ height: calc(100% - 3.5rem);
+ }
+ .modal-dialog-centered {
+ min-height: calc(100% - 3.5rem);
+ }
+ .modal-sm {
+ max-width: 300px;
+ }
+}
+@media (min-width: 992px) {
+ .modal-lg,
+ .modal-xl {
+ max-width: 800px;
+ }
+}
+@media (min-width: 1200px) {
+ .modal-xl {
+ max-width: 1140px;
+ }
+}
+.modal-fullscreen {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+}
+.modal-fullscreen .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+}
+.modal-fullscreen .modal-header {
+ border-radius: 0;
+}
+.modal-fullscreen .modal-body {
+ overflow-y: auto;
+}
+.modal-fullscreen .modal-footer {
+ border-radius: 0;
+}
+@media (max-width: 575.98px) {
+ .modal-fullscreen-sm-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+ .modal-fullscreen-sm-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+ .modal-fullscreen-sm-down .modal-header {
+ border-radius: 0;
+ }
+ .modal-fullscreen-sm-down .modal-body {
+ overflow-y: auto;
+ }
+ .modal-fullscreen-sm-down .modal-footer {
+ border-radius: 0;
+ }
+}
+@media (max-width: 767.98px) {
+ .modal-fullscreen-md-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+ .modal-fullscreen-md-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+ .modal-fullscreen-md-down .modal-header {
+ border-radius: 0;
+ }
+ .modal-fullscreen-md-down .modal-body {
+ overflow-y: auto;
+ }
+ .modal-fullscreen-md-down .modal-footer {
+ border-radius: 0;
+ }
+}
+@media (max-width: 991.98px) {
+ .modal-fullscreen-lg-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+ .modal-fullscreen-lg-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+ .modal-fullscreen-lg-down .modal-header {
+ border-radius: 0;
+ }
+ .modal-fullscreen-lg-down .modal-body {
+ overflow-y: auto;
+ }
+ .modal-fullscreen-lg-down .modal-footer {
+ border-radius: 0;
+ }
+}
+@media (max-width: 1199.98px) {
+ .modal-fullscreen-xl-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+ .modal-fullscreen-xl-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+ .modal-fullscreen-xl-down .modal-header {
+ border-radius: 0;
+ }
+ .modal-fullscreen-xl-down .modal-body {
+ overflow-y: auto;
+ }
+ .modal-fullscreen-xl-down .modal-footer {
+ border-radius: 0;
+ }
+}
+@media (max-width: 1399.98px) {
+ .modal-fullscreen-xxl-down {
+ width: 100vw;
+ max-width: none;
+ height: 100%;
+ margin: 0;
+ }
+ .modal-fullscreen-xxl-down .modal-content {
+ height: 100%;
+ border: 0;
+ border-radius: 0;
+ }
+ .modal-fullscreen-xxl-down .modal-header {
+ border-radius: 0;
+ }
+ .modal-fullscreen-xxl-down .modal-body {
+ overflow-y: auto;
+ }
+ .modal-fullscreen-xxl-down .modal-footer {
+ border-radius: 0;
+ }
+}
+.tooltip {
+ position: absolute;
+ z-index: 1080;
+ display: block;
+ margin: 0;
+ font-family: var(--bs-font-sans-serif);
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ white-space: normal;
+ line-break: auto;
+ font-size: 0.875rem;
+ word-wrap: break-word;
+ opacity: 0;
+}
+.tooltip.show {
+ opacity: 0.9;
+}
+.tooltip .tooltip-arrow {
+ position: absolute;
+ display: block;
+ width: 0.8rem;
+ height: 0.4rem;
+}
+.tooltip .tooltip-arrow::before {
+ position: absolute;
+ content: '';
+ border-color: transparent;
+ border-style: solid;
+}
+.bs-tooltip-auto[data-popper-placement^='top'],
+.bs-tooltip-top {
+ padding: 0.4rem 0;
+}
+.bs-tooltip-auto[data-popper-placement^='top'] .tooltip-arrow,
+.bs-tooltip-top .tooltip-arrow {
+ bottom: 0;
+}
+.bs-tooltip-auto[data-popper-placement^='top'] .tooltip-arrow::before,
+.bs-tooltip-top .tooltip-arrow::before {
+ top: -1px;
+ border-width: 0.4rem 0.4rem 0;
+ border-top-color: #000;
+}
+.bs-tooltip-auto[data-popper-placement^='right'],
+.bs-tooltip-end {
+ padding: 0 0.4rem;
+}
+.bs-tooltip-auto[data-popper-placement^='right'] .tooltip-arrow,
+.bs-tooltip-end .tooltip-arrow {
+ left: 0;
+ width: 0.4rem;
+ height: 0.8rem;
+}
+.bs-tooltip-auto[data-popper-placement^='right'] .tooltip-arrow::before,
+.bs-tooltip-end .tooltip-arrow::before {
+ right: -1px;
+ border-width: 0.4rem 0.4rem 0.4rem 0;
+ border-right-color: #000;
+}
+.bs-tooltip-auto[data-popper-placement^='bottom'],
+.bs-tooltip-bottom {
+ padding: 0.4rem 0;
+}
+.bs-tooltip-auto[data-popper-placement^='bottom'] .tooltip-arrow,
+.bs-tooltip-bottom .tooltip-arrow {
+ top: 0;
+}
+.bs-tooltip-auto[data-popper-placement^='bottom'] .tooltip-arrow::before,
+.bs-tooltip-bottom .tooltip-arrow::before {
+ bottom: -1px;
+ border-width: 0 0.4rem 0.4rem;
+ border-bottom-color: #000;
+}
+.bs-tooltip-auto[data-popper-placement^='left'],
+.bs-tooltip-start {
+ padding: 0 0.4rem;
+}
+.bs-tooltip-auto[data-popper-placement^='left'] .tooltip-arrow,
+.bs-tooltip-start .tooltip-arrow {
+ right: 0;
+ width: 0.4rem;
+ height: 0.8rem;
+}
+.bs-tooltip-auto[data-popper-placement^='left'] .tooltip-arrow::before,
+.bs-tooltip-start .tooltip-arrow::before {
+ left: -1px;
+ border-width: 0.4rem 0 0.4rem 0.4rem;
+ border-left-color: #000;
+}
+.tooltip-inner {
+ max-width: 200px;
+ padding: 0.25rem 0.5rem;
+ color: #fff;
+ text-align: center;
+ background-color: #000;
+ border-radius: 0.25rem;
+}
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1070;
+ display: block;
+ max-width: 276px;
+ font-family: var(--bs-font-sans-serif);
+ font-style: normal;
+ font-weight: 400;
+ line-height: 1.5;
+ text-align: left;
+ text-align: start;
+ text-decoration: none;
+ text-shadow: none;
+ text-transform: none;
+ letter-spacing: normal;
+ word-break: normal;
+ word-spacing: normal;
+ white-space: normal;
+ line-break: auto;
+ font-size: 0.875rem;
+ word-wrap: break-word;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ border-radius: 0.3rem;
+}
+.popover .popover-arrow {
+ position: absolute;
+ display: block;
+ width: 1rem;
+ height: 0.5rem;
+}
+.popover .popover-arrow::after,
+.popover .popover-arrow::before {
+ position: absolute;
+ display: block;
+ content: '';
+ border-color: transparent;
+ border-style: solid;
+}
+.bs-popover-auto[data-popper-placement^='top'] > .popover-arrow,
+.bs-popover-top > .popover-arrow {
+ bottom: calc(-0.5rem - 1px);
+}
+.bs-popover-auto[data-popper-placement^='top'] > .popover-arrow::before,
+.bs-popover-top > .popover-arrow::before {
+ bottom: 0;
+ border-width: 0.5rem 0.5rem 0;
+ border-top-color: rgba(0, 0, 0, 0.25);
+}
+.bs-popover-auto[data-popper-placement^='top'] > .popover-arrow::after,
+.bs-popover-top > .popover-arrow::after {
+ bottom: 1px;
+ border-width: 0.5rem 0.5rem 0;
+ border-top-color: #fff;
+}
+.bs-popover-auto[data-popper-placement^='right'] > .popover-arrow,
+.bs-popover-end > .popover-arrow {
+ left: calc(-0.5rem - 1px);
+ width: 0.5rem;
+ height: 1rem;
+}
+.bs-popover-auto[data-popper-placement^='right'] > .popover-arrow::before,
+.bs-popover-end > .popover-arrow::before {
+ left: 0;
+ border-width: 0.5rem 0.5rem 0.5rem 0;
+ border-right-color: rgba(0, 0, 0, 0.25);
+}
+.bs-popover-auto[data-popper-placement^='right'] > .popover-arrow::after,
+.bs-popover-end > .popover-arrow::after {
+ left: 1px;
+ border-width: 0.5rem 0.5rem 0.5rem 0;
+ border-right-color: #fff;
+}
+.bs-popover-auto[data-popper-placement^='bottom'] > .popover-arrow,
+.bs-popover-bottom > .popover-arrow {
+ top: calc(-0.5rem - 1px);
+}
+.bs-popover-auto[data-popper-placement^='bottom'] > .popover-arrow::before,
+.bs-popover-bottom > .popover-arrow::before {
+ top: 0;
+ border-width: 0 0.5rem 0.5rem 0.5rem;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+}
+.bs-popover-auto[data-popper-placement^='bottom'] > .popover-arrow::after,
+.bs-popover-bottom > .popover-arrow::after {
+ top: 1px;
+ border-width: 0 0.5rem 0.5rem 0.5rem;
+ border-bottom-color: #fff;
+}
+.bs-popover-auto[data-popper-placement^='bottom'] .popover-header::before,
+.bs-popover-bottom .popover-header::before {
+ position: absolute;
+ top: 0;
+ left: 50%;
+ display: block;
+ width: 1rem;
+ margin-left: -0.5rem;
+ content: '';
+ border-bottom: 1px solid #f0f0f0;
+}
+.bs-popover-auto[data-popper-placement^='left'] > .popover-arrow,
+.bs-popover-start > .popover-arrow {
+ right: calc(-0.5rem - 1px);
+ width: 0.5rem;
+ height: 1rem;
+}
+.bs-popover-auto[data-popper-placement^='left'] > .popover-arrow::before,
+.bs-popover-start > .popover-arrow::before {
+ right: 0;
+ border-width: 0.5rem 0 0.5rem 0.5rem;
+ border-left-color: rgba(0, 0, 0, 0.25);
+}
+.bs-popover-auto[data-popper-placement^='left'] > .popover-arrow::after,
+.bs-popover-start > .popover-arrow::after {
+ right: 1px;
+ border-width: 0.5rem 0 0.5rem 0.5rem;
+ border-left-color: #fff;
+}
+.popover-header {
+ padding: 0.5rem 1rem;
+ margin-bottom: 0;
+ font-size: 1rem;
+ background-color: #f0f0f0;
+ border-bottom: 1px solid #d8d8d8;
+ border-top-left-radius: calc(0.3rem - 1px);
+ border-top-right-radius: calc(0.3rem - 1px);
+}
+.popover-header:empty {
+ display: none;
+}
+.popover-body {
+ padding: 1rem 1rem;
+ color: #212529;
+}
+.carousel {
+ position: relative;
+}
+.carousel.pointer-event {
+ touch-action: pan-y;
+}
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+.carousel-inner::after {
+ display: block;
+ clear: both;
+ content: '';
+}
+.carousel-item {
+ position: relative;
+ display: none;
+ float: left;
+ width: 100%;
+ margin-right: -100%;
+ -webkit-backface-visibility: hidden;
+ backface-visibility: hidden;
+ transition: transform 0.6s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .carousel-item {
+ transition: none;
+ }
+}
+.carousel-item-next,
+.carousel-item-prev,
+.carousel-item.active {
+ display: block;
+}
+.active.carousel-item-end,
+.carousel-item-next:not(.carousel-item-start) {
+ transform: translateX(100%);
+}
+.active.carousel-item-start,
+.carousel-item-prev:not(.carousel-item-end) {
+ transform: translateX(-100%);
+}
+.carousel-fade .carousel-item {
+ opacity: 0;
+ transition-property: opacity;
+ transform: none;
+}
+.carousel-fade .carousel-item-next.carousel-item-start,
+.carousel-fade .carousel-item-prev.carousel-item-end,
+.carousel-fade .carousel-item.active {
+ z-index: 1;
+ opacity: 1;
+}
+.carousel-fade .active.carousel-item-end,
+.carousel-fade .active.carousel-item-start {
+ z-index: 0;
+ opacity: 0;
+ transition: opacity 0s 0.6s;
+}
+@media (prefers-reduced-motion: reduce) {
+ .carousel-fade .active.carousel-item-end,
+ .carousel-fade .active.carousel-item-start {
+ transition: none;
+ }
+}
+.carousel-control-next,
+.carousel-control-prev {
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ z-index: 1;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 15%;
+ padding: 0;
+ color: #fff;
+ text-align: center;
+ background: 0;
+ border: 0;
+ opacity: 0.5;
+ transition: opacity 0.15s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+ .carousel-control-next,
+ .carousel-control-prev {
+ transition: none;
+ }
+}
+.carousel-control-next:focus,
+.carousel-control-next:hover,
+.carousel-control-prev:focus,
+.carousel-control-prev:hover {
+ color: #fff;
+ text-decoration: none;
+ outline: 0;
+ opacity: 0.9;
+}
+.carousel-control-prev {
+ left: 0;
+}
+.carousel-control-next {
+ right: 0;
+}
+.carousel-control-next-icon,
+.carousel-control-prev-icon {
+ display: inline-block;
+ width: 2rem;
+ height: 2rem;
+ background-repeat: no-repeat;
+ background-position: 50%;
+ background-size: 100% 100%;
+}
+.carousel-control-prev-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z'/%3e%3c/svg%3e");
+}
+.carousel-control-next-icon {
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23fff'%3e%3cpath d='M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
+}
+.carousel-indicators {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 2;
+ display: flex;
+ justify-content: center;
+ padding: 0;
+ margin-right: 15%;
+ margin-bottom: 1rem;
+ margin-left: 15%;
+ list-style: none;
+}
+.carousel-indicators [data-bs-target] {
+ box-sizing: content-box;
+ flex: 0 1 auto;
+ width: 30px;
+ height: 3px;
+ padding: 0;
+ margin-right: 3px;
+ margin-left: 3px;
+ text-indent: -999px;
+ cursor: pointer;
+ background-color: #fff;
+ background-clip: padding-box;
+ border: 0;
+ border-top: 10px solid transparent;
+ border-bottom: 10px solid transparent;
+ opacity: 0.5;
+ transition: opacity 0.6s ease;
+}
+@media (prefers-reduced-motion: reduce) {
+ .carousel-indicators [data-bs-target] {
+ transition: none;
+ }
+}
+.carousel-indicators .active {
+ opacity: 1;
+}
+.carousel-caption {
+ position: absolute;
+ right: 15%;
+ bottom: 1.25rem;
+ left: 15%;
+ padding-top: 1.25rem;
+ padding-bottom: 1.25rem;
+ color: #fff;
+ text-align: center;
+}
+.carousel-dark .carousel-control-next-icon,
+.carousel-dark .carousel-control-prev-icon {
+ filter: invert(1) grayscale(100);
+}
+.carousel-dark .carousel-indicators [data-bs-target] {
+ background-color: #000;
+}
+.carousel-dark .carousel-caption {
+ color: #000;
+}
+@-webkit-keyframes spinner-border {
+ to {
+ transform: rotate(360deg);
+ }
+}
+@keyframes spinner-border {
+ to {
+ transform: rotate(360deg);
+ }
+}
+.spinner-border {
+ display: inline-block;
+ width: 2rem;
+ height: 2rem;
+ vertical-align: text-bottom;
+ border: 0.25em solid currentColor;
+ border-right-color: transparent;
+ border-radius: 50%;
+ -webkit-animation: 0.75s linear infinite spinner-border;
+ animation: 0.75s linear infinite spinner-border;
+}
+.spinner-border-sm {
+ width: 1rem;
+ height: 1rem;
+ border-width: 0.2em;
+}
+@-webkit-keyframes spinner-grow {
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ opacity: 1;
+ transform: none;
+ }
+}
+@keyframes spinner-grow {
+ 0% {
+ transform: scale(0);
+ }
+ 50% {
+ opacity: 1;
+ transform: none;
+ }
+}
+.spinner-grow {
+ display: inline-block;
+ width: 2rem;
+ height: 2rem;
+ vertical-align: text-bottom;
+ background-color: currentColor;
+ border-radius: 50%;
+ opacity: 0;
+ -webkit-animation: 0.75s linear infinite spinner-grow;
+ animation: 0.75s linear infinite spinner-grow;
+}
+.spinner-grow-sm {
+ width: 1rem;
+ height: 1rem;
+}
+@media (prefers-reduced-motion: reduce) {
+ .spinner-border,
+ .spinner-grow {
+ -webkit-animation-duration: 1.5s;
+ animation-duration: 1.5s;
+ }
+}
+.offcanvas {
+ position: fixed;
+ bottom: 0;
+ z-index: 1040;
+ display: flex;
+ flex-direction: column;
+ max-width: 100%;
+ visibility: hidden;
+ background-color: #fff;
+ background-clip: padding-box;
+ outline: 0;
+ transition: transform 0.3s ease-in-out;
+}
+@media (prefers-reduced-motion: reduce) {
+ .offcanvas {
+ transition: none;
+ }
+}
+.offcanvas-header {
+ display: flex;
+ justify-content: space-between;
+ padding: 1rem 1rem;
+}
+.offcanvas-header .btn-close {
+ padding: 0.5rem 0.5rem;
+ margin: -0.5rem -0.5rem -0.5rem auto;
+}
+.offcanvas-title {
+ margin-bottom: 0;
+ line-height: 1.5;
+}
+.offcanvas-body {
+ flex-grow: 1;
+ padding: 1rem 1rem;
+ overflow-y: auto;
+}
+.offcanvas-start {
+ top: 0;
+ left: 0;
+ width: 400px;
+ border-right: 1px solid rgba(0, 0, 0, 0.2);
+ transform: translateX(-100%);
+}
+.offcanvas-end {
+ top: 0;
+ right: 0;
+ width: 400px;
+ border-left: 1px solid rgba(0, 0, 0, 0.2);
+ transform: translateX(100%);
+}
+.offcanvas-bottom {
+ right: 0;
+ left: 0;
+ height: 30vh;
+ max-height: 100%;
+ border-top: 1px solid rgba(0, 0, 0, 0.2);
+ transform: translateY(100%);
+}
+.offcanvas.show {
+ transform: none;
+}
+.offcanvas-backdrop::before {
+ position: fixed;
+ top: 0;
+ left: 0;
+ z-index: 1039;
+ width: 100vw;
+ height: 100vh;
+ content: '';
+ background-color: rgba(0, 0, 0, 0.5);
+}
+.clearfix::after {
+ display: block;
+ clear: both;
+ content: '';
+}
+.link-primary {
+ color: #0d6efd;
+}
+.link-primary:focus,
+.link-primary:hover {
+ color: #0a58ca;
+}
+.link-secondary {
+ color: #6c757d;
+}
+.link-secondary:focus,
+.link-secondary:hover {
+ color: #565e64;
+}
+.link-success {
+ color: #198754;
+}
+.link-success:focus,
+.link-success:hover {
+ color: #146c43;
+}
+.link-info {
+ color: #0dcaf0;
+}
+.link-info:focus,
+.link-info:hover {
+ color: #3dd5f3;
+}
+.link-warning {
+ color: #ffc107;
+}
+.link-warning:focus,
+.link-warning:hover {
+ color: #ffcd39;
+}
+.link-danger {
+ color: #dc3545;
+}
+.link-danger:focus,
+.link-danger:hover {
+ color: #b02a37;
+}
+.link-light {
+ color: #f8f9fa;
+}
+.link-light:focus,
+.link-light:hover {
+ color: #f9fafb;
+}
+.link-dark {
+ color: #212529;
+}
+.link-dark:focus,
+.link-dark:hover {
+ color: #1a1e21;
+}
+.ratio {
+ position: relative;
+ width: 100%;
+}
+.ratio::before {
+ display: block;
+ padding-top: var(--bs-aspect-ratio);
+ content: '';
+}
+.ratio > * {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+}
+.ratio-1x1 {
+ --bs-aspect-ratio: 100%;
+}
+.ratio-4x3 {
+ --bs-aspect-ratio: calc(3 / 4 * 100%);
+}
+.ratio-16x9 {
+ --bs-aspect-ratio: calc(9 / 16 * 100%);
+}
+.ratio-21x9 {
+ --bs-aspect-ratio: calc(9 / 21 * 100%);
+}
+.fixed-top {
+ position: fixed;
+ top: 0;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+}
+.fixed-bottom {
+ position: fixed;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1030;
+}
+.sticky-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+}
+@media (min-width: 576px) {
+ .sticky-sm-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+}
+@media (min-width: 768px) {
+ .sticky-md-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+}
+@media (min-width: 992px) {
+ .sticky-lg-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+}
+@media (min-width: 1200px) {
+ .sticky-xl-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+}
+@media (min-width: 1400px) {
+ .sticky-xxl-top {
+ position: -webkit-sticky;
+ position: sticky;
+ top: 0;
+ z-index: 1020;
+ }
+}
+.visually-hidden,
+.visually-hidden-focusable:not(:focus):not(:focus-within) {
+ position: absolute !important;
+ width: 1px !important;
+ height: 1px !important;
+ padding: 0 !important;
+ margin: -1px !important;
+ overflow: hidden !important;
+ clip: rect(0, 0, 0, 0) !important;
+ white-space: nowrap !important;
+ border: 0 !important;
+}
+.stretched-link::after {
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1;
+ content: '';
+}
+.text-truncate {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.align-baseline {
+ vertical-align: baseline !important;
+}
+.align-top {
+ vertical-align: top !important;
+}
+.align-middle {
+ vertical-align: middle !important;
+}
+.align-bottom {
+ vertical-align: bottom !important;
+}
+.align-text-bottom {
+ vertical-align: text-bottom !important;
+}
+.align-text-top {
+ vertical-align: text-top !important;
+}
+.float-start {
+ float: left !important;
+}
+.float-end {
+ float: right !important;
+}
+.float-none {
+ float: none !important;
+}
+.overflow-auto {
+ overflow: auto !important;
+}
+.overflow-hidden {
+ overflow: hidden !important;
+}
+.overflow-visible {
+ overflow: visible !important;
+}
+.overflow-scroll {
+ overflow: scroll !important;
+}
+.d-inline {
+ display: inline !important;
+}
+.d-inline-block {
+ display: inline-block !important;
+}
+.d-block {
+ display: block !important;
+}
+.d-grid {
+ display: grid !important;
+}
+.d-table {
+ display: table !important;
+}
+.d-table-row {
+ display: table-row !important;
+}
+.d-table-cell {
+ display: table-cell !important;
+}
+.d-flex {
+ display: flex !important;
+}
+.d-inline-flex {
+ display: inline-flex !important;
+}
+.d-none {
+ display: none !important;
+}
+.shadow {
+ box-shadow: 0 0.5rem 1rem rgba(0, 0, 0, 0.15) !important;
+}
+.shadow-sm {
+ box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075) !important;
+}
+.shadow-lg {
+ box-shadow: 0 1rem 3rem rgba(0, 0, 0, 0.175) !important;
+}
+.shadow-none {
+ box-shadow: none !important;
+}
+.position-static {
+ position: static !important;
+}
+.position-relative {
+ position: relative !important;
+}
+.position-absolute {
+ position: absolute !important;
+}
+.position-fixed {
+ position: fixed !important;
+}
+.position-sticky {
+ position: -webkit-sticky !important;
+ position: sticky !important;
+}
+.top-0 {
+ top: 0 !important;
+}
+.top-50 {
+ top: 50% !important;
+}
+.top-100 {
+ top: 100% !important;
+}
+.bottom-0 {
+ bottom: 0 !important;
+}
+.bottom-50 {
+ bottom: 50% !important;
+}
+.bottom-100 {
+ bottom: 100% !important;
+}
+.start-0 {
+ left: 0 !important;
+}
+.start-50 {
+ left: 50% !important;
+}
+.start-100 {
+ left: 100% !important;
+}
+.end-0 {
+ right: 0 !important;
+}
+.end-50 {
+ right: 50% !important;
+}
+.end-100 {
+ right: 100% !important;
+}
+.translate-middle {
+ transform: translate(-50%, -50%) !important;
+}
+.translate-middle-x {
+ transform: translateX(-50%) !important;
+}
+.translate-middle-y {
+ transform: translateY(-50%) !important;
+}
+.border {
+ border: 1px solid #dee2e6 !important;
+}
+.border-0 {
+ border: 0 !important;
+}
+.border-top {
+ border-top: 1px solid #dee2e6 !important;
+}
+.border-top-0 {
+ border-top: 0 !important;
+}
+.border-end {
+ border-right: 1px solid #dee2e6 !important;
+}
+.border-end-0 {
+ border-right: 0 !important;
+}
+.border-bottom {
+ border-bottom: 1px solid #dee2e6 !important;
+}
+.border-bottom-0 {
+ border-bottom: 0 !important;
+}
+.border-start {
+ border-left: 1px solid #dee2e6 !important;
+}
+.border-start-0 {
+ border-left: 0 !important;
+}
+.border-primary {
+ border-color: #0d6efd !important;
+}
+.border-secondary {
+ border-color: #6c757d !important;
+}
+.border-success {
+ border-color: #198754 !important;
+}
+.border-info {
+ border-color: #0dcaf0 !important;
+}
+.border-warning {
+ border-color: #ffc107 !important;
+}
+.border-danger {
+ border-color: #dc3545 !important;
+}
+.border-light {
+ border-color: #f8f9fa !important;
+}
+.border-dark {
+ border-color: #212529 !important;
+}
+.border-white {
+ border-color: #fff !important;
+}
+.border-1 {
+ border-width: 1px !important;
+}
+.border-2 {
+ border-width: 2px !important;
+}
+.border-3 {
+ border-width: 3px !important;
+}
+.border-4 {
+ border-width: 4px !important;
+}
+.border-5 {
+ border-width: 5px !important;
+}
+.w-25 {
+ width: 25% !important;
+}
+.w-50 {
+ width: 50% !important;
+}
+.w-75 {
+ width: 75% !important;
+}
+.w-100 {
+ width: 100% !important;
+}
+.w-auto {
+ width: auto !important;
+}
+.mw-100 {
+ max-width: 100% !important;
+}
+.vw-100 {
+ width: 100vw !important;
+}
+.min-vw-100 {
+ min-width: 100vw !important;
+}
+.h-25 {
+ height: 25% !important;
+}
+.h-50 {
+ height: 50% !important;
+}
+.h-75 {
+ height: 75% !important;
+}
+.h-100 {
+ height: 100% !important;
+}
+.h-auto {
+ height: auto !important;
+}
+.mh-100 {
+ max-height: 100% !important;
+}
+.vh-100 {
+ height: 100vh !important;
+}
+.min-vh-100 {
+ min-height: 100vh !important;
+}
+.flex-fill {
+ flex: 1 1 auto !important;
+}
+.flex-row {
+ flex-direction: row !important;
+}
+.flex-column {
+ flex-direction: column !important;
+}
+.flex-row-reverse {
+ flex-direction: row-reverse !important;
+}
+.flex-column-reverse {
+ flex-direction: column-reverse !important;
+}
+.flex-grow-0 {
+ flex-grow: 0 !important;
+}
+.flex-grow-1 {
+ flex-grow: 1 !important;
+}
+.flex-shrink-0 {
+ flex-shrink: 0 !important;
+}
+.flex-shrink-1 {
+ flex-shrink: 1 !important;
+}
+.flex-wrap {
+ flex-wrap: wrap !important;
+}
+.flex-nowrap {
+ flex-wrap: nowrap !important;
+}
+.flex-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+}
+.gap-0 {
+ gap: 0 !important;
+}
+.gap-1 {
+ gap: 0.25rem !important;
+}
+.gap-2 {
+ gap: 0.5rem !important;
+}
+.gap-3 {
+ gap: 1rem !important;
+}
+.gap-4 {
+ gap: 1.5rem !important;
+}
+.gap-5 {
+ gap: 3rem !important;
+}
+.justify-content-start {
+ justify-content: flex-start !important;
+}
+.justify-content-end {
+ justify-content: flex-end !important;
+}
+.justify-content-center {
+ justify-content: center !important;
+}
+.justify-content-between {
+ justify-content: space-between !important;
+}
+.justify-content-around {
+ justify-content: space-around !important;
+}
+.justify-content-evenly {
+ justify-content: space-evenly !important;
+}
+.align-items-start {
+ align-items: flex-start !important;
+}
+.align-items-end {
+ align-items: flex-end !important;
+}
+.align-items-center {
+ align-items: center !important;
+}
+.align-items-baseline {
+ align-items: baseline !important;
+}
+.align-items-stretch {
+ align-items: stretch !important;
+}
+.align-content-start {
+ align-content: flex-start !important;
+}
+.align-content-end {
+ align-content: flex-end !important;
+}
+.align-content-center {
+ align-content: center !important;
+}
+.align-content-between {
+ align-content: space-between !important;
+}
+.align-content-around {
+ align-content: space-around !important;
+}
+.align-content-stretch {
+ align-content: stretch !important;
+}
+.align-self-auto {
+ align-self: auto !important;
+}
+.align-self-start {
+ align-self: flex-start !important;
+}
+.align-self-end {
+ align-self: flex-end !important;
+}
+.align-self-center {
+ align-self: center !important;
+}
+.align-self-baseline {
+ align-self: baseline !important;
+}
+.align-self-stretch {
+ align-self: stretch !important;
+}
+.order-first {
+ order: -1 !important;
+}
+.order-0 {
+ order: 0 !important;
+}
+.order-1 {
+ order: 1 !important;
+}
+.order-2 {
+ order: 2 !important;
+}
+.order-3 {
+ order: 3 !important;
+}
+.order-4 {
+ order: 4 !important;
+}
+.order-5 {
+ order: 5 !important;
+}
+.order-last {
+ order: 6 !important;
+}
+.m-0 {
+ margin: 0 !important;
+}
+.m-1 {
+ margin: 0.25rem !important;
+}
+.m-2 {
+ margin: 0.5rem !important;
+}
+.m-3 {
+ margin: 1rem !important;
+}
+.m-4 {
+ margin: 1.5rem !important;
+}
+.m-5 {
+ margin: 3rem !important;
+}
+.m-auto {
+ margin: auto !important;
+}
+.mx-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+}
+.mx-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+}
+.mx-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+}
+.mx-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+}
+.mx-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+}
+.mx-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+}
+.mx-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+}
+.my-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+}
+.my-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+}
+.my-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+}
+.my-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+}
+.my-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+}
+.my-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+}
+.my-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+}
+.mt-0 {
+ margin-top: 0 !important;
+}
+.mt-1 {
+ margin-top: 0.25rem !important;
+}
+.mt-2 {
+ margin-top: 0.5rem !important;
+}
+.mt-3 {
+ margin-top: 1rem !important;
+}
+.mt-4 {
+ margin-top: 1.5rem !important;
+}
+.mt-5 {
+ margin-top: 3rem !important;
+}
+.mt-auto {
+ margin-top: auto !important;
+}
+.me-0 {
+ margin-right: 0 !important;
+}
+.me-1 {
+ margin-right: 0.25rem !important;
+}
+.me-2 {
+ margin-right: 0.5rem !important;
+}
+.me-3 {
+ margin-right: 1rem !important;
+}
+.me-4 {
+ margin-right: 1.5rem !important;
+}
+.me-5 {
+ margin-right: 3rem !important;
+}
+.me-auto {
+ margin-right: auto !important;
+}
+.mb-0 {
+ margin-bottom: 0 !important;
+}
+.mb-1 {
+ margin-bottom: 0.25rem !important;
+}
+.mb-2 {
+ margin-bottom: 0.5rem !important;
+}
+.mb-3 {
+ margin-bottom: 1rem !important;
+}
+.mb-4 {
+ margin-bottom: 1.5rem !important;
+}
+.mb-5 {
+ margin-bottom: 3rem !important;
+}
+.mb-auto {
+ margin-bottom: auto !important;
+}
+.ms-0 {
+ margin-left: 0 !important;
+}
+.ms-1 {
+ margin-left: 0.25rem !important;
+}
+.ms-2 {
+ margin-left: 0.5rem !important;
+}
+.ms-3 {
+ margin-left: 1rem !important;
+}
+.ms-4 {
+ margin-left: 1.5rem !important;
+}
+.ms-5 {
+ margin-left: 3rem !important;
+}
+.ms-auto {
+ margin-left: auto !important;
+}
+.p-0 {
+ padding: 0 !important;
+}
+.p-1 {
+ padding: 0.25rem !important;
+}
+.p-2 {
+ padding: 0.5rem !important;
+}
+.p-3 {
+ padding: 1rem !important;
+}
+.p-4 {
+ padding: 1.5rem !important;
+}
+.p-5 {
+ padding: 3rem !important;
+}
+.px-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+}
+.px-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+}
+.px-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+}
+.px-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+}
+.px-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+}
+.px-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+}
+.py-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+}
+.py-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+}
+.py-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+}
+.py-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+}
+.py-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+}
+.py-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+}
+.pt-0 {
+ padding-top: 0 !important;
+}
+.pt-1 {
+ padding-top: 0.25rem !important;
+}
+.pt-2 {
+ padding-top: 0.5rem !important;
+}
+.pt-3 {
+ padding-top: 1rem !important;
+}
+.pt-4 {
+ padding-top: 1.5rem !important;
+}
+.pt-5 {
+ padding-top: 3rem !important;
+}
+.pe-0 {
+ padding-right: 0 !important;
+}
+.pe-1 {
+ padding-right: 0.25rem !important;
+}
+.pe-2 {
+ padding-right: 0.5rem !important;
+}
+.pe-3 {
+ padding-right: 1rem !important;
+}
+.pe-4 {
+ padding-right: 1.5rem !important;
+}
+.pe-5 {
+ padding-right: 3rem !important;
+}
+.pb-0 {
+ padding-bottom: 0 !important;
+}
+.pb-1 {
+ padding-bottom: 0.25rem !important;
+}
+.pb-2 {
+ padding-bottom: 0.5rem !important;
+}
+.pb-3 {
+ padding-bottom: 1rem !important;
+}
+.pb-4 {
+ padding-bottom: 1.5rem !important;
+}
+.pb-5 {
+ padding-bottom: 3rem !important;
+}
+.ps-0 {
+ padding-left: 0 !important;
+}
+.ps-1 {
+ padding-left: 0.25rem !important;
+}
+.ps-2 {
+ padding-left: 0.5rem !important;
+}
+.ps-3 {
+ padding-left: 1rem !important;
+}
+.ps-4 {
+ padding-left: 1.5rem !important;
+}
+.ps-5 {
+ padding-left: 3rem !important;
+}
+.font-monospace {
+ font-family: var(--bs-font-monospace) !important;
+}
+.fs-1 {
+ font-size: calc(1.375rem+1.5vw) !important;
+}
+.fs-2 {
+ font-size: calc(1.325rem+0.9vw) !important;
+}
+.fs-3 {
+ font-size: calc(1.3rem+0.6vw) !important;
+}
+.fs-4 {
+ font-size: calc(1.275rem+0.3vw) !important;
+}
+.fs-5 {
+ font-size: 1.25rem !important;
+}
+.fs-6 {
+ font-size: 1rem !important;
+}
+.fst-italic {
+ font-style: italic !important;
+}
+.fst-normal {
+ font-style: normal !important;
+}
+.fw-light {
+ font-weight: 300 !important;
+}
+.fw-lighter {
+ font-weight: lighter !important;
+}
+.fw-normal {
+ font-weight: 400 !important;
+}
+.fw-bold {
+ font-weight: 700 !important;
+}
+.fw-bolder {
+ font-weight: bolder !important;
+}
+.lh-1 {
+ line-height: 1 !important;
+}
+.lh-sm {
+ line-height: 1.25 !important;
+}
+.lh-base {
+ line-height: 1.5 !important;
+}
+.lh-lg {
+ line-height: 2 !important;
+}
+.text-start {
+ text-align: left !important;
+}
+.text-end {
+ text-align: right !important;
+}
+.text-center {
+ text-align: center !important;
+}
+.text-decoration-none {
+ text-decoration: none !important;
+}
+.text-decoration-underline {
+ text-decoration: underline !important;
+}
+.text-decoration-line-through {
+ text-decoration: line-through !important;
+}
+.text-lowercase {
+ text-transform: lowercase !important;
+}
+.text-uppercase {
+ text-transform: uppercase !important;
+}
+.text-capitalize {
+ text-transform: capitalize !important;
+}
+.text-wrap {
+ white-space: normal !important;
+}
+.text-nowrap {
+ white-space: nowrap !important;
+}
+.text-break {
+ word-wrap: break-word !important;
+ word-break: break-word !important;
+}
+.text-primary {
+ color: #0d6efd !important;
+}
+.text-secondary {
+ color: #6c757d !important;
+}
+.text-success {
+ color: #198754 !important;
+}
+.text-info {
+ color: #0dcaf0 !important;
+}
+.text-warning {
+ color: #ffc107 !important;
+}
+.text-danger {
+ color: #dc3545 !important;
+}
+.text-light {
+ color: #f8f9fa !important;
+}
+.text-dark {
+ color: #212529 !important;
+}
+.text-white {
+ color: #fff !important;
+}
+.text-body {
+ color: #212529 !important;
+}
+.text-muted {
+ color: #6c757d !important;
+}
+.text-black-50 {
+ color: rgba(0, 0, 0, 0.5) !important;
+}
+.text-white-50 {
+ color: rgba(255, 255, 255, 0.5) !important;
+}
+.text-reset {
+ color: inherit !important;
+}
+.bg-primary {
+ background-color: #0d6efd !important;
+}
+.bg-secondary {
+ background-color: #6c757d !important;
+}
+.bg-success {
+ background-color: #198754 !important;
+}
+.bg-info {
+ background-color: #0dcaf0 !important;
+}
+.bg-warning {
+ background-color: #ffc107 !important;
+}
+.bg-danger {
+ background-color: #dc3545 !important;
+}
+.bg-light {
+ background-color: #f8f9fa !important;
+}
+.bg-dark {
+ background-color: #212529 !important;
+}
+.bg-body {
+ background-color: #fff !important;
+}
+.bg-white {
+ background-color: #fff !important;
+}
+.bg-transparent {
+ background-color: transparent !important;
+}
+.bg-gradient {
+ background-image: var(--bs-gradient) !important;
+}
+.user-select-all {
+ -webkit-user-select: all !important;
+ -moz-user-select: all !important;
+ user-select: all !important;
+}
+.user-select-auto {
+ -webkit-user-select: auto !important;
+ -moz-user-select: auto !important;
+ user-select: auto !important;
+}
+.user-select-none {
+ -webkit-user-select: none !important;
+ -moz-user-select: none !important;
+ user-select: none !important;
+}
+.pe-none {
+ pointer-events: none !important;
+}
+.pe-auto {
+ pointer-events: auto !important;
+}
+.rounded {
+ border-radius: 0.25rem !important;
+}
+.rounded-0 {
+ border-radius: 0 !important;
+}
+.rounded-1 {
+ border-radius: 0.2rem !important;
+}
+.rounded-2 {
+ border-radius: 0.25rem !important;
+}
+.rounded-3 {
+ border-radius: 0.3rem !important;
+}
+.rounded-circle {
+ border-radius: 50% !important;
+}
+.rounded-pill {
+ border-radius: 50rem !important;
+}
+.rounded-top {
+ border-top-left-radius: 0.25rem !important;
+ border-top-right-radius: 0.25rem !important;
+}
+.rounded-end {
+ border-top-right-radius: 0.25rem !important;
+ border-bottom-right-radius: 0.25rem !important;
+}
+.rounded-bottom {
+ border-bottom-right-radius: 0.25rem !important;
+ border-bottom-left-radius: 0.25rem !important;
+}
+.rounded-start {
+ border-bottom-left-radius: 0.25rem !important;
+ border-top-left-radius: 0.25rem !important;
+}
+.visible {
+ visibility: visible !important;
+}
+.invisible {
+ visibility: hidden !important;
+}
+@media (min-width: 576px) {
+ .float-sm-start {
+ float: left !important;
+ }
+ .float-sm-end {
+ float: right !important;
+ }
+ .float-sm-none {
+ float: none !important;
+ }
+ .d-sm-inline {
+ display: inline !important;
+ }
+ .d-sm-inline-block {
+ display: inline-block !important;
+ }
+ .d-sm-block {
+ display: block !important;
+ }
+ .d-sm-grid {
+ display: grid !important;
+ }
+ .d-sm-table {
+ display: table !important;
+ }
+ .d-sm-table-row {
+ display: table-row !important;
+ }
+ .d-sm-table-cell {
+ display: table-cell !important;
+ }
+ .d-sm-flex {
+ display: flex !important;
+ }
+ .d-sm-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-sm-none {
+ display: none !important;
+ }
+ .flex-sm-fill {
+ flex: 1 1 auto !important;
+ }
+ .flex-sm-row {
+ flex-direction: row !important;
+ }
+ .flex-sm-column {
+ flex-direction: column !important;
+ }
+ .flex-sm-row-reverse {
+ flex-direction: row-reverse !important;
+ }
+ .flex-sm-column-reverse {
+ flex-direction: column-reverse !important;
+ }
+ .flex-sm-grow-0 {
+ flex-grow: 0 !important;
+ }
+ .flex-sm-grow-1 {
+ flex-grow: 1 !important;
+ }
+ .flex-sm-shrink-0 {
+ flex-shrink: 0 !important;
+ }
+ .flex-sm-shrink-1 {
+ flex-shrink: 1 !important;
+ }
+ .flex-sm-wrap {
+ flex-wrap: wrap !important;
+ }
+ .flex-sm-nowrap {
+ flex-wrap: nowrap !important;
+ }
+ .flex-sm-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+ }
+ .gap-sm-0 {
+ gap: 0 !important;
+ }
+ .gap-sm-1 {
+ gap: 0.25rem !important;
+ }
+ .gap-sm-2 {
+ gap: 0.5rem !important;
+ }
+ .gap-sm-3 {
+ gap: 1rem !important;
+ }
+ .gap-sm-4 {
+ gap: 1.5rem !important;
+ }
+ .gap-sm-5 {
+ gap: 3rem !important;
+ }
+ .justify-content-sm-start {
+ justify-content: flex-start !important;
+ }
+ .justify-content-sm-end {
+ justify-content: flex-end !important;
+ }
+ .justify-content-sm-center {
+ justify-content: center !important;
+ }
+ .justify-content-sm-between {
+ justify-content: space-between !important;
+ }
+ .justify-content-sm-around {
+ justify-content: space-around !important;
+ }
+ .justify-content-sm-evenly {
+ justify-content: space-evenly !important;
+ }
+ .align-items-sm-start {
+ align-items: flex-start !important;
+ }
+ .align-items-sm-end {
+ align-items: flex-end !important;
+ }
+ .align-items-sm-center {
+ align-items: center !important;
+ }
+ .align-items-sm-baseline {
+ align-items: baseline !important;
+ }
+ .align-items-sm-stretch {
+ align-items: stretch !important;
+ }
+ .align-content-sm-start {
+ align-content: flex-start !important;
+ }
+ .align-content-sm-end {
+ align-content: flex-end !important;
+ }
+ .align-content-sm-center {
+ align-content: center !important;
+ }
+ .align-content-sm-between {
+ align-content: space-between !important;
+ }
+ .align-content-sm-around {
+ align-content: space-around !important;
+ }
+ .align-content-sm-stretch {
+ align-content: stretch !important;
+ }
+ .align-self-sm-auto {
+ align-self: auto !important;
+ }
+ .align-self-sm-start {
+ align-self: flex-start !important;
+ }
+ .align-self-sm-end {
+ align-self: flex-end !important;
+ }
+ .align-self-sm-center {
+ align-self: center !important;
+ }
+ .align-self-sm-baseline {
+ align-self: baseline !important;
+ }
+ .align-self-sm-stretch {
+ align-self: stretch !important;
+ }
+ .order-sm-first {
+ order: -1 !important;
+ }
+ .order-sm-0 {
+ order: 0 !important;
+ }
+ .order-sm-1 {
+ order: 1 !important;
+ }
+ .order-sm-2 {
+ order: 2 !important;
+ }
+ .order-sm-3 {
+ order: 3 !important;
+ }
+ .order-sm-4 {
+ order: 4 !important;
+ }
+ .order-sm-5 {
+ order: 5 !important;
+ }
+ .order-sm-last {
+ order: 6 !important;
+ }
+ .m-sm-0 {
+ margin: 0 !important;
+ }
+ .m-sm-1 {
+ margin: 0.25rem !important;
+ }
+ .m-sm-2 {
+ margin: 0.5rem !important;
+ }
+ .m-sm-3 {
+ margin: 1rem !important;
+ }
+ .m-sm-4 {
+ margin: 1.5rem !important;
+ }
+ .m-sm-5 {
+ margin: 3rem !important;
+ }
+ .m-sm-auto {
+ margin: auto !important;
+ }
+ .mx-sm-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ }
+ .mx-sm-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+ }
+ .mx-sm-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+ }
+ .mx-sm-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+ }
+ .mx-sm-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+ }
+ .mx-sm-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+ }
+ .mx-sm-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my-sm-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ }
+ .my-sm-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+ }
+ .my-sm-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .my-sm-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+ }
+ .my-sm-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+ }
+ .my-sm-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+ }
+ .my-sm-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ .mt-sm-0 {
+ margin-top: 0 !important;
+ }
+ .mt-sm-1 {
+ margin-top: 0.25rem !important;
+ }
+ .mt-sm-2 {
+ margin-top: 0.5rem !important;
+ }
+ .mt-sm-3 {
+ margin-top: 1rem !important;
+ }
+ .mt-sm-4 {
+ margin-top: 1.5rem !important;
+ }
+ .mt-sm-5 {
+ margin-top: 3rem !important;
+ }
+ .mt-sm-auto {
+ margin-top: auto !important;
+ }
+ .me-sm-0 {
+ margin-right: 0 !important;
+ }
+ .me-sm-1 {
+ margin-right: 0.25rem !important;
+ }
+ .me-sm-2 {
+ margin-right: 0.5rem !important;
+ }
+ .me-sm-3 {
+ margin-right: 1rem !important;
+ }
+ .me-sm-4 {
+ margin-right: 1.5rem !important;
+ }
+ .me-sm-5 {
+ margin-right: 3rem !important;
+ }
+ .me-sm-auto {
+ margin-right: auto !important;
+ }
+ .mb-sm-0 {
+ margin-bottom: 0 !important;
+ }
+ .mb-sm-1 {
+ margin-bottom: 0.25rem !important;
+ }
+ .mb-sm-2 {
+ margin-bottom: 0.5rem !important;
+ }
+ .mb-sm-3 {
+ margin-bottom: 1rem !important;
+ }
+ .mb-sm-4 {
+ margin-bottom: 1.5rem !important;
+ }
+ .mb-sm-5 {
+ margin-bottom: 3rem !important;
+ }
+ .mb-sm-auto {
+ margin-bottom: auto !important;
+ }
+ .ms-sm-0 {
+ margin-left: 0 !important;
+ }
+ .ms-sm-1 {
+ margin-left: 0.25rem !important;
+ }
+ .ms-sm-2 {
+ margin-left: 0.5rem !important;
+ }
+ .ms-sm-3 {
+ margin-left: 1rem !important;
+ }
+ .ms-sm-4 {
+ margin-left: 1.5rem !important;
+ }
+ .ms-sm-5 {
+ margin-left: 3rem !important;
+ }
+ .ms-sm-auto {
+ margin-left: auto !important;
+ }
+ .p-sm-0 {
+ padding: 0 !important;
+ }
+ .p-sm-1 {
+ padding: 0.25rem !important;
+ }
+ .p-sm-2 {
+ padding: 0.5rem !important;
+ }
+ .p-sm-3 {
+ padding: 1rem !important;
+ }
+ .p-sm-4 {
+ padding: 1.5rem !important;
+ }
+ .p-sm-5 {
+ padding: 3rem !important;
+ }
+ .px-sm-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
+ .px-sm-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+ }
+ .px-sm-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+ }
+ .px-sm-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+ }
+ .px-sm-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+ }
+ .px-sm-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+ }
+ .py-sm-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+ .py-sm-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+ }
+ .py-sm-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ }
+ .py-sm-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ }
+ .py-sm-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+ }
+ .py-sm-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+ }
+ .pt-sm-0 {
+ padding-top: 0 !important;
+ }
+ .pt-sm-1 {
+ padding-top: 0.25rem !important;
+ }
+ .pt-sm-2 {
+ padding-top: 0.5rem !important;
+ }
+ .pt-sm-3 {
+ padding-top: 1rem !important;
+ }
+ .pt-sm-4 {
+ padding-top: 1.5rem !important;
+ }
+ .pt-sm-5 {
+ padding-top: 3rem !important;
+ }
+ .pe-sm-0 {
+ padding-right: 0 !important;
+ }
+ .pe-sm-1 {
+ padding-right: 0.25rem !important;
+ }
+ .pe-sm-2 {
+ padding-right: 0.5rem !important;
+ }
+ .pe-sm-3 {
+ padding-right: 1rem !important;
+ }
+ .pe-sm-4 {
+ padding-right: 1.5rem !important;
+ }
+ .pe-sm-5 {
+ padding-right: 3rem !important;
+ }
+ .pb-sm-0 {
+ padding-bottom: 0 !important;
+ }
+ .pb-sm-1 {
+ padding-bottom: 0.25rem !important;
+ }
+ .pb-sm-2 {
+ padding-bottom: 0.5rem !important;
+ }
+ .pb-sm-3 {
+ padding-bottom: 1rem !important;
+ }
+ .pb-sm-4 {
+ padding-bottom: 1.5rem !important;
+ }
+ .pb-sm-5 {
+ padding-bottom: 3rem !important;
+ }
+ .ps-sm-0 {
+ padding-left: 0 !important;
+ }
+ .ps-sm-1 {
+ padding-left: 0.25rem !important;
+ }
+ .ps-sm-2 {
+ padding-left: 0.5rem !important;
+ }
+ .ps-sm-3 {
+ padding-left: 1rem !important;
+ }
+ .ps-sm-4 {
+ padding-left: 1.5rem !important;
+ }
+ .ps-sm-5 {
+ padding-left: 3rem !important;
+ }
+ .text-sm-start {
+ text-align: left !important;
+ }
+ .text-sm-end {
+ text-align: right !important;
+ }
+ .text-sm-center {
+ text-align: center !important;
+ }
+}
+@media (min-width: 768px) {
+ .float-md-start {
+ float: left !important;
+ }
+ .float-md-end {
+ float: right !important;
+ }
+ .float-md-none {
+ float: none !important;
+ }
+ .d-md-inline {
+ display: inline !important;
+ }
+ .d-md-inline-block {
+ display: inline-block !important;
+ }
+ .d-md-block {
+ display: block !important;
+ }
+ .d-md-grid {
+ display: grid !important;
+ }
+ .d-md-table {
+ display: table !important;
+ }
+ .d-md-table-row {
+ display: table-row !important;
+ }
+ .d-md-table-cell {
+ display: table-cell !important;
+ }
+ .d-md-flex {
+ display: flex !important;
+ }
+ .d-md-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-md-none {
+ display: none !important;
+ }
+ .flex-md-fill {
+ flex: 1 1 auto !important;
+ }
+ .flex-md-row {
+ flex-direction: row !important;
+ }
+ .flex-md-column {
+ flex-direction: column !important;
+ }
+ .flex-md-row-reverse {
+ flex-direction: row-reverse !important;
+ }
+ .flex-md-column-reverse {
+ flex-direction: column-reverse !important;
+ }
+ .flex-md-grow-0 {
+ flex-grow: 0 !important;
+ }
+ .flex-md-grow-1 {
+ flex-grow: 1 !important;
+ }
+ .flex-md-shrink-0 {
+ flex-shrink: 0 !important;
+ }
+ .flex-md-shrink-1 {
+ flex-shrink: 1 !important;
+ }
+ .flex-md-wrap {
+ flex-wrap: wrap !important;
+ }
+ .flex-md-nowrap {
+ flex-wrap: nowrap !important;
+ }
+ .flex-md-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+ }
+ .gap-md-0 {
+ gap: 0 !important;
+ }
+ .gap-md-1 {
+ gap: 0.25rem !important;
+ }
+ .gap-md-2 {
+ gap: 0.5rem !important;
+ }
+ .gap-md-3 {
+ gap: 1rem !important;
+ }
+ .gap-md-4 {
+ gap: 1.5rem !important;
+ }
+ .gap-md-5 {
+ gap: 3rem !important;
+ }
+ .justify-content-md-start {
+ justify-content: flex-start !important;
+ }
+ .justify-content-md-end {
+ justify-content: flex-end !important;
+ }
+ .justify-content-md-center {
+ justify-content: center !important;
+ }
+ .justify-content-md-between {
+ justify-content: space-between !important;
+ }
+ .justify-content-md-around {
+ justify-content: space-around !important;
+ }
+ .justify-content-md-evenly {
+ justify-content: space-evenly !important;
+ }
+ .align-items-md-start {
+ align-items: flex-start !important;
+ }
+ .align-items-md-end {
+ align-items: flex-end !important;
+ }
+ .align-items-md-center {
+ align-items: center !important;
+ }
+ .align-items-md-baseline {
+ align-items: baseline !important;
+ }
+ .align-items-md-stretch {
+ align-items: stretch !important;
+ }
+ .align-content-md-start {
+ align-content: flex-start !important;
+ }
+ .align-content-md-end {
+ align-content: flex-end !important;
+ }
+ .align-content-md-center {
+ align-content: center !important;
+ }
+ .align-content-md-between {
+ align-content: space-between !important;
+ }
+ .align-content-md-around {
+ align-content: space-around !important;
+ }
+ .align-content-md-stretch {
+ align-content: stretch !important;
+ }
+ .align-self-md-auto {
+ align-self: auto !important;
+ }
+ .align-self-md-start {
+ align-self: flex-start !important;
+ }
+ .align-self-md-end {
+ align-self: flex-end !important;
+ }
+ .align-self-md-center {
+ align-self: center !important;
+ }
+ .align-self-md-baseline {
+ align-self: baseline !important;
+ }
+ .align-self-md-stretch {
+ align-self: stretch !important;
+ }
+ .order-md-first {
+ order: -1 !important;
+ }
+ .order-md-0 {
+ order: 0 !important;
+ }
+ .order-md-1 {
+ order: 1 !important;
+ }
+ .order-md-2 {
+ order: 2 !important;
+ }
+ .order-md-3 {
+ order: 3 !important;
+ }
+ .order-md-4 {
+ order: 4 !important;
+ }
+ .order-md-5 {
+ order: 5 !important;
+ }
+ .order-md-last {
+ order: 6 !important;
+ }
+ .m-md-0 {
+ margin: 0 !important;
+ }
+ .m-md-1 {
+ margin: 0.25rem !important;
+ }
+ .m-md-2 {
+ margin: 0.5rem !important;
+ }
+ .m-md-3 {
+ margin: 1rem !important;
+ }
+ .m-md-4 {
+ margin: 1.5rem !important;
+ }
+ .m-md-5 {
+ margin: 3rem !important;
+ }
+ .m-md-auto {
+ margin: auto !important;
+ }
+ .mx-md-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ }
+ .mx-md-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+ }
+ .mx-md-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+ }
+ .mx-md-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+ }
+ .mx-md-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+ }
+ .mx-md-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+ }
+ .mx-md-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my-md-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ }
+ .my-md-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+ }
+ .my-md-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .my-md-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+ }
+ .my-md-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+ }
+ .my-md-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+ }
+ .my-md-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ .mt-md-0 {
+ margin-top: 0 !important;
+ }
+ .mt-md-1 {
+ margin-top: 0.25rem !important;
+ }
+ .mt-md-2 {
+ margin-top: 0.5rem !important;
+ }
+ .mt-md-3 {
+ margin-top: 1rem !important;
+ }
+ .mt-md-4 {
+ margin-top: 1.5rem !important;
+ }
+ .mt-md-5 {
+ margin-top: 3rem !important;
+ }
+ .mt-md-auto {
+ margin-top: auto !important;
+ }
+ .me-md-0 {
+ margin-right: 0 !important;
+ }
+ .me-md-1 {
+ margin-right: 0.25rem !important;
+ }
+ .me-md-2 {
+ margin-right: 0.5rem !important;
+ }
+ .me-md-3 {
+ margin-right: 1rem !important;
+ }
+ .me-md-4 {
+ margin-right: 1.5rem !important;
+ }
+ .me-md-5 {
+ margin-right: 3rem !important;
+ }
+ .me-md-auto {
+ margin-right: auto !important;
+ }
+ .mb-md-0 {
+ margin-bottom: 0 !important;
+ }
+ .mb-md-1 {
+ margin-bottom: 0.25rem !important;
+ }
+ .mb-md-2 {
+ margin-bottom: 0.5rem !important;
+ }
+ .mb-md-3 {
+ margin-bottom: 1rem !important;
+ }
+ .mb-md-4 {
+ margin-bottom: 1.5rem !important;
+ }
+ .mb-md-5 {
+ margin-bottom: 3rem !important;
+ }
+ .mb-md-auto {
+ margin-bottom: auto !important;
+ }
+ .ms-md-0 {
+ margin-left: 0 !important;
+ }
+ .ms-md-1 {
+ margin-left: 0.25rem !important;
+ }
+ .ms-md-2 {
+ margin-left: 0.5rem !important;
+ }
+ .ms-md-3 {
+ margin-left: 1rem !important;
+ }
+ .ms-md-4 {
+ margin-left: 1.5rem !important;
+ }
+ .ms-md-5 {
+ margin-left: 3rem !important;
+ }
+ .ms-md-auto {
+ margin-left: auto !important;
+ }
+ .p-md-0 {
+ padding: 0 !important;
+ }
+ .p-md-1 {
+ padding: 0.25rem !important;
+ }
+ .p-md-2 {
+ padding: 0.5rem !important;
+ }
+ .p-md-3 {
+ padding: 1rem !important;
+ }
+ .p-md-4 {
+ padding: 1.5rem !important;
+ }
+ .p-md-5 {
+ padding: 3rem !important;
+ }
+ .px-md-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
+ .px-md-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+ }
+ .px-md-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+ }
+ .px-md-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+ }
+ .px-md-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+ }
+ .px-md-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+ }
+ .py-md-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+ .py-md-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+ }
+ .py-md-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ }
+ .py-md-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ }
+ .py-md-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+ }
+ .py-md-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+ }
+ .pt-md-0 {
+ padding-top: 0 !important;
+ }
+ .pt-md-1 {
+ padding-top: 0.25rem !important;
+ }
+ .pt-md-2 {
+ padding-top: 0.5rem !important;
+ }
+ .pt-md-3 {
+ padding-top: 1rem !important;
+ }
+ .pt-md-4 {
+ padding-top: 1.5rem !important;
+ }
+ .pt-md-5 {
+ padding-top: 3rem !important;
+ }
+ .pe-md-0 {
+ padding-right: 0 !important;
+ }
+ .pe-md-1 {
+ padding-right: 0.25rem !important;
+ }
+ .pe-md-2 {
+ padding-right: 0.5rem !important;
+ }
+ .pe-md-3 {
+ padding-right: 1rem !important;
+ }
+ .pe-md-4 {
+ padding-right: 1.5rem !important;
+ }
+ .pe-md-5 {
+ padding-right: 3rem !important;
+ }
+ .pb-md-0 {
+ padding-bottom: 0 !important;
+ }
+ .pb-md-1 {
+ padding-bottom: 0.25rem !important;
+ }
+ .pb-md-2 {
+ padding-bottom: 0.5rem !important;
+ }
+ .pb-md-3 {
+ padding-bottom: 1rem !important;
+ }
+ .pb-md-4 {
+ padding-bottom: 1.5rem !important;
+ }
+ .pb-md-5 {
+ padding-bottom: 3rem !important;
+ }
+ .ps-md-0 {
+ padding-left: 0 !important;
+ }
+ .ps-md-1 {
+ padding-left: 0.25rem !important;
+ }
+ .ps-md-2 {
+ padding-left: 0.5rem !important;
+ }
+ .ps-md-3 {
+ padding-left: 1rem !important;
+ }
+ .ps-md-4 {
+ padding-left: 1.5rem !important;
+ }
+ .ps-md-5 {
+ padding-left: 3rem !important;
+ }
+ .text-md-start {
+ text-align: left !important;
+ }
+ .text-md-end {
+ text-align: right !important;
+ }
+ .text-md-center {
+ text-align: center !important;
+ }
+}
+@media (min-width: 992px) {
+ .float-lg-start {
+ float: left !important;
+ }
+ .float-lg-end {
+ float: right !important;
+ }
+ .float-lg-none {
+ float: none !important;
+ }
+ .d-lg-inline {
+ display: inline !important;
+ }
+ .d-lg-inline-block {
+ display: inline-block !important;
+ }
+ .d-lg-block {
+ display: block !important;
+ }
+ .d-lg-grid {
+ display: grid !important;
+ }
+ .d-lg-table {
+ display: table !important;
+ }
+ .d-lg-table-row {
+ display: table-row !important;
+ }
+ .d-lg-table-cell {
+ display: table-cell !important;
+ }
+ .d-lg-flex {
+ display: flex !important;
+ }
+ .d-lg-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-lg-none {
+ display: none !important;
+ }
+ .flex-lg-fill {
+ flex: 1 1 auto !important;
+ }
+ .flex-lg-row {
+ flex-direction: row !important;
+ }
+ .flex-lg-column {
+ flex-direction: column !important;
+ }
+ .flex-lg-row-reverse {
+ flex-direction: row-reverse !important;
+ }
+ .flex-lg-column-reverse {
+ flex-direction: column-reverse !important;
+ }
+ .flex-lg-grow-0 {
+ flex-grow: 0 !important;
+ }
+ .flex-lg-grow-1 {
+ flex-grow: 1 !important;
+ }
+ .flex-lg-shrink-0 {
+ flex-shrink: 0 !important;
+ }
+ .flex-lg-shrink-1 {
+ flex-shrink: 1 !important;
+ }
+ .flex-lg-wrap {
+ flex-wrap: wrap !important;
+ }
+ .flex-lg-nowrap {
+ flex-wrap: nowrap !important;
+ }
+ .flex-lg-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+ }
+ .gap-lg-0 {
+ gap: 0 !important;
+ }
+ .gap-lg-1 {
+ gap: 0.25rem !important;
+ }
+ .gap-lg-2 {
+ gap: 0.5rem !important;
+ }
+ .gap-lg-3 {
+ gap: 1rem !important;
+ }
+ .gap-lg-4 {
+ gap: 1.5rem !important;
+ }
+ .gap-lg-5 {
+ gap: 3rem !important;
+ }
+ .justify-content-lg-start {
+ justify-content: flex-start !important;
+ }
+ .justify-content-lg-end {
+ justify-content: flex-end !important;
+ }
+ .justify-content-lg-center {
+ justify-content: center !important;
+ }
+ .justify-content-lg-between {
+ justify-content: space-between !important;
+ }
+ .justify-content-lg-around {
+ justify-content: space-around !important;
+ }
+ .justify-content-lg-evenly {
+ justify-content: space-evenly !important;
+ }
+ .align-items-lg-start {
+ align-items: flex-start !important;
+ }
+ .align-items-lg-end {
+ align-items: flex-end !important;
+ }
+ .align-items-lg-center {
+ align-items: center !important;
+ }
+ .align-items-lg-baseline {
+ align-items: baseline !important;
+ }
+ .align-items-lg-stretch {
+ align-items: stretch !important;
+ }
+ .align-content-lg-start {
+ align-content: flex-start !important;
+ }
+ .align-content-lg-end {
+ align-content: flex-end !important;
+ }
+ .align-content-lg-center {
+ align-content: center !important;
+ }
+ .align-content-lg-between {
+ align-content: space-between !important;
+ }
+ .align-content-lg-around {
+ align-content: space-around !important;
+ }
+ .align-content-lg-stretch {
+ align-content: stretch !important;
+ }
+ .align-self-lg-auto {
+ align-self: auto !important;
+ }
+ .align-self-lg-start {
+ align-self: flex-start !important;
+ }
+ .align-self-lg-end {
+ align-self: flex-end !important;
+ }
+ .align-self-lg-center {
+ align-self: center !important;
+ }
+ .align-self-lg-baseline {
+ align-self: baseline !important;
+ }
+ .align-self-lg-stretch {
+ align-self: stretch !important;
+ }
+ .order-lg-first {
+ order: -1 !important;
+ }
+ .order-lg-0 {
+ order: 0 !important;
+ }
+ .order-lg-1 {
+ order: 1 !important;
+ }
+ .order-lg-2 {
+ order: 2 !important;
+ }
+ .order-lg-3 {
+ order: 3 !important;
+ }
+ .order-lg-4 {
+ order: 4 !important;
+ }
+ .order-lg-5 {
+ order: 5 !important;
+ }
+ .order-lg-last {
+ order: 6 !important;
+ }
+ .m-lg-0 {
+ margin: 0 !important;
+ }
+ .m-lg-1 {
+ margin: 0.25rem !important;
+ }
+ .m-lg-2 {
+ margin: 0.5rem !important;
+ }
+ .m-lg-3 {
+ margin: 1rem !important;
+ }
+ .m-lg-4 {
+ margin: 1.5rem !important;
+ }
+ .m-lg-5 {
+ margin: 3rem !important;
+ }
+ .m-lg-auto {
+ margin: auto !important;
+ }
+ .mx-lg-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ }
+ .mx-lg-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+ }
+ .mx-lg-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+ }
+ .mx-lg-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+ }
+ .mx-lg-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+ }
+ .mx-lg-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+ }
+ .mx-lg-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my-lg-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ }
+ .my-lg-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+ }
+ .my-lg-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .my-lg-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+ }
+ .my-lg-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+ }
+ .my-lg-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+ }
+ .my-lg-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ .mt-lg-0 {
+ margin-top: 0 !important;
+ }
+ .mt-lg-1 {
+ margin-top: 0.25rem !important;
+ }
+ .mt-lg-2 {
+ margin-top: 0.5rem !important;
+ }
+ .mt-lg-3 {
+ margin-top: 1rem !important;
+ }
+ .mt-lg-4 {
+ margin-top: 1.5rem !important;
+ }
+ .mt-lg-5 {
+ margin-top: 3rem !important;
+ }
+ .mt-lg-auto {
+ margin-top: auto !important;
+ }
+ .me-lg-0 {
+ margin-right: 0 !important;
+ }
+ .me-lg-1 {
+ margin-right: 0.25rem !important;
+ }
+ .me-lg-2 {
+ margin-right: 0.5rem !important;
+ }
+ .me-lg-3 {
+ margin-right: 1rem !important;
+ }
+ .me-lg-4 {
+ margin-right: 1.5rem !important;
+ }
+ .me-lg-5 {
+ margin-right: 3rem !important;
+ }
+ .me-lg-auto {
+ margin-right: auto !important;
+ }
+ .mb-lg-0 {
+ margin-bottom: 0 !important;
+ }
+ .mb-lg-1 {
+ margin-bottom: 0.25rem !important;
+ }
+ .mb-lg-2 {
+ margin-bottom: 0.5rem !important;
+ }
+ .mb-lg-3 {
+ margin-bottom: 1rem !important;
+ }
+ .mb-lg-4 {
+ margin-bottom: 1.5rem !important;
+ }
+ .mb-lg-5 {
+ margin-bottom: 3rem !important;
+ }
+ .mb-lg-auto {
+ margin-bottom: auto !important;
+ }
+ .ms-lg-0 {
+ margin-left: 0 !important;
+ }
+ .ms-lg-1 {
+ margin-left: 0.25rem !important;
+ }
+ .ms-lg-2 {
+ margin-left: 0.5rem !important;
+ }
+ .ms-lg-3 {
+ margin-left: 1rem !important;
+ }
+ .ms-lg-4 {
+ margin-left: 1.5rem !important;
+ }
+ .ms-lg-5 {
+ margin-left: 3rem !important;
+ }
+ .ms-lg-auto {
+ margin-left: auto !important;
+ }
+ .p-lg-0 {
+ padding: 0 !important;
+ }
+ .p-lg-1 {
+ padding: 0.25rem !important;
+ }
+ .p-lg-2 {
+ padding: 0.5rem !important;
+ }
+ .p-lg-3 {
+ padding: 1rem !important;
+ }
+ .p-lg-4 {
+ padding: 1.5rem !important;
+ }
+ .p-lg-5 {
+ padding: 3rem !important;
+ }
+ .px-lg-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
+ .px-lg-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+ }
+ .px-lg-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+ }
+ .px-lg-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+ }
+ .px-lg-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+ }
+ .px-lg-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+ }
+ .py-lg-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+ .py-lg-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+ }
+ .py-lg-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ }
+ .py-lg-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ }
+ .py-lg-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+ }
+ .py-lg-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+ }
+ .pt-lg-0 {
+ padding-top: 0 !important;
+ }
+ .pt-lg-1 {
+ padding-top: 0.25rem !important;
+ }
+ .pt-lg-2 {
+ padding-top: 0.5rem !important;
+ }
+ .pt-lg-3 {
+ padding-top: 1rem !important;
+ }
+ .pt-lg-4 {
+ padding-top: 1.5rem !important;
+ }
+ .pt-lg-5 {
+ padding-top: 3rem !important;
+ }
+ .pe-lg-0 {
+ padding-right: 0 !important;
+ }
+ .pe-lg-1 {
+ padding-right: 0.25rem !important;
+ }
+ .pe-lg-2 {
+ padding-right: 0.5rem !important;
+ }
+ .pe-lg-3 {
+ padding-right: 1rem !important;
+ }
+ .pe-lg-4 {
+ padding-right: 1.5rem !important;
+ }
+ .pe-lg-5 {
+ padding-right: 3rem !important;
+ }
+ .pb-lg-0 {
+ padding-bottom: 0 !important;
+ }
+ .pb-lg-1 {
+ padding-bottom: 0.25rem !important;
+ }
+ .pb-lg-2 {
+ padding-bottom: 0.5rem !important;
+ }
+ .pb-lg-3 {
+ padding-bottom: 1rem !important;
+ }
+ .pb-lg-4 {
+ padding-bottom: 1.5rem !important;
+ }
+ .pb-lg-5 {
+ padding-bottom: 3rem !important;
+ }
+ .ps-lg-0 {
+ padding-left: 0 !important;
+ }
+ .ps-lg-1 {
+ padding-left: 0.25rem !important;
+ }
+ .ps-lg-2 {
+ padding-left: 0.5rem !important;
+ }
+ .ps-lg-3 {
+ padding-left: 1rem !important;
+ }
+ .ps-lg-4 {
+ padding-left: 1.5rem !important;
+ }
+ .ps-lg-5 {
+ padding-left: 3rem !important;
+ }
+ .text-lg-start {
+ text-align: left !important;
+ }
+ .text-lg-end {
+ text-align: right !important;
+ }
+ .text-lg-center {
+ text-align: center !important;
+ }
+}
+@media (min-width: 1200px) {
+ .float-xl-start {
+ float: left !important;
+ }
+ .float-xl-end {
+ float: right !important;
+ }
+ .float-xl-none {
+ float: none !important;
+ }
+ .d-xl-inline {
+ display: inline !important;
+ }
+ .d-xl-inline-block {
+ display: inline-block !important;
+ }
+ .d-xl-block {
+ display: block !important;
+ }
+ .d-xl-grid {
+ display: grid !important;
+ }
+ .d-xl-table {
+ display: table !important;
+ }
+ .d-xl-table-row {
+ display: table-row !important;
+ }
+ .d-xl-table-cell {
+ display: table-cell !important;
+ }
+ .d-xl-flex {
+ display: flex !important;
+ }
+ .d-xl-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-xl-none {
+ display: none !important;
+ }
+ .flex-xl-fill {
+ flex: 1 1 auto !important;
+ }
+ .flex-xl-row {
+ flex-direction: row !important;
+ }
+ .flex-xl-column {
+ flex-direction: column !important;
+ }
+ .flex-xl-row-reverse {
+ flex-direction: row-reverse !important;
+ }
+ .flex-xl-column-reverse {
+ flex-direction: column-reverse !important;
+ }
+ .flex-xl-grow-0 {
+ flex-grow: 0 !important;
+ }
+ .flex-xl-grow-1 {
+ flex-grow: 1 !important;
+ }
+ .flex-xl-shrink-0 {
+ flex-shrink: 0 !important;
+ }
+ .flex-xl-shrink-1 {
+ flex-shrink: 1 !important;
+ }
+ .flex-xl-wrap {
+ flex-wrap: wrap !important;
+ }
+ .flex-xl-nowrap {
+ flex-wrap: nowrap !important;
+ }
+ .flex-xl-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+ }
+ .gap-xl-0 {
+ gap: 0 !important;
+ }
+ .gap-xl-1 {
+ gap: 0.25rem !important;
+ }
+ .gap-xl-2 {
+ gap: 0.5rem !important;
+ }
+ .gap-xl-3 {
+ gap: 1rem !important;
+ }
+ .gap-xl-4 {
+ gap: 1.5rem !important;
+ }
+ .gap-xl-5 {
+ gap: 3rem !important;
+ }
+ .justify-content-xl-start {
+ justify-content: flex-start !important;
+ }
+ .justify-content-xl-end {
+ justify-content: flex-end !important;
+ }
+ .justify-content-xl-center {
+ justify-content: center !important;
+ }
+ .justify-content-xl-between {
+ justify-content: space-between !important;
+ }
+ .justify-content-xl-around {
+ justify-content: space-around !important;
+ }
+ .justify-content-xl-evenly {
+ justify-content: space-evenly !important;
+ }
+ .align-items-xl-start {
+ align-items: flex-start !important;
+ }
+ .align-items-xl-end {
+ align-items: flex-end !important;
+ }
+ .align-items-xl-center {
+ align-items: center !important;
+ }
+ .align-items-xl-baseline {
+ align-items: baseline !important;
+ }
+ .align-items-xl-stretch {
+ align-items: stretch !important;
+ }
+ .align-content-xl-start {
+ align-content: flex-start !important;
+ }
+ .align-content-xl-end {
+ align-content: flex-end !important;
+ }
+ .align-content-xl-center {
+ align-content: center !important;
+ }
+ .align-content-xl-between {
+ align-content: space-between !important;
+ }
+ .align-content-xl-around {
+ align-content: space-around !important;
+ }
+ .align-content-xl-stretch {
+ align-content: stretch !important;
+ }
+ .align-self-xl-auto {
+ align-self: auto !important;
+ }
+ .align-self-xl-start {
+ align-self: flex-start !important;
+ }
+ .align-self-xl-end {
+ align-self: flex-end !important;
+ }
+ .align-self-xl-center {
+ align-self: center !important;
+ }
+ .align-self-xl-baseline {
+ align-self: baseline !important;
+ }
+ .align-self-xl-stretch {
+ align-self: stretch !important;
+ }
+ .order-xl-first {
+ order: -1 !important;
+ }
+ .order-xl-0 {
+ order: 0 !important;
+ }
+ .order-xl-1 {
+ order: 1 !important;
+ }
+ .order-xl-2 {
+ order: 2 !important;
+ }
+ .order-xl-3 {
+ order: 3 !important;
+ }
+ .order-xl-4 {
+ order: 4 !important;
+ }
+ .order-xl-5 {
+ order: 5 !important;
+ }
+ .order-xl-last {
+ order: 6 !important;
+ }
+ .m-xl-0 {
+ margin: 0 !important;
+ }
+ .m-xl-1 {
+ margin: 0.25rem !important;
+ }
+ .m-xl-2 {
+ margin: 0.5rem !important;
+ }
+ .m-xl-3 {
+ margin: 1rem !important;
+ }
+ .m-xl-4 {
+ margin: 1.5rem !important;
+ }
+ .m-xl-5 {
+ margin: 3rem !important;
+ }
+ .m-xl-auto {
+ margin: auto !important;
+ }
+ .mx-xl-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ }
+ .mx-xl-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+ }
+ .mx-xl-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+ }
+ .mx-xl-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+ }
+ .mx-xl-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+ }
+ .mx-xl-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+ }
+ .mx-xl-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my-xl-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ }
+ .my-xl-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+ }
+ .my-xl-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .my-xl-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+ }
+ .my-xl-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+ }
+ .my-xl-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+ }
+ .my-xl-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ .mt-xl-0 {
+ margin-top: 0 !important;
+ }
+ .mt-xl-1 {
+ margin-top: 0.25rem !important;
+ }
+ .mt-xl-2 {
+ margin-top: 0.5rem !important;
+ }
+ .mt-xl-3 {
+ margin-top: 1rem !important;
+ }
+ .mt-xl-4 {
+ margin-top: 1.5rem !important;
+ }
+ .mt-xl-5 {
+ margin-top: 3rem !important;
+ }
+ .mt-xl-auto {
+ margin-top: auto !important;
+ }
+ .me-xl-0 {
+ margin-right: 0 !important;
+ }
+ .me-xl-1 {
+ margin-right: 0.25rem !important;
+ }
+ .me-xl-2 {
+ margin-right: 0.5rem !important;
+ }
+ .me-xl-3 {
+ margin-right: 1rem !important;
+ }
+ .me-xl-4 {
+ margin-right: 1.5rem !important;
+ }
+ .me-xl-5 {
+ margin-right: 3rem !important;
+ }
+ .me-xl-auto {
+ margin-right: auto !important;
+ }
+ .mb-xl-0 {
+ margin-bottom: 0 !important;
+ }
+ .mb-xl-1 {
+ margin-bottom: 0.25rem !important;
+ }
+ .mb-xl-2 {
+ margin-bottom: 0.5rem !important;
+ }
+ .mb-xl-3 {
+ margin-bottom: 1rem !important;
+ }
+ .mb-xl-4 {
+ margin-bottom: 1.5rem !important;
+ }
+ .mb-xl-5 {
+ margin-bottom: 3rem !important;
+ }
+ .mb-xl-auto {
+ margin-bottom: auto !important;
+ }
+ .ms-xl-0 {
+ margin-left: 0 !important;
+ }
+ .ms-xl-1 {
+ margin-left: 0.25rem !important;
+ }
+ .ms-xl-2 {
+ margin-left: 0.5rem !important;
+ }
+ .ms-xl-3 {
+ margin-left: 1rem !important;
+ }
+ .ms-xl-4 {
+ margin-left: 1.5rem !important;
+ }
+ .ms-xl-5 {
+ margin-left: 3rem !important;
+ }
+ .ms-xl-auto {
+ margin-left: auto !important;
+ }
+ .p-xl-0 {
+ padding: 0 !important;
+ }
+ .p-xl-1 {
+ padding: 0.25rem !important;
+ }
+ .p-xl-2 {
+ padding: 0.5rem !important;
+ }
+ .p-xl-3 {
+ padding: 1rem !important;
+ }
+ .p-xl-4 {
+ padding: 1.5rem !important;
+ }
+ .p-xl-5 {
+ padding: 3rem !important;
+ }
+ .px-xl-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
+ .px-xl-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+ }
+ .px-xl-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+ }
+ .px-xl-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+ }
+ .px-xl-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+ }
+ .px-xl-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+ }
+ .py-xl-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+ .py-xl-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+ }
+ .py-xl-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ }
+ .py-xl-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ }
+ .py-xl-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+ }
+ .py-xl-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+ }
+ .pt-xl-0 {
+ padding-top: 0 !important;
+ }
+ .pt-xl-1 {
+ padding-top: 0.25rem !important;
+ }
+ .pt-xl-2 {
+ padding-top: 0.5rem !important;
+ }
+ .pt-xl-3 {
+ padding-top: 1rem !important;
+ }
+ .pt-xl-4 {
+ padding-top: 1.5rem !important;
+ }
+ .pt-xl-5 {
+ padding-top: 3rem !important;
+ }
+ .pe-xl-0 {
+ padding-right: 0 !important;
+ }
+ .pe-xl-1 {
+ padding-right: 0.25rem !important;
+ }
+ .pe-xl-2 {
+ padding-right: 0.5rem !important;
+ }
+ .pe-xl-3 {
+ padding-right: 1rem !important;
+ }
+ .pe-xl-4 {
+ padding-right: 1.5rem !important;
+ }
+ .pe-xl-5 {
+ padding-right: 3rem !important;
+ }
+ .pb-xl-0 {
+ padding-bottom: 0 !important;
+ }
+ .pb-xl-1 {
+ padding-bottom: 0.25rem !important;
+ }
+ .pb-xl-2 {
+ padding-bottom: 0.5rem !important;
+ }
+ .pb-xl-3 {
+ padding-bottom: 1rem !important;
+ }
+ .pb-xl-4 {
+ padding-bottom: 1.5rem !important;
+ }
+ .pb-xl-5 {
+ padding-bottom: 3rem !important;
+ }
+ .ps-xl-0 {
+ padding-left: 0 !important;
+ }
+ .ps-xl-1 {
+ padding-left: 0.25rem !important;
+ }
+ .ps-xl-2 {
+ padding-left: 0.5rem !important;
+ }
+ .ps-xl-3 {
+ padding-left: 1rem !important;
+ }
+ .ps-xl-4 {
+ padding-left: 1.5rem !important;
+ }
+ .ps-xl-5 {
+ padding-left: 3rem !important;
+ }
+ .text-xl-start {
+ text-align: left !important;
+ }
+ .text-xl-end {
+ text-align: right !important;
+ }
+ .text-xl-center {
+ text-align: center !important;
+ }
+}
+@media (min-width: 1400px) {
+ .float-xxl-start {
+ float: left !important;
+ }
+ .float-xxl-end {
+ float: right !important;
+ }
+ .float-xxl-none {
+ float: none !important;
+ }
+ .d-xxl-inline {
+ display: inline !important;
+ }
+ .d-xxl-inline-block {
+ display: inline-block !important;
+ }
+ .d-xxl-block {
+ display: block !important;
+ }
+ .d-xxl-grid {
+ display: grid !important;
+ }
+ .d-xxl-table {
+ display: table !important;
+ }
+ .d-xxl-table-row {
+ display: table-row !important;
+ }
+ .d-xxl-table-cell {
+ display: table-cell !important;
+ }
+ .d-xxl-flex {
+ display: flex !important;
+ }
+ .d-xxl-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-xxl-none {
+ display: none !important;
+ }
+ .flex-xxl-fill {
+ flex: 1 1 auto !important;
+ }
+ .flex-xxl-row {
+ flex-direction: row !important;
+ }
+ .flex-xxl-column {
+ flex-direction: column !important;
+ }
+ .flex-xxl-row-reverse {
+ flex-direction: row-reverse !important;
+ }
+ .flex-xxl-column-reverse {
+ flex-direction: column-reverse !important;
+ }
+ .flex-xxl-grow-0 {
+ flex-grow: 0 !important;
+ }
+ .flex-xxl-grow-1 {
+ flex-grow: 1 !important;
+ }
+ .flex-xxl-shrink-0 {
+ flex-shrink: 0 !important;
+ }
+ .flex-xxl-shrink-1 {
+ flex-shrink: 1 !important;
+ }
+ .flex-xxl-wrap {
+ flex-wrap: wrap !important;
+ }
+ .flex-xxl-nowrap {
+ flex-wrap: nowrap !important;
+ }
+ .flex-xxl-wrap-reverse {
+ flex-wrap: wrap-reverse !important;
+ }
+ .gap-xxl-0 {
+ gap: 0 !important;
+ }
+ .gap-xxl-1 {
+ gap: 0.25rem !important;
+ }
+ .gap-xxl-2 {
+ gap: 0.5rem !important;
+ }
+ .gap-xxl-3 {
+ gap: 1rem !important;
+ }
+ .gap-xxl-4 {
+ gap: 1.5rem !important;
+ }
+ .gap-xxl-5 {
+ gap: 3rem !important;
+ }
+ .justify-content-xxl-start {
+ justify-content: flex-start !important;
+ }
+ .justify-content-xxl-end {
+ justify-content: flex-end !important;
+ }
+ .justify-content-xxl-center {
+ justify-content: center !important;
+ }
+ .justify-content-xxl-between {
+ justify-content: space-between !important;
+ }
+ .justify-content-xxl-around {
+ justify-content: space-around !important;
+ }
+ .justify-content-xxl-evenly {
+ justify-content: space-evenly !important;
+ }
+ .align-items-xxl-start {
+ align-items: flex-start !important;
+ }
+ .align-items-xxl-end {
+ align-items: flex-end !important;
+ }
+ .align-items-xxl-center {
+ align-items: center !important;
+ }
+ .align-items-xxl-baseline {
+ align-items: baseline !important;
+ }
+ .align-items-xxl-stretch {
+ align-items: stretch !important;
+ }
+ .align-content-xxl-start {
+ align-content: flex-start !important;
+ }
+ .align-content-xxl-end {
+ align-content: flex-end !important;
+ }
+ .align-content-xxl-center {
+ align-content: center !important;
+ }
+ .align-content-xxl-between {
+ align-content: space-between !important;
+ }
+ .align-content-xxl-around {
+ align-content: space-around !important;
+ }
+ .align-content-xxl-stretch {
+ align-content: stretch !important;
+ }
+ .align-self-xxl-auto {
+ align-self: auto !important;
+ }
+ .align-self-xxl-start {
+ align-self: flex-start !important;
+ }
+ .align-self-xxl-end {
+ align-self: flex-end !important;
+ }
+ .align-self-xxl-center {
+ align-self: center !important;
+ }
+ .align-self-xxl-baseline {
+ align-self: baseline !important;
+ }
+ .align-self-xxl-stretch {
+ align-self: stretch !important;
+ }
+ .order-xxl-first {
+ order: -1 !important;
+ }
+ .order-xxl-0 {
+ order: 0 !important;
+ }
+ .order-xxl-1 {
+ order: 1 !important;
+ }
+ .order-xxl-2 {
+ order: 2 !important;
+ }
+ .order-xxl-3 {
+ order: 3 !important;
+ }
+ .order-xxl-4 {
+ order: 4 !important;
+ }
+ .order-xxl-5 {
+ order: 5 !important;
+ }
+ .order-xxl-last {
+ order: 6 !important;
+ }
+ .m-xxl-0 {
+ margin: 0 !important;
+ }
+ .m-xxl-1 {
+ margin: 0.25rem !important;
+ }
+ .m-xxl-2 {
+ margin: 0.5rem !important;
+ }
+ .m-xxl-3 {
+ margin: 1rem !important;
+ }
+ .m-xxl-4 {
+ margin: 1.5rem !important;
+ }
+ .m-xxl-5 {
+ margin: 3rem !important;
+ }
+ .m-xxl-auto {
+ margin: auto !important;
+ }
+ .mx-xxl-0 {
+ margin-right: 0 !important;
+ margin-left: 0 !important;
+ }
+ .mx-xxl-1 {
+ margin-right: 0.25rem !important;
+ margin-left: 0.25rem !important;
+ }
+ .mx-xxl-2 {
+ margin-right: 0.5rem !important;
+ margin-left: 0.5rem !important;
+ }
+ .mx-xxl-3 {
+ margin-right: 1rem !important;
+ margin-left: 1rem !important;
+ }
+ .mx-xxl-4 {
+ margin-right: 1.5rem !important;
+ margin-left: 1.5rem !important;
+ }
+ .mx-xxl-5 {
+ margin-right: 3rem !important;
+ margin-left: 3rem !important;
+ }
+ .mx-xxl-auto {
+ margin-right: auto !important;
+ margin-left: auto !important;
+ }
+ .my-xxl-0 {
+ margin-top: 0 !important;
+ margin-bottom: 0 !important;
+ }
+ .my-xxl-1 {
+ margin-top: 0.25rem !important;
+ margin-bottom: 0.25rem !important;
+ }
+ .my-xxl-2 {
+ margin-top: 0.5rem !important;
+ margin-bottom: 0.5rem !important;
+ }
+ .my-xxl-3 {
+ margin-top: 1rem !important;
+ margin-bottom: 1rem !important;
+ }
+ .my-xxl-4 {
+ margin-top: 1.5rem !important;
+ margin-bottom: 1.5rem !important;
+ }
+ .my-xxl-5 {
+ margin-top: 3rem !important;
+ margin-bottom: 3rem !important;
+ }
+ .my-xxl-auto {
+ margin-top: auto !important;
+ margin-bottom: auto !important;
+ }
+ .mt-xxl-0 {
+ margin-top: 0 !important;
+ }
+ .mt-xxl-1 {
+ margin-top: 0.25rem !important;
+ }
+ .mt-xxl-2 {
+ margin-top: 0.5rem !important;
+ }
+ .mt-xxl-3 {
+ margin-top: 1rem !important;
+ }
+ .mt-xxl-4 {
+ margin-top: 1.5rem !important;
+ }
+ .mt-xxl-5 {
+ margin-top: 3rem !important;
+ }
+ .mt-xxl-auto {
+ margin-top: auto !important;
+ }
+ .me-xxl-0 {
+ margin-right: 0 !important;
+ }
+ .me-xxl-1 {
+ margin-right: 0.25rem !important;
+ }
+ .me-xxl-2 {
+ margin-right: 0.5rem !important;
+ }
+ .me-xxl-3 {
+ margin-right: 1rem !important;
+ }
+ .me-xxl-4 {
+ margin-right: 1.5rem !important;
+ }
+ .me-xxl-5 {
+ margin-right: 3rem !important;
+ }
+ .me-xxl-auto {
+ margin-right: auto !important;
+ }
+ .mb-xxl-0 {
+ margin-bottom: 0 !important;
+ }
+ .mb-xxl-1 {
+ margin-bottom: 0.25rem !important;
+ }
+ .mb-xxl-2 {
+ margin-bottom: 0.5rem !important;
+ }
+ .mb-xxl-3 {
+ margin-bottom: 1rem !important;
+ }
+ .mb-xxl-4 {
+ margin-bottom: 1.5rem !important;
+ }
+ .mb-xxl-5 {
+ margin-bottom: 3rem !important;
+ }
+ .mb-xxl-auto {
+ margin-bottom: auto !important;
+ }
+ .ms-xxl-0 {
+ margin-left: 0 !important;
+ }
+ .ms-xxl-1 {
+ margin-left: 0.25rem !important;
+ }
+ .ms-xxl-2 {
+ margin-left: 0.5rem !important;
+ }
+ .ms-xxl-3 {
+ margin-left: 1rem !important;
+ }
+ .ms-xxl-4 {
+ margin-left: 1.5rem !important;
+ }
+ .ms-xxl-5 {
+ margin-left: 3rem !important;
+ }
+ .ms-xxl-auto {
+ margin-left: auto !important;
+ }
+ .p-xxl-0 {
+ padding: 0 !important;
+ }
+ .p-xxl-1 {
+ padding: 0.25rem !important;
+ }
+ .p-xxl-2 {
+ padding: 0.5rem !important;
+ }
+ .p-xxl-3 {
+ padding: 1rem !important;
+ }
+ .p-xxl-4 {
+ padding: 1.5rem !important;
+ }
+ .p-xxl-5 {
+ padding: 3rem !important;
+ }
+ .px-xxl-0 {
+ padding-right: 0 !important;
+ padding-left: 0 !important;
+ }
+ .px-xxl-1 {
+ padding-right: 0.25rem !important;
+ padding-left: 0.25rem !important;
+ }
+ .px-xxl-2 {
+ padding-right: 0.5rem !important;
+ padding-left: 0.5rem !important;
+ }
+ .px-xxl-3 {
+ padding-right: 1rem !important;
+ padding-left: 1rem !important;
+ }
+ .px-xxl-4 {
+ padding-right: 1.5rem !important;
+ padding-left: 1.5rem !important;
+ }
+ .px-xxl-5 {
+ padding-right: 3rem !important;
+ padding-left: 3rem !important;
+ }
+ .py-xxl-0 {
+ padding-top: 0 !important;
+ padding-bottom: 0 !important;
+ }
+ .py-xxl-1 {
+ padding-top: 0.25rem !important;
+ padding-bottom: 0.25rem !important;
+ }
+ .py-xxl-2 {
+ padding-top: 0.5rem !important;
+ padding-bottom: 0.5rem !important;
+ }
+ .py-xxl-3 {
+ padding-top: 1rem !important;
+ padding-bottom: 1rem !important;
+ }
+ .py-xxl-4 {
+ padding-top: 1.5rem !important;
+ padding-bottom: 1.5rem !important;
+ }
+ .py-xxl-5 {
+ padding-top: 3rem !important;
+ padding-bottom: 3rem !important;
+ }
+ .pt-xxl-0 {
+ padding-top: 0 !important;
+ }
+ .pt-xxl-1 {
+ padding-top: 0.25rem !important;
+ }
+ .pt-xxl-2 {
+ padding-top: 0.5rem !important;
+ }
+ .pt-xxl-3 {
+ padding-top: 1rem !important;
+ }
+ .pt-xxl-4 {
+ padding-top: 1.5rem !important;
+ }
+ .pt-xxl-5 {
+ padding-top: 3rem !important;
+ }
+ .pe-xxl-0 {
+ padding-right: 0 !important;
+ }
+ .pe-xxl-1 {
+ padding-right: 0.25rem !important;
+ }
+ .pe-xxl-2 {
+ padding-right: 0.5rem !important;
+ }
+ .pe-xxl-3 {
+ padding-right: 1rem !important;
+ }
+ .pe-xxl-4 {
+ padding-right: 1.5rem !important;
+ }
+ .pe-xxl-5 {
+ padding-right: 3rem !important;
+ }
+ .pb-xxl-0 {
+ padding-bottom: 0 !important;
+ }
+ .pb-xxl-1 {
+ padding-bottom: 0.25rem !important;
+ }
+ .pb-xxl-2 {
+ padding-bottom: 0.5rem !important;
+ }
+ .pb-xxl-3 {
+ padding-bottom: 1rem !important;
+ }
+ .pb-xxl-4 {
+ padding-bottom: 1.5rem !important;
+ }
+ .pb-xxl-5 {
+ padding-bottom: 3rem !important;
+ }
+ .ps-xxl-0 {
+ padding-left: 0 !important;
+ }
+ .ps-xxl-1 {
+ padding-left: 0.25rem !important;
+ }
+ .ps-xxl-2 {
+ padding-left: 0.5rem !important;
+ }
+ .ps-xxl-3 {
+ padding-left: 1rem !important;
+ }
+ .ps-xxl-4 {
+ padding-left: 1.5rem !important;
+ }
+ .ps-xxl-5 {
+ padding-left: 3rem !important;
+ }
+ .text-xxl-start {
+ text-align: left !important;
+ }
+ .text-xxl-end {
+ text-align: right !important;
+ }
+ .text-xxl-center {
+ text-align: center !important;
+ }
+}
+@media (min-width: 1200px) {
+ .fs-1 {
+ font-size: 2.5rem !important;
+ }
+ .fs-2 {
+ font-size: 2rem !important;
+ }
+ .fs-3 {
+ font-size: 1.75rem !important;
+ }
+ .fs-4 {
+ font-size: 1.5rem !important;
+ }
+}
+@media print {
+ .d-print-inline {
+ display: inline !important;
+ }
+ .d-print-inline-block {
+ display: inline-block !important;
+ }
+ .d-print-block {
+ display: block !important;
+ }
+ .d-print-grid {
+ display: grid !important;
+ }
+ .d-print-table {
+ display: table !important;
+ }
+ .d-print-table-row {
+ display: table-row !important;
+ }
+ .d-print-table-cell {
+ display: table-cell !important;
+ }
+ .d-print-flex {
+ display: flex !important;
+ }
+ .d-print-inline-flex {
+ display: inline-flex !important;
+ }
+ .d-print-none {
+ display: none !important;
+ }
+}
+@font-face {
+ font-family: Pe-icon-7-stroke;
+ src: url(../../fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.eot?d7yf1v);
+ src: url(../../fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.eot?#iefixd7yf1v) format('embedded-opentype'),
+ url(../../fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.woff?d7yf1v) format('woff'),
+ url(../../fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.ttf?d7yf1v) format('truetype'),
+ url(../../fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.svg?d7yf1v#Pe-icon-7-stroke) format('svg');
+ font-weight: 400;
+ font-style: normal;
+}
+[class*=' pe-7s-'],
+[class^='pe-7s-'] {
+ display: inline-block;
+ font-family: Pe-icon-7-stroke;
+ speak: none;
+ font-style: normal;
+ font-weight: 400;
+ font-variant: normal;
+ text-transform: none;
+ line-height: 1;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+.pe-7s-album:before {
+ content: '\e6aa';
+}
+.pe-7s-arc:before {
+ content: '\e6ab';
+}
+.pe-7s-back-2:before {
+ content: '\e6ac';
+}
+.pe-7s-bandaid:before {
+ content: '\e6ad';
+}
+.pe-7s-car:before {
+ content: '\e6ae';
+}
+.pe-7s-diamond:before {
+ content: '\e6af';
+}
+.pe-7s-door-lock:before {
+ content: '\e6b0';
+}
+.pe-7s-eyedropper:before {
+ content: '\e6b1';
+}
+.pe-7s-female:before {
+ content: '\e6b2';
+}
+.pe-7s-gym:before {
+ content: '\e6b3';
+}
+.pe-7s-hammer:before {
+ content: '\e6b4';
+}
+.pe-7s-headphones:before {
+ content: '\e6b5';
+}
+.pe-7s-helm:before {
+ content: '\e6b6';
+}
+.pe-7s-hourglass:before {
+ content: '\e6b7';
+}
+.pe-7s-leaf:before {
+ content: '\e6b8';
+}
+.pe-7s-magic-wand:before {
+ content: '\e6b9';
+}
+.pe-7s-male:before {
+ content: '\e6ba';
+}
+.pe-7s-map-2:before {
+ content: '\e6bb';
+}
+.pe-7s-next-2:before {
+ content: '\e6bc';
+}
+.pe-7s-paint-bucket:before {
+ content: '\e6bd';
+}
+.pe-7s-pendrive:before {
+ content: '\e6be';
+}
+.pe-7s-photo:before {
+ content: '\e6bf';
+}
+.pe-7s-piggy:before {
+ content: '\e6c0';
+}
+.pe-7s-plugin:before {
+ content: '\e6c1';
+}
+.pe-7s-refresh-2:before {
+ content: '\e6c2';
+}
+.pe-7s-rocket:before {
+ content: '\e6c3';
+}
+.pe-7s-settings:before {
+ content: '\e6c4';
+}
+.pe-7s-shield:before {
+ content: '\e6c5';
+}
+.pe-7s-smile:before {
+ content: '\e6c6';
+}
+.pe-7s-usb:before {
+ content: '\e6c7';
+}
+.pe-7s-vector:before {
+ content: '\e6c8';
+}
+.pe-7s-wine:before {
+ content: '\e6c9';
+}
+.pe-7s-cloud-upload:before {
+ content: '\e68a';
+}
+.pe-7s-cash:before {
+ content: '\e68c';
+}
+.pe-7s-close:before {
+ content: '\e680';
+}
+.pe-7s-bluetooth:before {
+ content: '\e68d';
+}
+.pe-7s-cloud-download:before {
+ content: '\e68b';
+}
+.pe-7s-way:before {
+ content: '\e68e';
+}
+.pe-7s-close-circle:before {
+ content: '\e681';
+}
+.pe-7s-id:before {
+ content: '\e68f';
+}
+.pe-7s-angle-up:before {
+ content: '\e682';
+}
+.pe-7s-wristwatch:before {
+ content: '\e690';
+}
+.pe-7s-angle-up-circle:before {
+ content: '\e683';
+}
+.pe-7s-world:before {
+ content: '\e691';
+}
+.pe-7s-angle-right:before {
+ content: '\e684';
+}
+.pe-7s-volume:before {
+ content: '\e692';
+}
+.pe-7s-angle-right-circle:before {
+ content: '\e685';
+}
+.pe-7s-users:before {
+ content: '\e693';
+}
+.pe-7s-angle-left:before {
+ content: '\e686';
+}
+.pe-7s-user-female:before {
+ content: '\e694';
+}
+.pe-7s-angle-left-circle:before {
+ content: '\e687';
+}
+.pe-7s-up-arrow:before {
+ content: '\e695';
+}
+.pe-7s-angle-down:before {
+ content: '\e688';
+}
+.pe-7s-switch:before {
+ content: '\e696';
+}
+.pe-7s-angle-down-circle:before {
+ content: '\e689';
+}
+.pe-7s-scissors:before {
+ content: '\e697';
+}
+.pe-7s-wallet:before {
+ content: '\e600';
+}
+.pe-7s-safe:before {
+ content: '\e698';
+}
+.pe-7s-volume2:before {
+ content: '\e601';
+}
+.pe-7s-volume1:before {
+ content: '\e602';
+}
+.pe-7s-voicemail:before {
+ content: '\e603';
+}
+.pe-7s-video:before {
+ content: '\e604';
+}
+.pe-7s-user:before {
+ content: '\e605';
+}
+.pe-7s-upload:before {
+ content: '\e606';
+}
+.pe-7s-unlock:before {
+ content: '\e607';
+}
+.pe-7s-umbrella:before {
+ content: '\e608';
+}
+.pe-7s-trash:before {
+ content: '\e609';
+}
+.pe-7s-tools:before {
+ content: '\e60a';
+}
+.pe-7s-timer:before {
+ content: '\e60b';
+}
+.pe-7s-ticket:before {
+ content: '\e60c';
+}
+.pe-7s-target:before {
+ content: '\e60d';
+}
+.pe-7s-sun:before {
+ content: '\e60e';
+}
+.pe-7s-study:before {
+ content: '\e60f';
+}
+.pe-7s-stopwatch:before {
+ content: '\e610';
+}
+.pe-7s-star:before {
+ content: '\e611';
+}
+.pe-7s-speaker:before {
+ content: '\e612';
+}
+.pe-7s-signal:before {
+ content: '\e613';
+}
+.pe-7s-shuffle:before {
+ content: '\e614';
+}
+.pe-7s-shopbag:before {
+ content: '\e615';
+}
+.pe-7s-share:before {
+ content: '\e616';
+}
+.pe-7s-server:before {
+ content: '\e617';
+}
+.pe-7s-search:before {
+ content: '\e618';
+}
+.pe-7s-film:before {
+ content: '\e6a5';
+}
+.pe-7s-science:before {
+ content: '\e619';
+}
+.pe-7s-disk:before {
+ content: '\e6a6';
+}
+.pe-7s-ribbon:before {
+ content: '\e61a';
+}
+.pe-7s-repeat:before {
+ content: '\e61b';
+}
+.pe-7s-refresh:before {
+ content: '\e61c';
+}
+.pe-7s-add-user:before {
+ content: '\e6a9';
+}
+.pe-7s-refresh-cloud:before {
+ content: '\e61d';
+}
+.pe-7s-paperclip:before {
+ content: '\e69c';
+}
+.pe-7s-radio:before {
+ content: '\e61e';
+}
+.pe-7s-note2:before {
+ content: '\e69d';
+}
+.pe-7s-print:before {
+ content: '\e61f';
+}
+.pe-7s-network:before {
+ content: '\e69e';
+}
+.pe-7s-prev:before {
+ content: '\e620';
+}
+.pe-7s-mute:before {
+ content: '\e69f';
+}
+.pe-7s-power:before {
+ content: '\e621';
+}
+.pe-7s-medal:before {
+ content: '\e6a0';
+}
+.pe-7s-portfolio:before {
+ content: '\e622';
+}
+.pe-7s-like2:before {
+ content: '\e6a1';
+}
+.pe-7s-plus:before {
+ content: '\e623';
+}
+.pe-7s-left-arrow:before {
+ content: '\e6a2';
+}
+.pe-7s-play:before {
+ content: '\e624';
+}
+.pe-7s-key:before {
+ content: '\e6a3';
+}
+.pe-7s-plane:before {
+ content: '\e625';
+}
+.pe-7s-joy:before {
+ content: '\e6a4';
+}
+.pe-7s-photo-gallery:before {
+ content: '\e626';
+}
+.pe-7s-pin:before {
+ content: '\e69b';
+}
+.pe-7s-phone:before {
+ content: '\e627';
+}
+.pe-7s-plug:before {
+ content: '\e69a';
+}
+.pe-7s-pen:before {
+ content: '\e628';
+}
+.pe-7s-right-arrow:before {
+ content: '\e699';
+}
+.pe-7s-paper-plane:before {
+ content: '\e629';
+}
+.pe-7s-delete-user:before {
+ content: '\e6a7';
+}
+.pe-7s-paint:before {
+ content: '\e62a';
+}
+.pe-7s-bottom-arrow:before {
+ content: '\e6a8';
+}
+.pe-7s-notebook:before {
+ content: '\e62b';
+}
+.pe-7s-note:before {
+ content: '\e62c';
+}
+.pe-7s-next:before {
+ content: '\e62d';
+}
+.pe-7s-news-paper:before {
+ content: '\e62e';
+}
+.pe-7s-musiclist:before {
+ content: '\e62f';
+}
+.pe-7s-music:before {
+ content: '\e630';
+}
+.pe-7s-mouse:before {
+ content: '\e631';
+}
+.pe-7s-more:before {
+ content: '\e632';
+}
+.pe-7s-moon:before {
+ content: '\e633';
+}
+.pe-7s-monitor:before {
+ content: '\e634';
+}
+.pe-7s-micro:before {
+ content: '\e635';
+}
+.pe-7s-menu:before {
+ content: '\e636';
+}
+.pe-7s-map:before {
+ content: '\e637';
+}
+.pe-7s-map-marker:before {
+ content: '\e638';
+}
+.pe-7s-mail:before {
+ content: '\e639';
+}
+.pe-7s-mail-open:before {
+ content: '\e63a';
+}
+.pe-7s-mail-open-file:before {
+ content: '\e63b';
+}
+.pe-7s-magnet:before {
+ content: '\e63c';
+}
+.pe-7s-loop:before {
+ content: '\e63d';
+}
+.pe-7s-look:before {
+ content: '\e63e';
+}
+.pe-7s-lock:before {
+ content: '\e63f';
+}
+.pe-7s-lintern:before {
+ content: '\e640';
+}
+.pe-7s-link:before {
+ content: '\e641';
+}
+.pe-7s-like:before {
+ content: '\e642';
+}
+.pe-7s-light:before {
+ content: '\e643';
+}
+.pe-7s-less:before {
+ content: '\e644';
+}
+.pe-7s-keypad:before {
+ content: '\e645';
+}
+.pe-7s-junk:before {
+ content: '\e646';
+}
+.pe-7s-info:before {
+ content: '\e647';
+}
+.pe-7s-home:before {
+ content: '\e648';
+}
+.pe-7s-help2:before {
+ content: '\e649';
+}
+.pe-7s-help1:before {
+ content: '\e64a';
+}
+.pe-7s-graph3:before {
+ content: '\e64b';
+}
+.pe-7s-graph2:before {
+ content: '\e64c';
+}
+.pe-7s-graph1:before {
+ content: '\e64d';
+}
+.pe-7s-graph:before {
+ content: '\e64e';
+}
+.pe-7s-global:before {
+ content: '\e64f';
+}
+.pe-7s-gleam:before {
+ content: '\e650';
+}
+.pe-7s-glasses:before {
+ content: '\e651';
+}
+.pe-7s-gift:before {
+ content: '\e652';
+}
+.pe-7s-folder:before {
+ content: '\e653';
+}
+.pe-7s-flag:before {
+ content: '\e654';
+}
+.pe-7s-filter:before {
+ content: '\e655';
+}
+.pe-7s-file:before {
+ content: '\e656';
+}
+.pe-7s-expand1:before {
+ content: '\e657';
+}
+.pe-7s-exapnd2:before {
+ content: '\e658';
+}
+.pe-7s-edit:before {
+ content: '\e659';
+}
+.pe-7s-drop:before {
+ content: '\e65a';
+}
+.pe-7s-drawer:before {
+ content: '\e65b';
+}
+.pe-7s-download:before {
+ content: '\e65c';
+}
+.pe-7s-display2:before {
+ content: '\e65d';
+}
+.pe-7s-display1:before {
+ content: '\e65e';
+}
+.pe-7s-diskette:before {
+ content: '\e65f';
+}
+.pe-7s-date:before {
+ content: '\e660';
+}
+.pe-7s-cup:before {
+ content: '\e661';
+}
+.pe-7s-culture:before {
+ content: '\e662';
+}
+.pe-7s-crop:before {
+ content: '\e663';
+}
+.pe-7s-credit:before {
+ content: '\e664';
+}
+.pe-7s-copy-file:before {
+ content: '\e665';
+}
+.pe-7s-config:before {
+ content: '\e666';
+}
+.pe-7s-compass:before {
+ content: '\e667';
+}
+.pe-7s-comment:before {
+ content: '\e668';
+}
+.pe-7s-coffee:before {
+ content: '\e669';
+}
+.pe-7s-cloud:before {
+ content: '\e66a';
+}
+.pe-7s-clock:before {
+ content: '\e66b';
+}
+.pe-7s-check:before {
+ content: '\e66c';
+}
+.pe-7s-chat:before {
+ content: '\e66d';
+}
+.pe-7s-cart:before {
+ content: '\e66e';
+}
+.pe-7s-camera:before {
+ content: '\e66f';
+}
+.pe-7s-call:before {
+ content: '\e670';
+}
+.pe-7s-calculator:before {
+ content: '\e671';
+}
+.pe-7s-browser:before {
+ content: '\e672';
+}
+.pe-7s-box2:before {
+ content: '\e673';
+}
+.pe-7s-box1:before {
+ content: '\e674';
+}
+.pe-7s-bookmarks:before {
+ content: '\e675';
+}
+.pe-7s-bicycle:before {
+ content: '\e676';
+}
+.pe-7s-bell:before {
+ content: '\e677';
+}
+.pe-7s-battery:before {
+ content: '\e678';
+}
+.pe-7s-ball:before {
+ content: '\e679';
+}
+.pe-7s-back:before {
+ content: '\e67a';
+}
+.pe-7s-attention:before {
+ content: '\e67b';
+}
+.pe-7s-anchor:before {
+ content: '\e67c';
+}
+.pe-7s-albums:before {
+ content: '\e67d';
+}
+.pe-7s-alarm:before {
+ content: '\e67e';
+}
+.pe-7s-airplay:before {
+ content: '\e67f';
+} /*!
+ * Font Awesome 4.7.0 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/fontawesome-webfont.eot?v=4.7.0');
+ src: url('../../fonts/FontAwesome/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),
+ url('../../fonts/FontAwesome/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),
+ url('../../fonts/FontAwesome/fontawesome-webfont.woff?v=4.7.0') format('woff'),
+ url('../../fonts/FontAwesome/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),
+ url('../../fonts/FontAwesome/fontawesome-webfont.svg?v=4.7.0#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: 0.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: 0.14285714em;
+ text-align: center;
+}
+.fa-li.fa-lg {
+ left: -1.85714286em;
+}
+.fa-border {
+ padding: 0.2em 0.25em 0.15em;
+ border: solid 0.08em #eee;
+ border-radius: 0.1em;
+}
+.fa-pull-left {
+ float: left;
+}
+.fa-pull-right {
+ float: right;
+}
+.fa.fa-pull-left {
+ margin-right: 0.3em;
+}
+.fa.fa-pull-right {
+ margin-left: 0.3em;
+}
+.pull-right {
+ float: right;
+}
+.pull-left {
+ float: left;
+}
+.fa.pull-left {
+ margin-right: 0.3em;
+}
+.fa.pull-right {
+ margin-left: 0.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);
+ transform: rotate(90deg);
+}
+.fa-rotate-180 {
+ -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=2)';
+ -webkit-transform: rotate(180deg);
+ transform: rotate(180deg);
+}
+.fa-rotate-270 {
+ -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=3)';
+ -webkit-transform: rotate(270deg);
+ transform: rotate(270deg);
+}
+.fa-flip-horizontal {
+ -ms-filter: 'progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)';
+ -webkit-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);
+ transform: scale(1, -1);
+}
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+ -webkit-filter: none;
+ 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-pp: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-resistance: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: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';
+}
+.fa-pied-piper:before {
+ content: '\f2ae';
+}
+.fa-first-order:before {
+ content: '\f2b0';
+}
+.fa-yoast:before {
+ content: '\f2b1';
+}
+.fa-themeisle:before {
+ content: '\f2b2';
+}
+.fa-google-plus-circle:before,
+.fa-google-plus-official:before {
+ content: '\f2b3';
+}
+.fa-fa:before,
+.fa-font-awesome:before {
+ content: '\f2b4';
+}
+.fa-handshake-o:before {
+ content: '\f2b5';
+}
+.fa-envelope-open:before {
+ content: '\f2b6';
+}
+.fa-envelope-open-o:before {
+ content: '\f2b7';
+}
+.fa-linode:before {
+ content: '\f2b8';
+}
+.fa-address-book:before {
+ content: '\f2b9';
+}
+.fa-address-book-o:before {
+ content: '\f2ba';
+}
+.fa-vcard:before,
+.fa-address-card:before {
+ content: '\f2bb';
+}
+.fa-vcard-o:before,
+.fa-address-card-o:before {
+ content: '\f2bc';
+}
+.fa-user-circle:before {
+ content: '\f2bd';
+}
+.fa-user-circle-o:before {
+ content: '\f2be';
+}
+.fa-user-o:before {
+ content: '\f2c0';
+}
+.fa-id-badge:before {
+ content: '\f2c1';
+}
+.fa-drivers-license:before,
+.fa-id-card:before {
+ content: '\f2c2';
+}
+.fa-drivers-license-o:before,
+.fa-id-card-o:before {
+ content: '\f2c3';
+}
+.fa-quora:before {
+ content: '\f2c4';
+}
+.fa-free-code-camp:before {
+ content: '\f2c5';
+}
+.fa-telegram:before {
+ content: '\f2c6';
+}
+.fa-thermometer-4:before,
+.fa-thermometer:before,
+.fa-thermometer-full:before {
+ content: '\f2c7';
+}
+.fa-thermometer-3:before,
+.fa-thermometer-three-quarters:before {
+ content: '\f2c8';
+}
+.fa-thermometer-2:before,
+.fa-thermometer-half:before {
+ content: '\f2c9';
+}
+.fa-thermometer-1:before,
+.fa-thermometer-quarter:before {
+ content: '\f2ca';
+}
+.fa-thermometer-0:before,
+.fa-thermometer-empty:before {
+ content: '\f2cb';
+}
+.fa-shower:before {
+ content: '\f2cc';
+}
+.fa-bathtub:before,
+.fa-s15:before,
+.fa-bath:before {
+ content: '\f2cd';
+}
+.fa-podcast:before {
+ content: '\f2ce';
+}
+.fa-window-maximize:before {
+ content: '\f2d0';
+}
+.fa-window-minimize:before {
+ content: '\f2d1';
+}
+.fa-window-restore:before {
+ content: '\f2d2';
+}
+.fa-times-rectangle:before,
+.fa-window-close:before {
+ content: '\f2d3';
+}
+.fa-times-rectangle-o:before,
+.fa-window-close-o:before {
+ content: '\f2d4';
+}
+.fa-bandcamp:before {
+ content: '\f2d5';
+}
+.fa-grav:before {
+ content: '\f2d6';
+}
+.fa-etsy:before {
+ content: '\f2d7';
+}
+.fa-imdb:before {
+ content: '\f2d8';
+}
+.fa-ravelry:before {
+ content: '\f2d9';
+}
+.fa-eercast:before {
+ content: '\f2da';
+}
+.fa-microchip:before {
+ content: '\f2db';
+}
+.fa-snowflake-o:before {
+ content: '\f2dc';
+}
+.fa-superpowers:before {
+ content: '\f2dd';
+}
+.fa-wpexplorer:before {
+ content: '\f2de';
+}
+.fa-meetup:before {
+ content: '\f2e0';
+}
+.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/public/assets/fonts/FontAwesome/fontawesome-webfont.woff2 b/public/assets/fonts/FontAwesome/fontawesome-webfont.woff2
new file mode 100644
index 0000000..4d13fc6
Binary files /dev/null and b/public/assets/fonts/FontAwesome/fontawesome-webfont.woff2 differ
diff --git a/public/assets/fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.woff b/public/assets/fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.woff
new file mode 100644
index 0000000..c205e6f
Binary files /dev/null and b/public/assets/fonts/Pe-icon-7-stroke/Pe-icon-7-stroke.woff differ
diff --git a/public/assets/images/Youtube.png b/public/assets/images/Youtube.png
new file mode 100644
index 0000000..83b57aa
Binary files /dev/null and b/public/assets/images/Youtube.png differ
diff --git a/public/assets/images/about-banner.jpg b/public/assets/images/about-banner.jpg
new file mode 100644
index 0000000..a15b9c5
Binary files /dev/null and b/public/assets/images/about-banner.jpg differ
diff --git a/public/assets/images/about-img01.jpg b/public/assets/images/about-img01.jpg
new file mode 100644
index 0000000..f4d238e
Binary files /dev/null and b/public/assets/images/about-img01.jpg differ
diff --git a/public/assets/images/about-img02.jpg b/public/assets/images/about-img02.jpg
new file mode 100644
index 0000000..19c8d2a
Binary files /dev/null and b/public/assets/images/about-img02.jpg differ
diff --git a/public/assets/images/about-img03.jpg b/public/assets/images/about-img03.jpg
new file mode 100644
index 0000000..5cfdb54
Binary files /dev/null and b/public/assets/images/about-img03.jpg differ
diff --git a/public/assets/images/about-img04.jpg b/public/assets/images/about-img04.jpg
new file mode 100644
index 0000000..01ff9b7
Binary files /dev/null and b/public/assets/images/about-img04.jpg differ
diff --git a/public/assets/images/banner-01.jpg b/public/assets/images/banner-01.jpg
new file mode 100644
index 0000000..027b883
Binary files /dev/null and b/public/assets/images/banner-01.jpg differ
diff --git a/public/assets/images/banner-02.jpg b/public/assets/images/banner-02.jpg
new file mode 100644
index 0000000..fb97232
Binary files /dev/null and b/public/assets/images/banner-02.jpg differ
diff --git a/public/assets/images/banner-03.jpg b/public/assets/images/banner-03.jpg
new file mode 100644
index 0000000..fb61c71
Binary files /dev/null and b/public/assets/images/banner-03.jpg differ
diff --git a/public/assets/images/bx_loader.gif b/public/assets/images/bx_loader.gif
new file mode 100644
index 0000000..f4ff40e
Binary files /dev/null and b/public/assets/images/bx_loader.gif differ
diff --git a/public/assets/images/cate-01.png b/public/assets/images/cate-01.png
new file mode 100644
index 0000000..bb9deb6
Binary files /dev/null and b/public/assets/images/cate-01.png differ
diff --git a/public/assets/images/cate-02.png b/public/assets/images/cate-02.png
new file mode 100644
index 0000000..bd6207b
Binary files /dev/null and b/public/assets/images/cate-02.png differ
diff --git a/public/assets/images/cate-03.png b/public/assets/images/cate-03.png
new file mode 100644
index 0000000..25d178c
Binary files /dev/null and b/public/assets/images/cate-03.png differ
diff --git a/public/assets/images/controls.png b/public/assets/images/controls.png
new file mode 100644
index 0000000..28918dd
Binary files /dev/null and b/public/assets/images/controls.png differ
diff --git a/public/assets/images/down-icon.png b/public/assets/images/down-icon.png
new file mode 100644
index 0000000..9b121a8
Binary files /dev/null and b/public/assets/images/down-icon.png differ
diff --git a/public/assets/images/download-bg.jpg b/public/assets/images/download-bg.jpg
new file mode 100644
index 0000000..39da9a7
Binary files /dev/null and b/public/assets/images/download-bg.jpg differ
diff --git a/public/assets/images/download-img.jpg b/public/assets/images/download-img.jpg
new file mode 100644
index 0000000..4dcd1e4
Binary files /dev/null and b/public/assets/images/download-img.jpg differ
diff --git a/public/assets/images/facebook.png b/public/assets/images/facebook.png
new file mode 100644
index 0000000..854e1f6
Binary files /dev/null and b/public/assets/images/facebook.png differ
diff --git a/public/assets/images/greyline.png b/public/assets/images/greyline.png
new file mode 100644
index 0000000..08fd503
Binary files /dev/null and b/public/assets/images/greyline.png differ
diff --git a/public/assets/images/greyyuandian.png b/public/assets/images/greyyuandian.png
new file mode 100644
index 0000000..0300cf9
Binary files /dev/null and b/public/assets/images/greyyuandian.png differ
diff --git a/public/assets/images/gywm1.jpg b/public/assets/images/gywm1.jpg
new file mode 100644
index 0000000..34d0a91
Binary files /dev/null and b/public/assets/images/gywm1.jpg differ
diff --git a/public/assets/images/gywm2.jpg b/public/assets/images/gywm2.jpg
new file mode 100644
index 0000000..d208f5f
Binary files /dev/null and b/public/assets/images/gywm2.jpg differ
diff --git a/public/assets/images/img-01.jpg b/public/assets/images/img-01.jpg
new file mode 100644
index 0000000..af2b3e9
Binary files /dev/null and b/public/assets/images/img-01.jpg differ
diff --git a/public/assets/images/img-02.jpg b/public/assets/images/img-02.jpg
new file mode 100644
index 0000000..fcd66f1
Binary files /dev/null and b/public/assets/images/img-02.jpg differ
diff --git a/public/assets/images/img-03.jpg b/public/assets/images/img-03.jpg
new file mode 100644
index 0000000..51d5f96
Binary files /dev/null and b/public/assets/images/img-03.jpg differ
diff --git a/public/assets/images/lichengbei.png b/public/assets/images/lichengbei.png
new file mode 100644
index 0000000..4a7d8b4
Binary files /dev/null and b/public/assets/images/lichengbei.png differ
diff --git a/public/assets/images/logo.svg b/public/assets/images/logo.svg
new file mode 100644
index 0000000..fbf025b
--- /dev/null
+++ b/public/assets/images/logo.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/assets/images/logo/logo.png b/public/assets/images/logo/logo.png
new file mode 100644
index 0000000..9cdb4f9
Binary files /dev/null and b/public/assets/images/logo/logo.png differ
diff --git a/public/assets/images/mail.png b/public/assets/images/mail.png
new file mode 100644
index 0000000..6424a84
Binary files /dev/null and b/public/assets/images/mail.png differ
diff --git a/public/assets/images/product-banner.jpg b/public/assets/images/product-banner.jpg
new file mode 100644
index 0000000..f3471ce
Binary files /dev/null and b/public/assets/images/product-banner.jpg differ
diff --git a/public/assets/images/tel.png b/public/assets/images/tel.png
new file mode 100644
index 0000000..0905943
Binary files /dev/null and b/public/assets/images/tel.png differ
diff --git a/public/assets/images/weibo.png b/public/assets/images/weibo.png
new file mode 100644
index 0000000..7b6bc75
Binary files /dev/null and b/public/assets/images/weibo.png differ
diff --git a/public/assets/images/yaundian.png b/public/assets/images/yaundian.png
new file mode 100644
index 0000000..740c12c
Binary files /dev/null and b/public/assets/images/yaundian.png differ
diff --git a/public/assets/images/zhihu.png b/public/assets/images/zhihu.png
new file mode 100644
index 0000000..a59e10f
Binary files /dev/null and b/public/assets/images/zhihu.png differ
diff --git a/public/assets/js/action.js b/public/assets/js/action.js
new file mode 100644
index 0000000..8f3d1d7
--- /dev/null
+++ b/public/assets/js/action.js
@@ -0,0 +1,83 @@
+/**
+ * 获取访问者IP
+ */
+getVisitorIp = function () {
+ let ip = '127.0.0.1'
+ $.ajax({
+ type: 'get',
+ url: 'https://get.geojs.io/v1/ip.json',
+ data: {},
+ dataType: 'json',
+ async:false,
+ }).done(function (responseData) {
+ // console.log(responseData)
+ if (responseData.ip) {
+ ip = responseData.ip
+ } else {
+ ip = '127.0.0.1'
+ }
+ });
+ return ip;
+}
+
+const visitIp = getVisitorIp()
+
+/**
+ * 请求开始
+ */
+const RequestUrl = "/index/base/submitActionLog"
+
+// 图片选择器,记录图片点击的
+const imgAction = $("[log='img']");
+const aAction = $("[log='a']");
+
+imgAction.click(function ($this){
+ // console.log('click-img',$this)
+ // console.log(window.location.href)
+ const content = $this.target.outerHTML
+ // console.log(content)
+ actionSub($this,1,content,visitIp)
+});
+
+imgAction.dblclick(function ($this){
+ const content = $this.target.outerHTML
+ actionSub($this,2,content,visitIp)
+});
+// a标签行为监控
+aAction.click(function ($this){
+ const content = $this.target.parentElement.outerHTML
+ actionSub($this,1,content,visitIp)
+});
+
+// a标签行为监控
+aAction.dblclick(function ($this){
+ const content = $this.target.parentElement.outerHTML
+ actionSub($this,2,content,visitIp)
+});
+
+/**
+ * 日志请求提交
+ */
+function actionSub(obj,clickNum,content,visitIp) {
+ $.ajax({
+ type: 'POST',
+ url: RequestUrl,
+ data: {
+ 'url' : window.location.href, /*访问页*/
+ 'refer' : obj.src, /*访问来源*/
+ 'click' : clickNum, /*点击次数*/
+ 'content' : content, /*访问内容*/
+ 'ip' : visitIp, /*访客IP*/
+ 'start_time' : obj.timeStamp, /*点击时间*/
+ 'drive' : window.navigator.userAgent.toLowerCase(), /*PC OR 移动端*/
+ // 'system' : window.navigator.userAgent.toLowerCase(), /*设备系统*/
+ // 'brower' : window.navigator.userAgent.toLowerCase(), /*浏览器*/
+ // 'models' : window.navigator.userAgent.toLowerCase(), /*设备型号*/
+ 'date_time' : (new Date()).valueOf() /*生成时间*/
+ },
+ dataType: 'json',
+ // success: function (json) {
+ // console.log(json);
+ // }
+ });
+}
diff --git a/public/assets/js/current.js b/public/assets/js/current.js
new file mode 100644
index 0000000..d5f4f42
--- /dev/null
+++ b/public/assets/js/current.js
@@ -0,0 +1,73 @@
+function SelectTag(t) {
+ this.child = t.child || ".default",
+ this.over = t.over || "on",
+ this.all = t.all || ".all",
+ this.init()
+}
+$.extend(SelectTag.prototype, {
+ init: function() {
+ var t = this;
+ t._bindEvent(),
+ t._select()
+ },
+ _bindEvent: function() {
+ var t = this;
+ $(t.child).click(function(e) {
+ e.preventDefault();
+ var i = window.location.href
+ , n = $(this).attr("rel")
+ , r = $(this).attr("name");
+ $(this).hasClass(t.over) || (window.location.href = t._changeURLPar(i, r, n))
+ }),
+ $(t.all).click(function(e) {
+ e.preventDefault();
+ var i = window.location.href
+ , n = $(this).attr("name");
+ $("[name=" + n + "]").removeClass(t.over),
+ $(this).addClass(t.over),
+ window.location.href = t._delUrlPar(i, n)
+ })
+ },
+ _delUrlPar: function(t, e) {
+ var n = "";
+ if (t.indexOf("?") == -1)
+ return t;
+ n = t.substr(t.indexOf("?") + 1);
+ var r = ""
+ , a = "";
+ if (n.indexOf("&") != -1) {
+ r = n.split("&");
+ for (i in r)
+ r[i].split("=")[0] != e && (a = a + r[i].split("=")[0] + "=" + r[i].split("=")[1] + "&");
+ return t.substr(0, t.indexOf("?")) + "?" + a.substr(0, a.length - 1)
+ }
+ return r = n.split("="),
+ r[0] == e ? t.substr(0, t.indexOf("?")) : t
+ },
+ _changeURLPar: function(t, e, i) {
+ var n = this
+ , r = e + "=([^&]*)"
+ , a = e + "=" + i
+ , s = encodeURI(n._getQueryString(e));
+ return t.match(r) ? t = t.replace(s, i) : t.match("[?]") ? t + "&" + a : t + "?" + a
+ },
+ _getQueryString: function(t) {
+ var e = new RegExp("(^|&)" + t + "=([^&]*)(&|$)","i")
+ , i = window.location.search.substr(1).match(e);
+ return null != i ? decodeURI(i[2]) : null
+ },
+ _select: function() {
+ var t = this
+ , e = window.location.href;
+ $(t.child).each(function() {
+ var i = $(this).attr("name") + "=" + $(this).attr("rel")
+ , n = new RegExp(encodeURI(i),"g");
+ if (n.test(e)) {
+ $(this).addClass(t.over);
+ var r = $(this).attr("name");
+ $("[name=" + r + "]").eq(0).removeClass(t.over)
+ } else
+ $(this).removeClass(t.over)
+ })
+ }
+});
diff --git a/public/assets/js/jquery.bxslider.js b/public/assets/js/jquery.bxslider.js
new file mode 100644
index 0000000..c8243e6
--- /dev/null
+++ b/public/assets/js/jquery.bxslider.js
@@ -0,0 +1,1343 @@
+/**
+ * BxSlider v4.1.2 - Fully loaded, responsive content slider
+ * http://bxslider.com
+ *
+ * Copyright 2014, Steven Wanderski - http://stevenwanderski.com - http://bxcreative.com
+ * Written while drinking Belgian ales and listening to jazz
+ *
+ * Released under the MIT license - http://opensource.org/licenses/MIT
+ */
+
+;(function($){
+
+ var plugin = {};
+
+ var defaults = {
+
+ // GENERAL
+ mode: 'horizontal',
+ slideSelector: '',
+ infiniteLoop: true,
+ hideControlOnEnd: false,
+ speed: 500,
+ easing: null,
+ slideMargin: 0,
+ startSlide: 0,
+ randomStart: false,
+ captions: false,
+ ticker: false,
+ tickerHover: false,
+ adaptiveHeight: false,
+ adaptiveHeightSpeed: 500,
+ video: false,
+ useCSS: true,
+ preloadImages: 'visible',
+ responsive: true,
+ slideZIndex: 50,
+ wrapperClass: 'bx-wrapper',
+
+ // TOUCH
+ touchEnabled: true,
+ swipeThreshold: 50,
+ oneToOneTouch: true,
+ preventDefaultSwipeX: true,
+ preventDefaultSwipeY: false,
+
+ // PAGER
+ pager: true,
+ pagerType: 'full',
+ pagerShortSeparator: ' / ',
+ pagerSelector: null,
+ buildPager: null,
+ pagerCustom: null,
+
+ // CONTROLS
+ controls: true,
+ nextText: 'Next',
+ prevText: 'Prev',
+ nextSelector: null,
+ prevSelector: null,
+ autoControls: false,
+ startText: 'Start',
+ stopText: 'Stop',
+ autoControlsCombine: false,
+ autoControlsSelector: null,
+
+ // AUTO
+ auto: false,
+ pause: 4000,
+ autoStart: true,
+ autoDirection: 'next',
+ autoHover: false,
+ autoDelay: 0,
+ autoSlideForOnePage: false,
+
+ // CAROUSEL
+ minSlides: 1,
+ maxSlides: 1,
+ moveSlides: 0,
+ slideWidth: 0,
+
+ // CALLBACKS
+ onSliderLoad: function() {},
+ onSlideBefore: function() {},
+ onSlideAfter: function() {},
+ onSlideNext: function() {},
+ onSlidePrev: function() {},
+ onSliderResize: function() {}
+ }
+
+ $.fn.bxSlider = function(options){
+
+ if(this.length == 0) return this;
+
+ // support mutltiple elements
+ if(this.length > 1){
+ this.each(function(){$(this).bxSlider(options)});
+ return this;
+ }
+
+ // create a namespace to be used throughout the plugin
+ var slider = {};
+ // set a reference to our slider element
+ var el = this;
+ plugin.el = this;
+
+ /**
+ * Makes slideshow responsive
+ */
+ // first get the original window dimens (thanks alot IE)
+ var windowWidth = $(window).width();
+ var windowHeight = $(window).height();
+
+
+
+ /**
+ * ===================================================================================
+ * = PRIVATE FUNCTIONS
+ * ===================================================================================
+ */
+
+ /**
+ * Initializes namespace settings to be used throughout plugin
+ */
+ var init = function(){
+ // merge user-supplied options with the defaults
+ slider.settings = $.extend({}, defaults, options);
+ // parse slideWidth setting
+ slider.settings.slideWidth = parseInt(slider.settings.slideWidth);
+ // store the original children
+ slider.children = el.children(slider.settings.slideSelector);
+ // check if actual number of slides is less than minSlides / maxSlides
+ if(slider.children.length < slider.settings.minSlides) slider.settings.minSlides = slider.children.length;
+ if(slider.children.length < slider.settings.maxSlides) slider.settings.maxSlides = slider.children.length;
+ // if random start, set the startSlide setting to random number
+ if(slider.settings.randomStart) slider.settings.startSlide = Math.floor(Math.random() * slider.children.length);
+ // store active slide information
+ slider.active = { index: slider.settings.startSlide }
+ // store if the slider is in carousel mode (displaying / moving multiple slides)
+ slider.carousel = slider.settings.minSlides > 1 || slider.settings.maxSlides > 1;
+ // if carousel, force preloadImages = 'all'
+ if(slider.carousel) slider.settings.preloadImages = 'all';
+ // calculate the min / max width thresholds based on min / max number of slides
+ // used to setup and update carousel slides dimensions
+ slider.minThreshold = (slider.settings.minSlides * slider.settings.slideWidth) + ((slider.settings.minSlides - 1) * slider.settings.slideMargin);
+ slider.maxThreshold = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
+ // store the current state of the slider (if currently animating, working is true)
+ slider.working = false;
+ // initialize the controls object
+ slider.controls = {};
+ // initialize an auto interval
+ slider.interval = null;
+ // determine which property to use for transitions
+ slider.animProp = slider.settings.mode == 'vertical' ? 'top' : 'left';
+ // determine if hardware acceleration can be used
+ slider.usingCSS = slider.settings.useCSS && slider.settings.mode != 'fade' && (function(){
+ // create our test div element
+ var div = document.createElement('div');
+ // css transition properties
+ var props = ['WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
+ // test for each property
+ for(var i in props){
+ if(div.style[props[i]] !== undefined){
+ slider.cssPrefix = props[i].replace('Perspective', '').toLowerCase();
+ slider.animProp = '-' + slider.cssPrefix + '-transform';
+ return true;
+ }
+ }
+ return false;
+ }());
+ // if vertical mode always make maxSlides and minSlides equal
+ if(slider.settings.mode == 'vertical') slider.settings.maxSlides = slider.settings.minSlides;
+ // save original style data
+ el.data("origStyle", el.attr("style"));
+ el.children(slider.settings.slideSelector).each(function() {
+ $(this).data("origStyle", $(this).attr("style"));
+ });
+ // perform all DOM / CSS modifications
+ setup();
+ }
+
+ /**
+ * Performs all DOM and CSS modifications
+ */
+ var setup = function(){
+ // wrap el in a wrapper
+ el.wrap('');
+ // store a namspace reference to .bx-viewport
+ slider.viewport = el.parent();
+ // add a loading div to display while images are loading
+ slider.loader = $('');
+ slider.viewport.prepend(slider.loader);
+ // set el to a massive width, to hold any needed slides
+ // also strip any margin and padding from el
+ el.css({
+ width: slider.settings.mode == 'horizontal' ? (slider.children.length * 100 + 215) + '%' : 'auto',
+ position: 'relative'
+ });
+ // if using CSS, add the easing property
+ if(slider.usingCSS && slider.settings.easing){
+ el.css('-' + slider.cssPrefix + '-transition-timing-function', slider.settings.easing);
+ // if not using CSS and no easing value was supplied, use the default JS animation easing (swing)
+ }else if(!slider.settings.easing){
+ slider.settings.easing = 'swing';
+ }
+ var slidesShowing = getNumberSlidesShowing();
+ // make modifications to the viewport (.bx-viewport)
+ slider.viewport.css({
+ width: '100%',
+ overflow: 'hidden',
+ position: 'relative'
+ });
+ slider.viewport.parent().css({
+ maxWidth: getViewportMaxWidth()
+ });
+ // make modification to the wrapper (.bx-wrapper)
+ if(!slider.settings.pager) {
+ slider.viewport.parent().css({
+ margin: '0 auto 0px'
+ });
+ }
+ // apply css to all slider children
+ slider.children.css({
+ 'float': slider.settings.mode == 'horizontal' ? 'left' : 'none',
+ listStyle: 'none',
+ position: 'relative'
+ });
+ // apply the calculated width after the float is applied to prevent scrollbar interference
+ slider.children.css('width', getSlideWidth());
+ // if slideMargin is supplied, add the css
+ if(slider.settings.mode == 'horizontal' && slider.settings.slideMargin > 0) slider.children.css('marginRight', slider.settings.slideMargin);
+ if(slider.settings.mode == 'vertical' && slider.settings.slideMargin > 0) slider.children.css('marginBottom', slider.settings.slideMargin);
+ // if "fade" mode, add positioning and z-index CSS
+ if(slider.settings.mode == 'fade'){
+ slider.children.css({
+ position: 'absolute',
+ zIndex: 0,
+ display: 'none'
+ });
+ // prepare the z-index on the showing element
+ slider.children.eq(slider.settings.startSlide).css({zIndex: slider.settings.slideZIndex, display: 'block'});
+ }
+ // create an element to contain all slider controls (pager, start / stop, etc)
+ slider.controls.el = $('');
+ // if captions are requested, add them
+ if(slider.settings.captions) appendCaptions();
+ // check if startSlide is last slide
+ slider.active.last = slider.settings.startSlide == getPagerQty() - 1;
+ // if video is true, set up the fitVids plugin
+ if(slider.settings.video) el.fitVids();
+ // set the default preload selector (visible)
+ var preloadSelector = slider.children.eq(slider.settings.startSlide);
+ if (slider.settings.preloadImages == "all") preloadSelector = slider.children;
+ // only check for control addition if not in "ticker" mode
+ if(!slider.settings.ticker){
+ // if pager is requested, add it
+ if(slider.settings.pager) appendPager();
+ // if controls are requested, add them
+ if(slider.settings.controls) appendControls();
+ // if auto is true, and auto controls are requested, add them
+ if(slider.settings.auto && slider.settings.autoControls) appendControlsAuto();
+ // if any control option is requested, add the controls wrapper
+ if(slider.settings.controls || slider.settings.autoControls || slider.settings.pager) slider.viewport.after(slider.controls.el);
+ // if ticker mode, do not allow a pager
+ }else{
+ slider.settings.pager = false;
+ }
+ // preload all images, then perform final DOM / CSS modifications that depend on images being loaded
+ loadElements(preloadSelector, start);
+ }
+
+ var loadElements = function(selector, callback){
+ var total = selector.find('img, iframe').length;
+ if (total == 0){
+ callback();
+ return;
+ }
+ var count = 0;
+ selector.find('img, iframe').each(function(){
+ $(this).one('load', function() {
+ if(++count == total) callback();
+ }).each(function() {
+ if(this.complete) $(this).load();
+ });
+ });
+ }
+
+ /**
+ * Start the slider
+ */
+ var start = function(){
+ // if infinite loop, prepare additional slides
+ if(slider.settings.infiniteLoop && slider.settings.mode != 'fade' && !slider.settings.ticker){
+ var slice = slider.settings.mode == 'vertical' ? slider.settings.minSlides : slider.settings.maxSlides;
+ var sliceAppend = slider.children.slice(0, slice).clone().addClass('bx-clone');
+ var slicePrepend = slider.children.slice(-slice).clone().addClass('bx-clone');
+ el.append(sliceAppend).prepend(slicePrepend);
+ }
+ // remove the loading DOM element
+ slider.loader.remove();
+ // set the left / top position of "el"
+ setSlidePosition();
+ // if "vertical" mode, always use adaptiveHeight to prevent odd behavior
+ if (slider.settings.mode == 'vertical') slider.settings.adaptiveHeight = true;
+ // set the viewport height
+ slider.viewport.height(getViewportHeight());
+ // make sure everything is positioned just right (same as a window resize)
+ el.redrawSlider();
+ // onSliderLoad callback
+ slider.settings.onSliderLoad(slider.active.index);
+ // slider has been fully initialized
+ slider.initialized = true;
+ // bind the resize call to the window
+ if (slider.settings.responsive) $(window).bind('resize', resizeWindow);
+ // if auto is true and has more than 1 page, start the show
+ if (slider.settings.auto && slider.settings.autoStart && (getPagerQty() > 1 || slider.settings.autoSlideForOnePage)) initAuto();
+ // if ticker is true, start the ticker
+ if (slider.settings.ticker) initTicker();
+ // if pager is requested, make the appropriate pager link active
+ if (slider.settings.pager) updatePagerActive(slider.settings.startSlide);
+ // check for any updates to the controls (like hideControlOnEnd updates)
+ if (slider.settings.controls) updateDirectionControls();
+ // if touchEnabled is true, setup the touch events
+ if (slider.settings.touchEnabled && !slider.settings.ticker) initTouch();
+ }
+
+ /**
+ * Returns the calculated height of the viewport, used to determine either adaptiveHeight or the maxHeight value
+ */
+ var getViewportHeight = function(){
+ var height = 0;
+ // first determine which children (slides) should be used in our height calculation
+ var children = $();
+ // if mode is not "vertical" and adaptiveHeight is false, include all children
+ if(slider.settings.mode != 'vertical' && !slider.settings.adaptiveHeight){
+ children = slider.children;
+ }else{
+ // if not carousel, return the single active child
+ if(!slider.carousel){
+ children = slider.children.eq(slider.active.index);
+ // if carousel, return a slice of children
+ }else{
+ // get the individual slide index
+ var currentIndex = slider.settings.moveSlides == 1 ? slider.active.index : slider.active.index * getMoveBy();
+ // add the current slide to the children
+ children = slider.children.eq(currentIndex);
+ // cycle through the remaining "showing" slides
+ for (i = 1; i <= slider.settings.maxSlides - 1; i++){
+ // if looped back to the start
+ if(currentIndex + i >= slider.children.length){
+ children = children.add(slider.children.eq(i - 1));
+ }else{
+ children = children.add(slider.children.eq(currentIndex + i));
+ }
+ }
+ }
+ }
+ // if "vertical" mode, calculate the sum of the heights of the children
+ if(slider.settings.mode == 'vertical'){
+ children.each(function(index) {
+ height += $(this).outerHeight();
+ });
+ // add user-supplied margins
+ if(slider.settings.slideMargin > 0){
+ height += slider.settings.slideMargin * (slider.settings.minSlides - 1);
+ }
+ // if not "vertical" mode, calculate the max height of the children
+ }else{
+ height = Math.max.apply(Math, children.map(function(){
+ return $(this).outerHeight(false);
+ }).get());
+ }
+
+ if(slider.viewport.css('box-sizing') == 'border-box'){
+ height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom')) +
+ parseFloat(slider.viewport.css('border-top-width')) + parseFloat(slider.viewport.css('border-bottom-width'));
+ }else if(slider.viewport.css('box-sizing') == 'padding-box'){
+ height += parseFloat(slider.viewport.css('padding-top')) + parseFloat(slider.viewport.css('padding-bottom'));
+ }
+
+ return height;
+ }
+
+ /**
+ * Returns the calculated width to be used for the outer wrapper / viewport
+ */
+ var getViewportMaxWidth = function(){
+ var width = '100%';
+ if(slider.settings.slideWidth > 0){
+ if(slider.settings.mode == 'horizontal'){
+ width = (slider.settings.maxSlides * slider.settings.slideWidth) + ((slider.settings.maxSlides - 1) * slider.settings.slideMargin);
+ }else{
+ width = slider.settings.slideWidth;
+ }
+ }
+ return width;
+ }
+
+ /**
+ * Returns the calculated width to be applied to each slide
+ */
+ var getSlideWidth = function(){
+ // start with any user-supplied slide width
+ var newElWidth = slider.settings.slideWidth;
+ // get the current viewport width
+ var wrapWidth = slider.viewport.width();
+ // if slide width was not supplied, or is larger than the viewport use the viewport width
+ if(slider.settings.slideWidth == 0 ||
+ (slider.settings.slideWidth > wrapWidth && !slider.carousel) ||
+ slider.settings.mode == 'vertical'){
+ newElWidth = wrapWidth;
+ // if carousel, use the thresholds to determine the width
+ }else if(slider.settings.maxSlides > 1 && slider.settings.mode == 'horizontal'){
+ if(wrapWidth > slider.maxThreshold){
+ // newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.maxSlides - 1))) / slider.settings.maxSlides;
+ }else if(wrapWidth < slider.minThreshold){
+ newElWidth = (wrapWidth - (slider.settings.slideMargin * (slider.settings.minSlides - 1))) / slider.settings.minSlides;
+ }
+ }
+ return newElWidth;
+ }
+
+ /**
+ * Returns the number of slides currently visible in the viewport (includes partially visible slides)
+ */
+ var getNumberSlidesShowing = function(){
+ var slidesShowing = 1;
+ if(slider.settings.mode == 'horizontal' && slider.settings.slideWidth > 0){
+ // if viewport is smaller than minThreshold, return minSlides
+ if(slider.viewport.width() < slider.minThreshold){
+ slidesShowing = slider.settings.minSlides;
+ // if viewport is larger than minThreshold, return maxSlides
+ }else if(slider.viewport.width() > slider.maxThreshold){
+ slidesShowing = slider.settings.maxSlides;
+ // if viewport is between min / max thresholds, divide viewport width by first child width
+ }else{
+ var childWidth = slider.children.first().width() + slider.settings.slideMargin;
+ slidesShowing = Math.floor((slider.viewport.width() +
+ slider.settings.slideMargin) / childWidth);
+ }
+ // if "vertical" mode, slides showing will always be minSlides
+ }else if(slider.settings.mode == 'vertical'){
+ slidesShowing = slider.settings.minSlides;
+ }
+ return slidesShowing;
+ }
+
+ /**
+ * Returns the number of pages (one full viewport of slides is one "page")
+ */
+ var getPagerQty = function(){
+ var pagerQty = 0;
+ // if moveSlides is specified by the user
+ if(slider.settings.moveSlides > 0){
+ if(slider.settings.infiniteLoop){
+ pagerQty = Math.ceil(slider.children.length / getMoveBy());
+ }else{
+ // use a while loop to determine pages
+ var breakPoint = 0;
+ var counter = 0
+ // when breakpoint goes above children length, counter is the number of pages
+ while (breakPoint < slider.children.length){
+ ++pagerQty;
+ breakPoint = counter + getNumberSlidesShowing();
+ counter += slider.settings.moveSlides <= getNumberSlidesShowing() ? slider.settings.moveSlides : getNumberSlidesShowing();
+ }
+ }
+ // if moveSlides is 0 (auto) divide children length by sides showing, then round up
+ }else{
+ pagerQty = Math.ceil(slider.children.length / getNumberSlidesShowing());
+ }
+ return pagerQty;
+ }
+
+ /**
+ * Returns the number of indivual slides by which to shift the slider
+ */
+ var getMoveBy = function(){
+ // if moveSlides was set by the user and moveSlides is less than number of slides showing
+ if(slider.settings.moveSlides > 0 && slider.settings.moveSlides <= getNumberSlidesShowing()){
+ return slider.settings.moveSlides;
+ }
+ // if moveSlides is 0 (auto)
+ return getNumberSlidesShowing();
+ }
+
+ /**
+ * Sets the slider's (el) left or top position
+ */
+ var setSlidePosition = function(){
+ // if last slide, not infinite loop, and number of children is larger than specified maxSlides
+ if(slider.children.length > slider.settings.maxSlides && slider.active.last && !slider.settings.infiniteLoop){
+ if (slider.settings.mode == 'horizontal'){
+ // get the last child's position
+ var lastChild = slider.children.last();
+ var position = lastChild.position();
+ // set the left position
+ setPositionProperty(-(position.left - (slider.viewport.width() - lastChild.outerWidth())), 'reset', 0);
+ }else if(slider.settings.mode == 'vertical'){
+ // get the last showing index's position
+ var lastShowingIndex = slider.children.length - slider.settings.minSlides;
+ var position = slider.children.eq(lastShowingIndex).position();
+ // set the top position
+ setPositionProperty(-position.top, 'reset', 0);
+ }
+ // if not last slide
+ }else{
+ // get the position of the first showing slide
+ var position = slider.children.eq(slider.active.index * getMoveBy()).position();
+ // check for last slide
+ if (slider.active.index == getPagerQty() - 1) slider.active.last = true;
+ // set the repective position
+ if (position != undefined){
+ if (slider.settings.mode == 'horizontal') setPositionProperty(-position.left, 'reset', 0);
+ else if (slider.settings.mode == 'vertical') setPositionProperty(-position.top, 'reset', 0);
+ }
+ }
+ }
+
+ /**
+ * Sets the el's animating property position (which in turn will sometimes animate el).
+ * If using CSS, sets the transform property. If not using CSS, sets the top / left property.
+ *
+ * @param value (int)
+ * - the animating property's value
+ *
+ * @param type (string) 'slider', 'reset', 'ticker'
+ * - the type of instance for which the function is being
+ *
+ * @param duration (int)
+ * - the amount of time (in ms) the transition should occupy
+ *
+ * @param params (array) optional
+ * - an optional parameter containing any variables that need to be passed in
+ */
+ var setPositionProperty = function(value, type, duration, params){
+ // use CSS transform
+ if(slider.usingCSS){
+ // determine the translate3d value
+ var propValue = slider.settings.mode == 'vertical' ? 'translate3d(0, ' + value + 'px, 0)' : 'translate3d(' + value + 'px, 0, 0)';
+ // add the CSS transition-duration
+ el.css('-' + slider.cssPrefix + '-transition-duration', duration / 1000 + 's');
+ if(type == 'slide'){
+ // set the property value
+ el.css(slider.animProp, propValue);
+ // bind a callback method - executes when CSS transition completes
+ el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
+ // unbind the callback
+ el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
+ updateAfterSlideTransition();
+ });
+ }else if(type == 'reset'){
+ el.css(slider.animProp, propValue);
+ }else if(type == 'ticker'){
+ // make the transition use 'linear'
+ el.css('-' + slider.cssPrefix + '-transition-timing-function', 'linear');
+ el.css(slider.animProp, propValue);
+ // bind a callback method - executes when CSS transition completes
+ el.bind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', function(){
+ // unbind the callback
+ el.unbind('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd');
+ // reset the position
+ setPositionProperty(params['resetValue'], 'reset', 0);
+ // start the loop again
+ tickerLoop();
+ });
+ }
+ // use JS animate
+ }else{
+ var animateObj = {};
+ animateObj[slider.animProp] = value;
+ if(type == 'slide'){
+ el.animate(animateObj, duration, slider.settings.easing, function(){
+ updateAfterSlideTransition();
+ });
+ }else if(type == 'reset'){
+ el.css(slider.animProp, value)
+ }else if(type == 'ticker'){
+ el.animate(animateObj, speed, 'linear', function(){
+ setPositionProperty(params['resetValue'], 'reset', 0);
+ // run the recursive loop after animation
+ tickerLoop();
+ });
+ }
+ }
+ }
+
+ /**
+ * Populates the pager with proper amount of pages
+ */
+ var populatePager = function(){
+ var pagerHtml = '';
+ var pagerQty = getPagerQty();
+ // loop through each pager item
+ for(var i=0; i < pagerQty; i++){
+ var linkContent = '';
+ // if a buildPager function is supplied, use it to get pager link value, else use index + 1
+ if(slider.settings.buildPager && $.isFunction(slider.settings.buildPager)){
+ linkContent = slider.settings.buildPager(i);
+ slider.pagerEl.addClass('bx-custom-pager');
+ }else{
+ linkContent = i + 1;
+ slider.pagerEl.addClass('bx-default-pager');
+ }
+ // var linkContent = slider.settings.buildPager && $.isFunction(slider.settings.buildPager) ? slider.settings.buildPager(i) : i + 1;
+ // add the markup to the string
+ pagerHtml += '';
+ };
+ // populate the pager element with pager links
+ slider.pagerEl.html(pagerHtml);
+ }
+
+ /**
+ * Appends the pager to the controls element
+ */
+ var appendPager = function(){
+ if(!slider.settings.pagerCustom){
+ // create the pager DOM element
+ slider.pagerEl = $('');
+ // if a pager selector was supplied, populate it with the pager
+ if(slider.settings.pagerSelector){
+ $(slider.settings.pagerSelector).html(slider.pagerEl);
+ // if no pager selector was supplied, add it after the wrapper
+ }else{
+ slider.controls.el.addClass('bx-has-pager').append(slider.pagerEl);
+ }
+ // populate the pager
+ populatePager();
+ }else{
+ slider.pagerEl = $(slider.settings.pagerCustom);
+ }
+ // assign the pager click binding
+ slider.pagerEl.on('click', 'a', clickPagerBind);
+ }
+
+ /**
+ * Appends prev / next controls to the controls element
+ */
+ var appendControls = function(){
+ slider.controls.next = $('' + slider.settings.nextText + '');
+ slider.controls.prev = $('' + slider.settings.prevText + '');
+ // bind click actions to the controls
+ slider.controls.next.bind('click', clickNextBind);
+ slider.controls.prev.bind('click', clickPrevBind);
+ // if nextSlector was supplied, populate it
+ if(slider.settings.nextSelector){
+ $(slider.settings.nextSelector).append(slider.controls.next);
+ }
+ // if prevSlector was supplied, populate it
+ if(slider.settings.prevSelector){
+ $(slider.settings.prevSelector).append(slider.controls.prev);
+ }
+ // if no custom selectors were supplied
+ if(!slider.settings.nextSelector && !slider.settings.prevSelector){
+ // add the controls to the DOM
+ slider.controls.directionEl = $('');
+ // add the control elements to the directionEl
+ slider.controls.directionEl.append(slider.controls.prev).append(slider.controls.next);
+ // slider.viewport.append(slider.controls.directionEl);
+ slider.controls.el.addClass('bx-has-controls-direction').append(slider.controls.directionEl);
+ }
+ }
+
+ /**
+ * Appends start / stop auto controls to the controls element
+ */
+ var appendControlsAuto = function(){
+ slider.controls.start = $('');
+ slider.controls.stop = $('');
+ // add the controls to the DOM
+ slider.controls.autoEl = $('');
+ // bind click actions to the controls
+ slider.controls.autoEl.on('click', '.bx-start', clickStartBind);
+ slider.controls.autoEl.on('click', '.bx-stop', clickStopBind);
+ // if autoControlsCombine, insert only the "start" control
+ if(slider.settings.autoControlsCombine){
+ slider.controls.autoEl.append(slider.controls.start);
+ // if autoControlsCombine is false, insert both controls
+ }else{
+ slider.controls.autoEl.append(slider.controls.start).append(slider.controls.stop);
+ }
+ // if auto controls selector was supplied, populate it with the controls
+ if(slider.settings.autoControlsSelector){
+ $(slider.settings.autoControlsSelector).html(slider.controls.autoEl);
+ // if auto controls selector was not supplied, add it after the wrapper
+ }else{
+ slider.controls.el.addClass('bx-has-controls-auto').append(slider.controls.autoEl);
+ }
+ // update the auto controls
+ updateAutoControls(slider.settings.autoStart ? 'stop' : 'start');
+ }
+
+ /**
+ * Appends image captions to the DOM
+ */
+ var appendCaptions = function(){
+ // cycle through each child
+ slider.children.each(function(index){
+ // get the image title attribute
+ var title = $(this).find('img:first').attr('title');
+ // append the caption
+ if (title != undefined && ('' + title).length) {
+ $(this).append('' + title + '');
+ }
+ });
+ }
+
+ /**
+ * Click next binding
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var clickNextBind = function(e){
+ // if auto show is running, stop it
+ if (slider.settings.auto) el.stopAuto();
+ el.goToNextSlide();
+ e.preventDefault();
+ }
+
+ /**
+ * Click prev binding
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var clickPrevBind = function(e){
+ // if auto show is running, stop it
+ if (slider.settings.auto) el.stopAuto();
+ el.goToPrevSlide();
+ e.preventDefault();
+ }
+
+ /**
+ * Click start binding
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var clickStartBind = function(e){
+ el.startAuto();
+ e.preventDefault();
+ }
+
+ /**
+ * Click stop binding
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var clickStopBind = function(e){
+ el.stopAuto();
+ e.preventDefault();
+ }
+
+ /**
+ * Click pager binding
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var clickPagerBind = function(e){
+ // if auto show is running, stop it
+ if (slider.settings.auto) el.stopAuto();
+ var pagerLink = $(e.currentTarget);
+ if(pagerLink.attr('data-slide-index') !== undefined){
+ var pagerIndex = parseInt(pagerLink.attr('data-slide-index'));
+ // if clicked pager link is not active, continue with the goToSlide call
+ if(pagerIndex != slider.active.index) el.goToSlide(pagerIndex);
+ e.preventDefault();
+ }
+ }
+
+ /**
+ * Updates the pager links with an active class
+ *
+ * @param slideIndex (int)
+ * - index of slide to make active
+ */
+ var updatePagerActive = function(slideIndex){
+ // if "short" pager type
+ var len = slider.children.length; // nb of children
+ if(slider.settings.pagerType == 'short'){
+ if(slider.settings.maxSlides > 1) {
+ len = Math.ceil(slider.children.length/slider.settings.maxSlides);
+ }
+ slider.pagerEl.html( (slideIndex + 1) + slider.settings.pagerShortSeparator + len);
+ return;
+ }
+ // remove all pager active classes
+ slider.pagerEl.find('a').removeClass('active');
+ // apply the active class for all pagers
+ slider.pagerEl.each(function(i, el) { $(el).find('a').eq(slideIndex).addClass('active'); });
+ }
+
+ /**
+ * Performs needed actions after a slide transition
+ */
+ var updateAfterSlideTransition = function(){
+ // if infinte loop is true
+ if(slider.settings.infiniteLoop){
+ var position = '';
+ // first slide
+ if(slider.active.index == 0){
+ // set the new position
+ position = slider.children.eq(0).position();
+ // carousel, last slide
+ }else if(slider.active.index == getPagerQty() - 1 && slider.carousel){
+ position = slider.children.eq((getPagerQty() - 1) * getMoveBy()).position();
+ // last slide
+ }else if(slider.active.index == slider.children.length - 1){
+ position = slider.children.eq(slider.children.length - 1).position();
+ }
+ if(position){
+ if (slider.settings.mode == 'horizontal') { setPositionProperty(-position.left, 'reset', 0); }
+ else if (slider.settings.mode == 'vertical') { setPositionProperty(-position.top, 'reset', 0); }
+ }
+ }
+ // declare that the transition is complete
+ slider.working = false;
+ // onSlideAfter callback
+ slider.settings.onSlideAfter(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
+ }
+
+ /**
+ * Updates the auto controls state (either active, or combined switch)
+ *
+ * @param state (string) "start", "stop"
+ * - the new state of the auto show
+ */
+ var updateAutoControls = function(state){
+ // if autoControlsCombine is true, replace the current control with the new state
+ if(slider.settings.autoControlsCombine){
+ slider.controls.autoEl.html(slider.controls[state]);
+ // if autoControlsCombine is false, apply the "active" class to the appropriate control
+ }else{
+ slider.controls.autoEl.find('a').removeClass('active');
+ slider.controls.autoEl.find('a:not(.bx-' + state + ')').addClass('active');
+ }
+ }
+
+ /**
+ * Updates the direction controls (checks if either should be hidden)
+ */
+ var updateDirectionControls = function(){
+ if(getPagerQty() == 1){
+ slider.controls.prev.addClass('disabled');
+ slider.controls.next.addClass('disabled');
+ }else if(!slider.settings.infiniteLoop && slider.settings.hideControlOnEnd){
+ // if first slide
+ if (slider.active.index == 0){
+ slider.controls.prev.addClass('disabled');
+ slider.controls.next.removeClass('disabled');
+ // if last slide
+ }else if(slider.active.index == getPagerQty() - 1){
+ slider.controls.next.addClass('disabled');
+ slider.controls.prev.removeClass('disabled');
+ // if any slide in the middle
+ }else{
+ slider.controls.prev.removeClass('disabled');
+ slider.controls.next.removeClass('disabled');
+ }
+ }
+ }
+
+ /**
+ * Initialzes the auto process
+ */
+ var initAuto = function(){
+ // if autoDelay was supplied, launch the auto show using a setTimeout() call
+ if(slider.settings.autoDelay > 0){
+ var timeout = setTimeout(el.startAuto, slider.settings.autoDelay);
+ // if autoDelay was not supplied, start the auto show normally
+ }else{
+ el.startAuto();
+ }
+ // if autoHover is requested
+ if(slider.settings.autoHover){
+ // on el hover
+ el.hover(function(){
+ // if the auto show is currently playing (has an active interval)
+ if(slider.interval){
+ // stop the auto show and pass true agument which will prevent control update
+ el.stopAuto(true);
+ // create a new autoPaused value which will be used by the relative "mouseout" event
+ slider.autoPaused = true;
+ }
+ }, function(){
+ // if the autoPaused value was created be the prior "mouseover" event
+ if(slider.autoPaused){
+ // start the auto show and pass true agument which will prevent control update
+ el.startAuto(true);
+ // reset the autoPaused value
+ slider.autoPaused = null;
+ }
+ });
+ }
+ }
+
+ /**
+ * Initialzes the ticker process
+ */
+ var initTicker = function(){
+ var startPosition = 0;
+ // if autoDirection is "next", append a clone of the entire slider
+ if(slider.settings.autoDirection == 'next'){
+ el.append(slider.children.clone().addClass('bx-clone'));
+ // if autoDirection is "prev", prepend a clone of the entire slider, and set the left position
+ }else{
+ el.prepend(slider.children.clone().addClass('bx-clone'));
+ var position = slider.children.first().position();
+ startPosition = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
+ }
+ setPositionProperty(startPosition, 'reset', 0);
+ // do not allow controls in ticker mode
+ slider.settings.pager = false;
+ slider.settings.controls = false;
+ slider.settings.autoControls = false;
+ // if autoHover is requested
+ if(slider.settings.tickerHover && !slider.usingCSS){
+ // on el hover
+ slider.viewport.hover(function(){
+ el.stop();
+ }, function(){
+ // calculate the total width of children (used to calculate the speed ratio)
+ var totalDimens = 0;
+ slider.children.each(function(index){
+ totalDimens += slider.settings.mode == 'horizontal' ? $(this).outerWidth(true) : $(this).outerHeight(true);
+ });
+ // calculate the speed ratio (used to determine the new speed to finish the paused animation)
+ var ratio = slider.settings.speed / totalDimens;
+ // determine which property to use
+ var property = slider.settings.mode == 'horizontal' ? 'left' : 'top';
+ // calculate the new speed
+ var newSpeed = ratio * (totalDimens - (Math.abs(parseInt(el.css(property)))));
+ tickerLoop(newSpeed);
+ });
+ }
+ // start the ticker loop
+ tickerLoop();
+ }
+
+ /**
+ * Runs a continuous loop, news ticker-style
+ */
+ var tickerLoop = function(resumeSpeed){
+ speed = resumeSpeed ? resumeSpeed : slider.settings.speed;
+ var position = {left: 0, top: 0};
+ var reset = {left: 0, top: 0};
+ // if "next" animate left position to last child, then reset left to 0
+ if(slider.settings.autoDirection == 'next'){
+ position = el.find('.bx-clone').first().position();
+ // if "prev" animate left position to 0, then reset left to first non-clone child
+ }else{
+ reset = slider.children.first().position();
+ }
+ var animateProperty = slider.settings.mode == 'horizontal' ? -position.left : -position.top;
+ var resetValue = slider.settings.mode == 'horizontal' ? -reset.left : -reset.top;
+ var params = {resetValue: resetValue};
+ setPositionProperty(animateProperty, 'ticker', speed, params);
+ }
+
+ /**
+ * Initializes touch events
+ */
+ var initTouch = function(){
+ // initialize object to contain all touch values
+ slider.touch = {
+ start: {x: 0, y: 0},
+ end: {x: 0, y: 0}
+ }
+ slider.viewport.bind('touchstart', onTouchStart);
+ }
+
+ /**
+ * Event handler for "touchstart"
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var onTouchStart = function(e){
+ if(slider.working){
+ e.preventDefault();
+ }else{
+ // record the original position when touch starts
+ slider.touch.originalPos = el.position();
+ var orig = e.originalEvent;
+ // record the starting touch x, y coordinates
+ slider.touch.start.x = orig.changedTouches[0].pageX;
+ slider.touch.start.y = orig.changedTouches[0].pageY;
+ // bind a "touchmove" event to the viewport
+ slider.viewport.bind('touchmove', onTouchMove);
+ // bind a "touchend" event to the viewport
+ slider.viewport.bind('touchend', onTouchEnd);
+ }
+ }
+
+ /**
+ * Event handler for "touchmove"
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var onTouchMove = function(e){
+ var orig = e.originalEvent;
+ // if scrolling on y axis, do not prevent default
+ var xMovement = Math.abs(orig.changedTouches[0].pageX - slider.touch.start.x);
+ var yMovement = Math.abs(orig.changedTouches[0].pageY - slider.touch.start.y);
+ // x axis swipe
+ if((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX){
+ e.preventDefault();
+ // y axis swipe
+ }else if((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY){
+ e.preventDefault();
+ }
+ if(slider.settings.mode != 'fade' && slider.settings.oneToOneTouch){
+ var value = 0;
+ // if horizontal, drag along x axis
+ if(slider.settings.mode == 'horizontal'){
+ var change = orig.changedTouches[0].pageX - slider.touch.start.x;
+ value = slider.touch.originalPos.left + change;
+ // if vertical, drag along y axis
+ }else{
+ var change = orig.changedTouches[0].pageY - slider.touch.start.y;
+ value = slider.touch.originalPos.top + change;
+ }
+ setPositionProperty(value, 'reset', 0);
+ }
+ }
+
+ /**
+ * Event handler for "touchend"
+ *
+ * @param e (event)
+ * - DOM event object
+ */
+ var onTouchEnd = function(e){
+ slider.viewport.unbind('touchmove', onTouchMove);
+ var orig = e.originalEvent;
+ var value = 0;
+ // record end x, y positions
+ slider.touch.end.x = orig.changedTouches[0].pageX;
+ slider.touch.end.y = orig.changedTouches[0].pageY;
+ // if fade mode, check if absolute x distance clears the threshold
+ if(slider.settings.mode == 'fade'){
+ var distance = Math.abs(slider.touch.start.x - slider.touch.end.x);
+ if(distance >= slider.settings.swipeThreshold){
+ slider.touch.start.x > slider.touch.end.x ? el.goToNextSlide() : el.goToPrevSlide();
+ el.stopAuto();
+ }
+ // not fade mode
+ }else{
+ var distance = 0;
+ // calculate distance and el's animate property
+ if(slider.settings.mode == 'horizontal'){
+ distance = slider.touch.end.x - slider.touch.start.x;
+ value = slider.touch.originalPos.left;
+ }else{
+ distance = slider.touch.end.y - slider.touch.start.y;
+ value = slider.touch.originalPos.top;
+ }
+ // if not infinite loop and first / last slide, do not attempt a slide transition
+ if(!slider.settings.infiniteLoop && ((slider.active.index == 0 && distance > 0) || (slider.active.last && distance < 0))){
+ setPositionProperty(value, 'reset', 200);
+ }else{
+ // check if distance clears threshold
+ if(Math.abs(distance) >= slider.settings.swipeThreshold){
+ distance < 0 ? el.goToNextSlide() : el.goToPrevSlide();
+ el.stopAuto();
+ }else{
+ // el.animate(property, 200);
+ setPositionProperty(value, 'reset', 200);
+ }
+ }
+ }
+ slider.viewport.unbind('touchend', onTouchEnd);
+ }
+
+ /**
+ * Window resize event callback
+ */
+ var resizeWindow = function(e){
+ // don't do anything if slider isn't initialized.
+ if(!slider.initialized) return;
+ // get the new window dimens (again, thank you IE)
+ var windowWidthNew = $(window).width();
+ var windowHeightNew = $(window).height();
+ // make sure that it is a true window resize
+ // *we must check this because our dinosaur friend IE fires a window resize event when certain DOM elements
+ // are resized. Can you just die already?*
+ if(windowWidth != windowWidthNew || windowHeight != windowHeightNew){
+ // set the new window dimens
+ windowWidth = windowWidthNew;
+ windowHeight = windowHeightNew;
+ // update all dynamic elements
+ el.redrawSlider();
+ // Call user resize handler
+ slider.settings.onSliderResize.call(el, slider.active.index);
+ }
+ }
+
+ /**
+ * ===================================================================================
+ * = PUBLIC FUNCTIONS
+ * ===================================================================================
+ */
+
+ /**
+ * Performs slide transition to the specified slide
+ *
+ * @param slideIndex (int)
+ * - the destination slide's index (zero-based)
+ *
+ * @param direction (string)
+ * - INTERNAL USE ONLY - the direction of travel ("prev" / "next")
+ */
+ el.goToSlide = function(slideIndex, direction){
+ // if plugin is currently in motion, ignore request
+ if(slider.working || slider.active.index == slideIndex) return;
+ // declare that plugin is in motion
+ slider.working = true;
+ // store the old index
+ slider.oldIndex = slider.active.index;
+ // if slideIndex is less than zero, set active index to last child (this happens during infinite loop)
+ if(slideIndex < 0){
+ slider.active.index = getPagerQty() - 1;
+ // if slideIndex is greater than children length, set active index to 0 (this happens during infinite loop)
+ }else if(slideIndex >= getPagerQty()){
+ slider.active.index = 0;
+ // set active index to requested slide
+ }else{
+ slider.active.index = slideIndex;
+ }
+ // onSlideBefore, onSlideNext, onSlidePrev callbacks
+ slider.settings.onSlideBefore(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
+ if(direction == 'next'){
+ slider.settings.onSlideNext(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
+ }else if(direction == 'prev'){
+ slider.settings.onSlidePrev(slider.children.eq(slider.active.index), slider.oldIndex, slider.active.index);
+ }
+ // check if last slide
+ slider.active.last = slider.active.index >= getPagerQty() - 1;
+ // update the pager with active class
+ if(slider.settings.pager) updatePagerActive(slider.active.index);
+ // // check for direction control update
+ if(slider.settings.controls) updateDirectionControls();
+ // if slider is set to mode: "fade"
+ if(slider.settings.mode == 'fade'){
+ // if adaptiveHeight is true and next height is different from current height, animate to the new height
+ if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
+ slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
+ }
+ // fade out the visible child and reset its z-index value
+ slider.children.filter(':visible').fadeOut(slider.settings.speed).css({zIndex: 0});
+ // fade in the newly requested slide
+ slider.children.eq(slider.active.index).css('zIndex', slider.settings.slideZIndex+1).fadeIn(slider.settings.speed, function(){
+ $(this).css('zIndex', slider.settings.slideZIndex);
+ updateAfterSlideTransition();
+ });
+ // slider mode is not "fade"
+ }else{
+ // if adaptiveHeight is true and next height is different from current height, animate to the new height
+ if(slider.settings.adaptiveHeight && slider.viewport.height() != getViewportHeight()){
+ slider.viewport.animate({height: getViewportHeight()}, slider.settings.adaptiveHeightSpeed);
+ }
+ var moveBy = 0;
+ var position = {left: 0, top: 0};
+ // if carousel and not infinite loop
+ if(!slider.settings.infiniteLoop && slider.carousel && slider.active.last){
+ if(slider.settings.mode == 'horizontal'){
+ // get the last child position
+ var lastChild = slider.children.eq(slider.children.length - 1);
+ position = lastChild.position();
+ // calculate the position of the last slide
+ moveBy = slider.viewport.width() - lastChild.outerWidth();
+ }else{
+ // get last showing index position
+ var lastShowingIndex = slider.children.length - slider.settings.minSlides;
+ position = slider.children.eq(lastShowingIndex).position();
+ }
+ // horizontal carousel, going previous while on first slide (infiniteLoop mode)
+ }else if(slider.carousel && slider.active.last && direction == 'prev'){
+ // get the last child position
+ var eq = slider.settings.moveSlides == 1 ? slider.settings.maxSlides - getMoveBy() : ((getPagerQty() - 1) * getMoveBy()) - (slider.children.length - slider.settings.maxSlides);
+ var lastChild = el.children('.bx-clone').eq(eq);
+ position = lastChild.position();
+ // if infinite loop and "Next" is clicked on the last slide
+ }else if(direction == 'next' && slider.active.index == 0){
+ // get the last clone position
+ position = el.find('> .bx-clone').eq(slider.settings.maxSlides).position();
+ slider.active.last = false;
+ // normal non-zero requests
+ }else if(slideIndex >= 0){
+ var requestEl = slideIndex * getMoveBy();
+ position = slider.children.eq(requestEl).position();
+ }
+
+ /* If the position doesn't exist
+ * (e.g. if you destroy the slider on a next click),
+ * it doesn't throw an error.
+ */
+ if ("undefined" !== typeof(position)) {
+ var value = slider.settings.mode == 'horizontal' ? -(position.left - moveBy) : -position.top;
+ // plugin values to be animated
+ setPositionProperty(value, 'slide', slider.settings.speed);
+ }
+ }
+ }
+
+ /**
+ * Transitions to the next slide in the show
+ */
+ el.goToNextSlide = function(){
+ // if infiniteLoop is false and last page is showing, disregard call
+ if (!slider.settings.infiniteLoop && slider.active.last) return;
+ var pagerIndex = parseInt(slider.active.index) + 1;
+ el.goToSlide(pagerIndex, 'next');
+ }
+
+ /**
+ * Transitions to the prev slide in the show
+ */
+ el.goToPrevSlide = function(){
+ // if infiniteLoop is false and last page is showing, disregard call
+ if (!slider.settings.infiniteLoop && slider.active.index == 0) return;
+ var pagerIndex = parseInt(slider.active.index) - 1;
+ el.goToSlide(pagerIndex, 'prev');
+ }
+
+ /**
+ * Starts the auto show
+ *
+ * @param preventControlUpdate (boolean)
+ * - if true, auto controls state will not be updated
+ */
+ el.startAuto = function(preventControlUpdate){
+ // if an interval already exists, disregard call
+ if(slider.interval) return;
+ // create an interval
+ slider.interval = setInterval(function(){
+ slider.settings.autoDirection == 'next' ? el.goToNextSlide() : el.goToPrevSlide();
+ }, slider.settings.pause);
+ // if auto controls are displayed and preventControlUpdate is not true
+ if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('stop');
+ }
+
+ /**
+ * Stops the auto show
+ *
+ * @param preventControlUpdate (boolean)
+ * - if true, auto controls state will not be updated
+ */
+ el.stopAuto = function(preventControlUpdate){
+ // if no interval exists, disregard call
+ if(!slider.interval) return;
+ // clear the interval
+ clearInterval(slider.interval);
+ slider.interval = null;
+ // if auto controls are displayed and preventControlUpdate is not true
+ if (slider.settings.autoControls && preventControlUpdate != true) updateAutoControls('start');
+ }
+
+ /**
+ * Returns current slide index (zero-based)
+ */
+ el.getCurrentSlide = function(){
+ return slider.active.index;
+ }
+
+ /**
+ * Returns current slide element
+ */
+ el.getCurrentSlideElement = function(){
+ return slider.children.eq(slider.active.index);
+ }
+
+ /**
+ * Returns number of slides in show
+ */
+ el.getSlideCount = function(){
+ return slider.children.length;
+ }
+
+ /**
+ * Update all dynamic slider elements
+ */
+ el.redrawSlider = function(){
+ // resize all children in ratio to new screen size
+ slider.children.add(el.find('.bx-clone')).width(getSlideWidth());
+ // adjust the height
+ slider.viewport.css('height', getViewportHeight());
+ // update the slide position
+ if(!slider.settings.ticker) setSlidePosition();
+ // if active.last was true before the screen resize, we want
+ // to keep it last no matter what screen size we end on
+ if (slider.active.last) slider.active.index = getPagerQty() - 1;
+ // if the active index (page) no longer exists due to the resize, simply set the index as last
+ if (slider.active.index >= getPagerQty()) slider.active.last = true;
+ // if a pager is being displayed and a custom pager is not being used, update it
+ if(slider.settings.pager && !slider.settings.pagerCustom){
+ populatePager();
+ updatePagerActive(slider.active.index);
+ }
+ }
+
+ /**
+ * Destroy the current instance of the slider (revert everything back to original state)
+ */
+ el.destroySlider = function(){
+ // don't do anything if slider has already been destroyed
+ if(!slider.initialized) return;
+ slider.initialized = false;
+ $('.bx-clone', this).remove();
+ slider.children.each(function() {
+ $(this).data("origStyle") != undefined ? $(this).attr("style", $(this).data("origStyle")) : $(this).removeAttr('style');
+ });
+ $(this).data("origStyle") != undefined ? this.attr("style", $(this).data("origStyle")) : $(this).removeAttr('style');
+ $(this).unwrap().unwrap();
+ if(slider.controls.el) slider.controls.el.remove();
+ if(slider.controls.next) slider.controls.next.remove();
+ if(slider.controls.prev) slider.controls.prev.remove();
+ if(slider.pagerEl && slider.settings.controls) slider.pagerEl.remove();
+ $('.bx-caption', this).remove();
+ if(slider.controls.autoEl) slider.controls.autoEl.remove();
+ clearInterval(slider.interval);
+ if(slider.settings.responsive) $(window).unbind('resize', resizeWindow);
+ }
+
+ /**
+ * Reload the slider (revert all DOM changes, and re-initialize)
+ */
+ el.reloadSlider = function(settings){
+ if (settings != undefined) options = settings;
+ el.destroySlider();
+ init();
+ }
+
+ init();
+
+ // returns the current jQuery object
+ return this;
+ }
+
+})(jQuery);
diff --git a/public/assets/js/main.js b/public/assets/js/main.js
new file mode 100644
index 0000000..947b327
--- /dev/null
+++ b/public/assets/js/main.js
@@ -0,0 +1 @@
+(function(a){var c=a(window),b=a("body");a("[data-bg-image]").each(function(){var q=a(this),p=q.data("bg-image");q.css("background-image","url("+p+")")});a(window).on("scroll",function(p){var q=a(window).scrollTop()+1;if(q>250){a(".sticky-nav").addClass("menu_fixed animated fadeInDown")}else{a(".sticky-nav").removeClass("menu_fixed animated fadeInDown")}});a(".dropdown").on("show.bs.dropdown",function(){a(this).find(".dropdown-menu").first().stop(true,true).slideDown()});a(".dropdown").on("hide.bs.dropdown",function(){a(this).find(".dropdown-menu").first().stop(true,true).slideUp()});a(".color a").on("click",function(){a(".sidebar-widget-list a").removeClass("active");a(this).addClass("active")});a(".size a").on("click",function(){a(".sidebar-widget-list a").removeClass("active-2");a(this).addClass("active-2")});a(".pro-details-color a").on("click",function(){a(".pro-details-color a").removeClass("active-color");a(this).addClass("active-color")});a(".pro-details-size a").on("click",function(){a(".pro-details-size a").removeClass("active-size");a(this).addClass("active-size")});(function(){var s=a(".offcanvas-toggle"),q=a(".offcanvas"),r=a(".offcanvas-overlay"),p=a(".mobile-menu-toggle");s.on("click",function(v){v.preventDefault();var u=a(this),t=u.attr("href");b.addClass("offcanvas-open");a(t).addClass("offcanvas-open");r.fadeIn();if(u.parent().hasClass("mobile-menu-toggle")){u.addClass("close")}});a(".offcanvas-close, .offcanvas-overlay").on("click",function(t){t.preventDefault();b.removeClass("offcanvas-open");q.removeClass("offcanvas-open");r.fadeOut();p.find("a").removeClass("close")})})();function j(){var p=a(".offcanvas-menu, .overlay-menu"),q=p.find(".sub-menu");q.parent().prepend('');p.on("click","li a, .menu-expand",function(s){var r=a(this);if(r.attr("href")==="#"||r.hasClass("menu-expand")){s.preventDefault();if(r.siblings("ul:visible").length){r.parent("li").removeClass("active");r.siblings("ul").slideUp();r.parent("li").find("li").removeClass("active");r.parent("li").find("ul:visible").slideUp()}else{r.parent("li").addClass("active");r.closest("li").siblings("li").removeClass("active").find("li").removeClass("active");r.closest("li").siblings("li").find("ul:visible").slideUp();r.siblings("ul").slideDown()}}})}j();function k(){var p=a(".offcanvas-userpanel"),q=p.find(".user-sub-menu");q.parent().prepend('');p.on("click","li a, .offcanvas__user-expand",function(s){var r=a(this);if(r.attr("href")==="#"||r.hasClass("offcanvas__user-expand")){s.preventDefault();if(r.siblings("ul:visible").length){r.parent("li").removeClass("active");r.siblings("ul").slideUp();r.parent("li").find("li").removeClass("active");r.parent("li").find("ul:visible").slideUp()}else{r.parent("li").addClass("active");r.closest("li").siblings("li").removeClass("active").find("li").removeClass("active");r.closest("li").siblings("li").find("ul:visible").slideUp();r.siblings("ul").slideDown()}}})}k();var i=new Swiper(".hero-slider.swiper-container",{loop:true,speed:2000,effect:"fade",autoplay:{delay:7000,disableOnInteraction:false,},navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",}});var e=new Swiper(".tab-slider.swiper-container",{loop:true,slidesPerView:6,spaceBetween:30,speed:1500,navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",},breakpoints:{0:{slidesPerView:2,},478:{slidesPerView:2,},576:{slidesPerView:3,},768:{slidesPerView:4,},992:{slidesPerView:5,},1200:{slidesPerView:6,},},});var e=new Swiper(".testimonial-wrapper.swiper-container",{loop:true,slidesPerView:1,spaceBetween:30,speed:1500,navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",},breakpoints:{0:{slidesPerView:1,},478:{slidesPerView:1,},576:{slidesPerView:1,},768:{slidesPerView:1,},992:{slidesPerView:1,},1200:{slidesPerView:1,},},});var l=new Swiper(".new-product-slider.swiper-container",{slidesPerView:4,spaceBetween:30,speed:1500,loop:true,navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",},breakpoints:{0:{slidesPerView:1,},478:{slidesPerView:1,},576:{slidesPerView:2,},768:{slidesPerView:2,},992:{slidesPerView:3,},1200:{slidesPerView:4,},},});var g=new Swiper(".gallery-thumbs",{spaceBetween:10,slidesPerView:5,freeMode:true,watchSlidesVisibility:true,watchSlidesProgress:true,});var h=new Swiper(".gallery-top",{spaceBetween:0,loop:true,thumbs:{swiper:g}});var n=new Swiper(".zoom-thumbs",{spaceBetween:18,slidesPerView:5,freeMode:true,watchSlidesVisibility:true,watchSlidesProgress:true,});var o=new Swiper(".zoom-top",{spaceBetween:0,slidesPerView:1,thumbs:{swiper:n}});var n=new Swiper(".zoom-thumbs-2",{spaceBetween:15,slidesPerView:5,direction:"vertical",freeMode:true,watchSlidesVisibility:true,watchSlidesProgress:true,});var o=new Swiper(".zoom-top-2",{spaceBetween:0,loop:true,thumbs:{swiper:n}});var d=a(".cart-plus-minus");d.prepend('');d.append('');a(".qtybutton").on("click",function(){var p=a(this);var r=p.parent().find("input").val();if(p.text()==="+"){var q=parseFloat(r)+1}else{if(r>1){var q=parseFloat(r)-1}else{q=1}}p.parent().find("input").val(q)});var m=new Swiper(".single-product-slider",{slidesPerView:4,spaceBetween:20,speed:1500,loop:true,navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",},breakpoints:{0:{slidesPerView:1,},478:{slidesPerView:1,},576:{slidesPerView:2,},768:{slidesPerView:3,},992:{slidesPerView:3,},1024:{slidesPerView:4,},1200:{slidesPerView:4,},},});a(".checkout-toggle2").on("click",function(){a(".open-toggle2").slideToggle(1000)});a(".checkout-toggle").on("click",function(){a(".open-toggle").slideToggle(1000)});a.scrollUp({scrollText:'',easingType:"linear",scrollSpeed:900,animation:"fade",});a("[data-countdown]").each(function(){var p=a(this),q=a(this).data("countdown");p.countdown(q,function(r){p.html(r.strftime('%-DDays
%-HHours
%M Mins
%S Sec
'))})});var m=new Swiper(".blog-post-media.swiper-container",{slidesPerView:1,spaceBetween:0,loop:true,autoplay:{delay:2000,disableOnInteraction:false,},navigation:{nextEl:".swiper-button-next",prevEl:".swiper-button-prev",},});var f=new Swiper(".brand-slider.swiper-container",{slidesPerView:5,speed:1500,loop:true,autoplay:{delay:2000,disableOnInteraction:false,},breakpoints:{0:{slidesPerView:2,},480:{slidesPerView:3,},768:{slidesPerView:3,},992:{slidesPerView:4,},1200:{slidesPerView:5,},}});a(".shop-sort").niceSelect();a(".zoom-image-hover").zoom();a(".venobox").venobox()})(jQuery);
\ No newline at end of file
diff --git a/public/assets/js/plugins/plugins.min.js b/public/assets/js/plugins/plugins.min.js
new file mode 100644
index 0000000..ca9f4b3
--- /dev/null
+++ b/public/assets/js/plugins/plugins.min.js
@@ -0,0 +1,117 @@
+/*
+ *
+ * scrollup
+ * Url: http://markgoodyear.com/labs/scrollup/
+ * v2.4.1
+ *
+ */
+!function(l,o,e){"use strict";l.fn.scrollUp=function(o){l.data(e.body,"scrollUp")||(l.data(e.body,"scrollUp",!0),l.fn.scrollUp.init(o))},l.fn.scrollUp.init=function(r){var s,t,c,i,n,a,d=l.fn.scrollUp.Settings=l.extend({},l.fn.scrollUp.defaults,r),p=!1;switch(a=d.scrollTrigger?l(d.scrollTrigger):l("",{id:d.scrollName,href:"#top"}),d.scrollTitle&&a.attr("title",d.scrollTitle),a.appendTo("body"),d.scrollImg||d.scrollTrigger||a.html(d.scrollText),a.css({display:"none",position:"fixed",zIndex:d.zIndex}),d.activeOverlay&&l("",{id:d.scrollName+"-active"}).css({position:"absolute",top:d.scrollDistance+"px",width:"100%",borderTop:"1px dotted"+d.activeOverlay,zIndex:d.zIndex}).appendTo("body"),d.animation){case"fade":s="fadeIn",t="fadeOut",c=d.animationSpeed;break;case"slide":s="slideDown",t="slideUp",c=d.animationSpeed;break;default:s="show",t="hide",c=0}i="top"===d.scrollFrom?d.scrollDistance:l(e).height()-l(o).height()-d.scrollDistance,l(o).scroll(function(){l(o).scrollTop()>i?p||(a[s](c),p=!0):p&&(a[t](c),p=!1)}),d.scrollTarget?"number"==typeof d.scrollTarget?n=d.scrollTarget:"string"==typeof d.scrollTarget&&(n=Math.floor(l(d.scrollTarget).offset().top)):n=0,a.click(function(o){o.preventDefault(),l("html, body").animate({scrollTop:n},d.scrollSpeed,d.easingType)})},l.fn.scrollUp.defaults={scrollName:"scrollUp",scrollDistance:300,scrollFrom:"top",scrollSpeed:300,easingType:"linear",animation:"fade",animationSpeed:200,scrollTrigger:!1,scrollTarget:!1,scrollText:"Scroll to top",scrollTitle:!1,scrollImg:!1,activeOverlay:!1,zIndex:2147483647},l.fn.scrollUp.destroy=function(r){l.removeData(e.body,"scrollUp"),l("#"+l.fn.scrollUp.Settings.scrollName).remove(),l("#"+l.fn.scrollUp.Settings.scrollName+"-active").remove(),l.fn.jquery.split(".")[1]>=7?l(o).off("scroll",r):l(o).unbind("scroll",r)},l.scrollUp=l.fn.scrollUp}(jQuery,window,document);
+
+
+/*!
+ Zoom 1.7.21
+ license: MIT
+ http://www.jacklmoore.com/zoom
+*/
+!function(o){var t={url:!1,callback:!1,target:!1,duration:120,on:"mouseover",touch:!0,onZoomIn:!1,onZoomOut:!1,magnify:1};o.zoom=function(t,n,e,i){var u,c,a,r,m,l,s,f=o(t),h=f.css("position"),d=o(n);return t.style.position=/(absolute|fixed)/.test(h)?h:"relative",t.style.overflow="hidden",e.style.width=e.style.height="",o(e).addClass("zoomImg").css({position:"absolute",top:0,left:0,opacity:0,width:e.width*i,height:e.height*i,border:"none",maxWidth:"none",maxHeight:"none"}).appendTo(t),{init:function(){c=f.outerWidth(),u=f.outerHeight(),n===t?(r=c,a=u):(r=d.outerWidth(),a=d.outerHeight()),m=(e.width-c)/r,l=(e.height-u)/a,s=d.offset()},move:function(o){var t=o.pageX-s.left,n=o.pageY-s.top;n=Math.max(Math.min(n,a),0),t=Math.max(Math.min(t,r),0),e.style.left=t*-m+"px",e.style.top=n*-l+"px"}}},o.fn.zoom=function(n){return this.each(function(){var e=o.extend({},t,n||{}),i=e.target&&o(e.target)[0]||this,u=this,c=o(u),a=document.createElement("img"),r=o(a),m="mousemove.zoom",l=!1,s=!1;if(!e.url){var f=u.querySelector("img");if(f&&(e.url=f.getAttribute("data-src")||f.currentSrc||f.src),!e.url)return}c.one("zoom.destroy",function(o,t){c.off(".zoom"),i.style.position=o,i.style.overflow=t,a.onload=null,r.remove()}.bind(this,i.style.position,i.style.overflow)),a.onload=function(){function t(t){f.init(),f.move(t),r.stop().fadeTo(o.support.opacity?e.duration:0,1,!!o.isFunction(e.onZoomIn)&&e.onZoomIn.call(a))}function n(){r.stop().fadeTo(e.duration,0,!!o.isFunction(e.onZoomOut)&&e.onZoomOut.call(a))}var f=o.zoom(i,u,a,e.magnify);"grab"===e.on?c.on("mousedown.zoom",function(e){1===e.which&&(o(document).one("mouseup.zoom",function(){n(),o(document).off(m,f.move)}),t(e),o(document).on(m,f.move),e.preventDefault())}):"click"===e.on?c.on("click.zoom",function(e){return l?void 0:(l=!0,t(e),o(document).on(m,f.move),o(document).one("click.zoom",function(){n(),l=!1,o(document).off(m,f.move)}),!1)}):"toggle"===e.on?c.on("click.zoom",function(o){l?n():t(o),l=!l}):"mouseover"===e.on&&(f.init(),c.on("mouseenter.zoom",t).on("mouseleave.zoom",n).on(m,f.move)),e.touch&&c.on("touchstart.zoom",function(o){o.preventDefault(),s?(s=!1,n()):(s=!0,t(o.originalEvent.touches[0]||o.originalEvent.changedTouches[0]))}).on("touchmove.zoom",function(o){o.preventDefault(),f.move(o.originalEvent.touches[0]||o.originalEvent.changedTouches[0])}).on("touchend.zoom",function(o){o.preventDefault(),s&&(s=!1,n())}),o.isFunction(e.callback)&&e.callback.call(a)},a.setAttribute("role","presentation"),a.alt="",a.src=e.url})},o.fn.zoom.defaults=t}(window.jQuery);
+
+
+
+/* jQuery Nice Select - v1.0
+ https://github.com/hernansartorio/jquery-nice-select
+ Made by Hernán Sartorio */
+
+
+!function(e){e.fn.niceSelect=function(t){function s(t){t.after(e("").addClass("nice-select").addClass(t.attr("class")||"").addClass(t.attr("disabled")?"disabled":"").attr("tabindex",t.attr("disabled")?null:"0").html('
'));var s=t.next(),n=t.find("option"),i=t.find("option:selected");s.find(".current").html(i.data("display")||i.text()),n.each(function(t){var n=e(this),i=n.data("display");s.find("ul").append(e("").attr("data-value",n.val()).attr("data-display",i||null).addClass("option"+(n.is(":selected")?" selected":"")+(n.is(":disabled")?" disabled":"")).html(n.text()))})}if("string"==typeof t)return"update"==t?this.each(function(){var t=e(this),n=e(this).next(".nice-select"),i=n.hasClass("open");n.length&&(n.remove(),s(t),i&&t.next().trigger("click"))}):"destroy"==t?(this.each(function(){var t=e(this),s=e(this).next(".nice-select");s.length&&(s.remove(),t.css("display",""))}),0==e(".nice-select").length&&e(document).off(".nice_select")):console.log('Method "'+t+'" does not exist.'),this;this.hide(),this.each(function(){var t=e(this);t.next().hasClass("nice-select")||s(t)}),e(document).off(".nice_select"),e(document).on("click.nice_select",".nice-select",function(t){var s=e(this);e(".nice-select").not(s).removeClass("open"),s.toggleClass("open"),s.hasClass("open")?(s.find(".option"),s.find(".focus").removeClass("focus"),s.find(".selected").addClass("focus")):s.focus()}),e(document).on("click.nice_select",function(t){0===e(t.target).closest(".nice-select").length&&e(".nice-select").removeClass("open").find(".option")}),e(document).on("click.nice_select",".nice-select .option:not(.disabled)",function(t){var s=e(this),n=s.closest(".nice-select");n.find(".selected").removeClass("selected"),s.addClass("selected");var i=s.data("display")||s.text();n.find(".current").text(i),n.prev("select").val(s.data("value")).trigger("change")}),e(document).on("keydown.nice_select",".nice-select",function(t){var s=e(this),n=e(s.find(".focus")||s.find(".list .option.selected"));if(32==t.keyCode||13==t.keyCode)return s.hasClass("open")?n.trigger("click"):s.trigger("click"),!1;if(40==t.keyCode){if(s.hasClass("open")){var i=n.nextAll(".option:not(.disabled)").first();i.length>0&&(s.find(".focus").removeClass("focus"),i.addClass("focus"))}else s.trigger("click");return!1}if(38==t.keyCode){if(s.hasClass("open")){var l=n.prevAll(".option:not(.disabled)").first();l.length>0&&(s.find(".focus").removeClass("focus"),l.addClass("focus"))}else s.trigger("click");return!1}if(27==t.keyCode)s.hasClass("open")&&s.trigger("click");else if(9==t.keyCode&&s.hasClass("open"))return!1});var n=document.createElement("a").style;return n.cssText="pointer-events:auto","auto"!==n.pointerEvents&&e("html").addClass("no-csspointerevents"),this}}(jQuery);
+
+
+
+
+$(document).ready(function() {
+ $("#slider-range").slider({
+ range: true,
+ min: 0,
+ max: 100,
+ values: [0, 100],
+ slide: function(event, ui) {
+ $("#amount").val("$" + ui.values[0] + " - $" + ui.values[1]);
+ }
+ });
+ $("#amount").val("$" + $("#slider-range").slider("values", 0) +
+ " - $" + $("#slider-range").slider("values", 1));
+
+});
+
+
+/*!
+ * The Final Countdown for jQuery v2.1.0 (http://hilios.github.io/jQuery.countdown/)
+ * Copyright (c) 2015 Edson Hilios
+ */
+!function(t){"use strict";"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){"use strict";function e(t){var e=t.toString().replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");return new RegExp(e)}function s(t){return function(s){var i=s.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);if(i)for(var a=0,o=i.length;o>a;++a){var r=i[a].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/),l=e(r[0]),c=r[1]||"",u=r[3]||"",f=null;r=r[2],h.hasOwnProperty(r)&&(f=h[r],f=Number(t[f])),null!==f&&("!"===c&&(f=n(u,f)),""===c&&10>f&&(f="0"+f.toString()),s=s.replace(l,f.toString()))}return s.replace(/%%/,"%")}}function n(t,e){var s="s",n="";return t&&(1===(t=t.replace(/(:|;|\s)/gi,"").split(/\,/)).length?s=t[0]:(n=t[0],s=t[1])),1===Math.abs(e)?n:s}var i=[],a=[],o={precision:100,elapse:!1};a.push(/^[0-9]*$/.source),a.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),a.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),a=new RegExp(a.join("|"));var h={Y:"years",m:"months",n:"daysToMonth",w:"weeks",d:"daysToWeek",D:"totalDays",H:"hours",M:"minutes",S:"seconds"},r=function(e,s,n){this.el=e,this.$el=t(e),this.interval=null,this.offset={},this.options=t.extend({},o),this.instanceNumber=i.length,i.push(this),this.$el.data("countdown-instance",this.instanceNumber),n&&("function"==typeof n?(this.$el.on("update.countdown",n),this.$el.on("stoped.countdown",n),this.$el.on("finish.countdown",n)):this.options=t.extend({},o,n)),this.setFinalDate(s),this.start()};t.extend(r.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var t=this;this.update(),this.interval=setInterval(function(){t.update.call(t)},this.options.precision)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),i[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(t){this.finalDate=function(t){if(t instanceof Date)return t;if(String(t).match(a))return String(t).match(/^[0-9]*$/)&&(t=Number(t)),String(t).match(/\-/)&&(t=String(t).replace(/\-/g,"/")),new Date(t);throw new Error("Couldn't cast `"+t+"` to a date object.")}(t)},update:function(){if(0!==this.$el.closest("html").length){var e,s=void 0!==t._data(this.el,"events"),n=new Date;e=this.finalDate.getTime()-n.getTime(),e=Math.ceil(e/1e3),e=!this.options.elapse&&0>e?0:Math.abs(e),this.totalSecsLeft!==e&&s&&(this.totalSecsLeft=e,this.elapsed=n>=this.finalDate,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToWeek:Math.floor(this.totalSecsLeft/60/60/24)%7,daysToMonth:Math.floor(this.totalSecsLeft/60/60/24%30.4368),totalDays:Math.floor(this.totalSecsLeft/60/60/24),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),months:Math.floor(this.totalSecsLeft/60/60/24/30.4368),years:Math.abs(this.finalDate.getFullYear()-n.getFullYear())},this.options.elapse||0!==this.totalSecsLeft?this.dispatchEvent("update"):(this.stop(),this.dispatchEvent("finish")))}else this.remove()},dispatchEvent:function(e){var n=t.Event(e+".countdown");n.finalDate=this.finalDate,n.elapsed=this.elapsed,n.offset=t.extend({},this.offset),n.strftime=s(this.offset),this.$el.trigger(n)}}),t.fn.countdown=function(){var e=Array.prototype.slice.call(arguments,0);return this.each(function(){var s=t(this).data("countdown-instance");if(void 0!==s){var n=i[s],a=e[0];r.prototype.hasOwnProperty(a)?n[a].apply(n,e.slice(1)):null===String(a).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(n.setFinalDate.call(n,a),n.start()):t.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,a))}else new r(this,e[0],e[1])})}});
+
+
+/*
+ * VenoBox - jQuery Plugin
+ * version: 1.9.1
+ * @requires jQuery >= 1.7.0
+ *
+ * Examples at http://veno.es/venobox/
+ * License: MIT License
+ * License URI: https://github.com/nicoldfranchini/VenoBox/blob/master/LICENSE
+ * Copyright 2013-2021 Nicold Franchini - @nicoldfranchini
+ *
+ */
+
+!function(e){"use strict";var s,i,a,t,o,c,r,l,d,n,v,u,b,h,k,p,g,m,f,x,w,y,_,C,z,B,P,M,E,O,D,N,U,V,I,j,R,X,Y,W,q,$,T,A,H,Q,S,Z='',F='',G='',J='',K='';e.fn.extend({venobox:function(L){var ee=this,se=e.extend({arrowsColor:"#B6B6B6",autoplay:!1,bgcolor:"#fff",border:"0",closeBackground:"transparent",closeColor:"#d2d2d2",framewidth:"",frameheight:"",gallItems:!1,infinigall:!1,htmlClose:"×",htmlNext:"Next",htmlPrev:"Prev",numeratio:!1,numerationBackground:"#161617",numerationColor:"#d2d2d2",numerationPosition:"top",overlayClose:!0,overlayColor:"rgba(23,23,23,0.85)",spinner:"double-bounce",spinColor:"#d2d2d2",titleattr:"title",titleBackground:"#161617",titleColor:"#d2d2d2",titlePosition:"top",share:[],cb_pre_open:function(){return!0},cb_post_open:function(){},cb_pre_close:function(){return!0},cb_post_close:function(){},cb_post_resize:function(){},cb_after_nav:function(){},cb_content_loaded:function(){},cb_init:function(){}},L);return se.cb_init(ee),this.each(function(){if((N=e(this)).data("venobox"))return!0;function L(){C=N.data("gall"),x=N.data("numeratio"),k=N.data("gallItems"),p=N.data("infinigall"),H=N.data("share"),o.html(""),"iframe"!==N.data("vbtype")&&"inline"!==N.data("vbtype")&&"ajax"!==N.data("vbtype")&&(Q={pinterest:''+Z+"",facebook:''+F+"",twitter:''+G+"",linkedin:''+J+"",download:''+K+""},e.each(H,function(e,s){o.append(Q[s])})),(g=k||e('.vbox-item[data-gall="'+C+'"]')).length<2&&(p=!1,x=!1),z=g.eq(g.index(N)+1),B=g.eq(g.index(N)-1),z.length||!0!==p||(z=g.eq(0)),g.length>=1?(U=g.index(N)+1,t.html(U+" / "+g.length)):U=1,!0===x?t.show():t.hide(),""!==_?c.show():c.hide(),z.length||!0===p?(e(".vbox-next").css("display","block"),P=!0):(e(".vbox-next").css("display","none"),P=!1),g.index(N)>0||!0===p?(e(".vbox-prev").css("display","block"),M=!0):(e(".vbox-prev").css("display","none"),M=!1),!0!==M&&!0!==P||(n.on(de.DOWN,ce),n.on(de.MOVE,re),n.on(de.UP,le))}function ie(e){return!(e.length<1)&&!m&&(m=!0,w=e.data("overlay")||e.data("overlaycolor"),b=e.data("framewidth"),h=e.data("frameheight"),r=e.data("border"),i=e.data("bgcolor"),v=e.data("href")||e.attr("href"),s=e.data("autoplay"),_=e.data("titleattr")&&e.attr(e.data("titleattr"))||"",e===B&&n.addClass("vbox-animated").addClass("swipe-right"),e===z&&n.addClass("vbox-animated").addClass("swipe-left"),O.show(),void n.animate({opacity:0},500,function(){y.css("background",w),n.removeClass("vbox-animated").removeClass("swipe-left").removeClass("swipe-right").css({"margin-left":0,"margin-right":0}),"iframe"==e.data("vbtype")?he():"inline"==e.data("vbtype")?pe():"ajax"==e.data("vbtype")?be():"video"==e.data("vbtype")?ke(s):(n.html('
'),ge()),N=e,L(),m=!1,se.cb_after_nav(N,U,z,B)}))}function ae(e){27===e.keyCode&&te(),37==e.keyCode&&!0===M&&ie(B),39==e.keyCode&&!0===P&&ie(z)}function te(){if(!1===se.cb_pre_close(N,U,z,B))return!1;e("body").off("keydown",ae).removeClass("vbox-open"),N.focus(),y.animate({opacity:0},500,function(){y.remove(),m=!1,se.cb_post_close()})}ee.VBclose=function(){te()},N.addClass("vbox-item"),N.data("framewidth",se.framewidth),N.data("frameheight",se.frameheight),N.data("border",se.border),N.data("bgcolor",se.bgcolor),N.data("numeratio",se.numeratio),N.data("gallItems",se.gallItems),N.data("infinigall",se.infinigall),N.data("overlaycolor",se.overlayColor),N.data("titleattr",se.titleattr),N.data("share",se.share),N.data("venobox",!0),N.on("click",function(k){if(k.preventDefault(),N=e(this),!1===se.cb_pre_open(N))return!1;switch(ee.VBnext=function(){ie(z)},ee.VBprev=function(){ie(B)},w=N.data("overlay")||N.data("overlaycolor"),b=N.data("framewidth"),h=N.data("frameheight"),s=N.data("autoplay")||se.autoplay,r=N.data("border"),i=N.data("bgcolor"),P=!1,M=!1,m=!1,v=N.data("href")||N.attr("href"),u=N.data("css")||"",_=N.attr(N.data("titleattr"))||"",H=N.data("share"),E='',se.spinner){case"rotating-plane":E+='';break;case"double-bounce":E+='';break;case"wave":E+='';break;case"wandering-cubes":E+='';break;case"spinner-pulse":E+='';break;case"chasing-dots":E+='';break;case"three-bounce":E+='';break;case"circle":E+='';break;case"cube-grid":E+='';break;case"fading-circle":E+='';break;case"folding-cube":E+=''}return E+="",D=''+se.htmlNext+''+se.htmlPrev+"",I='0/0'+se.htmlClose+"",l='',e("body").append(l).addClass("vbox-open"),e(".vbox-preloader div:not(.sk-circle) .sk-child, .vbox-preloader .sk-rotating-plane, .vbox-preloader .sk-rect, .vbox-preloader div:not(.sk-folding-cube) .sk-cube, .vbox-preloader .sk-spinner-pulse").css("background-color",se.spinColor),y=e(".vbox-overlay"),d=e(".vbox-container"),n=e(".vbox-content"),a=e(".vbox-left"),t=e(".vbox-num"),o=e(".vbox-share"),c=e(".vbox-title"),(O=e(".vbox-preloader")).show(),S="top"==se.titlePosition?"bottom":"top",o.css(S,"-1px"),o.css({color:se.titleColor,fill:se.titleColor,"background-color":se.titleBackground}),c.css(se.titlePosition,"-1px"),c.css({color:se.titleColor,"background-color":se.titleBackground}),e(".vbox-close").css({color:se.closeColor,"background-color":se.closeBackground}),a.css(se.numerationPosition,"-1px"),a.css({color:se.numerationColor,"background-color":se.numerationBackground}),e(".vbox-next span, .vbox-prev span").css({"border-top-color":se.arrowsColor,"border-right-color":se.arrowsColor}),n.html(""),n.css("opacity","0"),y.css("opacity","0"),L(),y.animate({opacity:1},250,function(){"iframe"==N.data("vbtype")?he():"inline"==N.data("vbtype")?pe():"ajax"==N.data("vbtype")?be():"video"==N.data("vbtype")?ke(s):(n.html('
'),ge()),se.cb_post_open(N,U,z,B)}),e("body").keydown(ae),e(".vbox-prev").on("click",function(){ie(B)}),e(".vbox-next").on("click",function(){ie(z)}),!1});var oe=".vbox-overlay";function ce(e){n.addClass("vbox-animated"),R=Y=e.pageY,X=W=e.pageX,V=!0}function re(e){if(!0===V){W=e.pageX,Y=e.pageY,$=W-X,T=Y-R;var s=Math.abs($);s>Math.abs(T)&&s<=100&&(e.preventDefault(),n.css("margin-left",$))}}function le(e){if(!0===V){V=!1;var s=N,i=!1;(q=W-X)<0&&!0===P&&(s=z,i=!0),q>0&&!0===M&&(s=B,i=!0),Math.abs(q)>=A&&!0===i?ie(s):n.css({"margin-left":0,"margin-right":0})}}se.overlayClose||(oe=".vbox-close"),e("body").on("click touchstart",oe,function(s){(e(s.target).is(".vbox-overlay")||e(s.target).is(".vbox-content")||e(s.target).is(".vbox-close")||e(s.target).is(".vbox-preloader")||e(s.target).is(".vbox-container"))&&te()}),X=0,W=0,q=0,A=50,V=!1;var de={DOWN:"touchmousedown",UP:"touchmouseup",MOVE:"touchmousemove"},ne=function(s){var i;switch(s.type){case"mousedown":i=de.DOWN;break;case"mouseup":case"mouseout":i=de.UP;break;case"mousemove":i=de.MOVE;break;default:return}var a=ue(i,s,s.pageX,s.pageY);e(s.target).trigger(a)},ve=function(s){var i;switch(s.type){case"touchstart":i=de.DOWN;break;case"touchend":i=de.UP;break;case"touchmove":i=de.MOVE;break;default:return}var a,t=s.originalEvent.touches[0];a=i==de.UP?ue(i,s,null,null):ue(i,s,t.pageX,t.pageY),e(s.target).trigger(a)},ue=function(s,i,a,t){return e.Event(s,{pageX:a,pageY:t,originalEvent:i})};function be(){e.ajax({url:v,cache:!1}).done(function(e){n.html(''+e+""),ge()}).fail(function(){n.html('Error retrieving contents, please retry
'),me()})}function he(){n.html(''),me()}function ke(e){var s,i=function(e){var s;return v.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/),RegExp.$3.indexOf("youtu")>-1?s="youtube":RegExp.$3.indexOf("vimeo")>-1&&(s="vimeo"),{type:s,id:RegExp.$6}}(),a=(e?"?rel=0&autoplay=1":"?rel=0")+function(e){var s="",i=decodeURIComponent(v).split("?");if(void 0!==i[1]){var a,t,o=i[1].split("&");for(t=0;t'),me()}function pe(){n.html(''+e(v).html()+""),me()}function ge(){(j=n.find("img")).length?j.each(function(){e(this).one("load",function(){me()})}):me()}function me(){c.html(_),n.find(">:first-child").addClass("vbox-figlio").css({width:b,height:h,padding:r,background:i}),e("img.vbox-figlio").on("dragstart",function(e){e.preventDefault()}),d.scrollTop(0),fe(),n.animate({opacity:"1"},"slow",function(){O.hide()}),se.cb_content_loaded(N,U,z,B)}function fe(){var s=n.outerHeight(),i=e(window).height();f=s+60+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"�":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){p()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(j=O.call(w.childNodes),w.childNodes),j[w.childNodes.length].nodeType}catch(t){H={apply:j.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}function se(e,t,r,i){var o,s,l,c,f,h,y,m=t&&t.ownerDocument,w=t?t.nodeType:9;if(r=r||[],"string"!=typeof e||!e||1!==w&&9!==w&&11!==w)return r;if(!i&&(p(t),t=t||d,g)){if(11!==w&&(f=Z.exec(e)))if(o=f[1]){if(9===w){if(!(l=t.getElementById(o)))return r;if(l.id===o)return r.push(l),r}else if(m&&(l=m.getElementById(o))&&x(t,l)&&l.id===o)return r.push(l),r}else{if(f[2])return H.apply(r,t.getElementsByTagName(e)),r;if((o=f[3])&&n.getElementsByClassName&&t.getElementsByClassName)return H.apply(r,t.getElementsByClassName(o)),r}if(n.qsa&&!A[e+" "]&&(!v||!v.test(e))&&(1!==w||"object"!==t.nodeName.toLowerCase())){if(y=e,m=t,1===w&&(U.test(e)||z.test(e))){for((m=ee.test(e)&&ye(t.parentNode)||t)===t&&n.scope||((c=t.getAttribute("id"))?c=c.replace(re,ie):t.setAttribute("id",c=b)),s=(h=a(e)).length;s--;)h[s]=(c?"#"+c:":scope")+" "+xe(h[s]);y=h.join(",")}try{return H.apply(r,m.querySelectorAll(y)),r}catch(t){A(e,!0)}finally{c===b&&t.removeAttribute("id")}}}return u(e.replace($,"$1"),t,r,i)}function ue(){var e=[];return function t(n,i){return e.push(n+" ")>r.cacheLength&&delete t[e.shift()],t[n+" "]=i}}function le(e){return e[b]=!0,e}function ce(e){var t=d.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){for(var n=e.split("|"),i=n.length;i--;)r.attrHandle[n[i]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function de(e){return function(t){return"input"===t.nodeName.toLowerCase()&&t.type===e}}function he(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function ge(e){return function(t){return"form"in t?t.parentNode&&!1===t.disabled?"label"in t?"label"in t.parentNode?t.parentNode.disabled===e:t.disabled===e:t.isDisabled===e||t.isDisabled!==!e&&ae(t)===e:t.disabled===e:"label"in t&&t.disabled===e}}function ve(e){return le(function(t){return t=+t,le(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function ye(e){return e&&void 0!==e.getElementsByTagName&&e}for(t in n=se.support={},o=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},p=se.setDocument=function(e){var t,i,a=e?e.ownerDocument||e:w;return a!=d&&9===a.nodeType&&a.documentElement&&(h=(d=a).documentElement,g=!o(d),w!=d&&(i=d.defaultView)&&i.top!==i&&(i.addEventListener?i.addEventListener("unload",oe,!1):i.attachEvent&&i.attachEvent("onunload",oe)),n.scope=ce(function(e){return h.appendChild(e).appendChild(d.createElement("div")),void 0!==e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),n.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),n.getElementsByTagName=ce(function(e){return e.appendChild(d.createComment("")),!e.getElementsByTagName("*").length}),n.getElementsByClassName=K.test(d.getElementsByClassName),n.getById=ce(function(e){return h.appendChild(e).id=b,!d.getElementsByName||!d.getElementsByName(b).length}),n.getById?(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n=t.getElementById(e);return n?[n]:[]}}):(r.filter.ID=function(e){var t=e.replace(te,ne);return function(e){var n=void 0!==e.getAttributeNode&&e.getAttributeNode("id");return n&&n.value===t}},r.find.ID=function(e,t){if(void 0!==t.getElementById&&g){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];for(i=t.getElementsByName(e),r=0;o=i[r++];)if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),r.find.TAG=n.getElementsByTagName?function(e,t){return void 0!==t.getElementsByTagName?t.getElementsByTagName(e):n.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},r.find.CLASS=n.getElementsByClassName&&function(e,t){if(void 0!==t.getElementsByClassName&&g)return t.getElementsByClassName(e)},y=[],v=[],(n.qsa=K.test(d.querySelectorAll))&&(ce(function(e){var t;h.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+b+"-]").length||v.push("~="),(t=d.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+b+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML="";var t=d.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),h.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(n.matchesSelector=K.test(m=h.matches||h.webkitMatchesSelector||h.mozMatchesSelector||h.oMatchesSelector||h.msMatchesSelector))&&ce(function(e){n.disconnectedMatch=m.call(e,"*"),m.call(e,"[s!='']:x"),y.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),y=y.length&&new RegExp(y.join("|")),t=K.test(h.compareDocumentPosition),x=t||K.test(h.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},N=t?function(e,t){if(e===t)return f=!0,0;var r=!e.compareDocumentPosition-!t.compareDocumentPosition;return r||(1&(r=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!n.sortDetached&&t.compareDocumentPosition(e)===r?e==d||e.ownerDocument==w&&x(w,e)?-1:t==d||t.ownerDocument==w&&x(w,t)?1:c?P(c,e)-P(c,t):0:4&r?-1:1)}:function(e,t){if(e===t)return f=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==d?-1:t==d?1:i?-1:o?1:c?P(c,e)-P(c,t):0;if(i===o)return pe(e,t);for(n=e;n=n.parentNode;)a.unshift(n);for(n=t;n=n.parentNode;)s.unshift(n);for(;a[r]===s[r];)r++;return r?pe(a[r],s[r]):a[r]==w?-1:s[r]==w?1:0}),d},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(p(e),n.matchesSelector&&g&&!A[t+" "]&&(!y||!y.test(t))&&(!v||!v.test(t)))try{var r=m.call(e,t);if(r||n.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=a(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=E[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&E(e,function(e){return t.test("string"==typeof e.className&&e.className||void 0!==e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=se.attr(r,e);return null==i?"!="===t:!t||(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,t,n){return h(t)?w.grep(e,function(e,r){return!!t.call(e,r,e)!==n}):t.nodeType?w.grep(e,function(e){return e===t!==n}):"string"!=typeof t?w.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(w.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof w?t[0]:t,w.merge(this,w.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:v,!0)),N.test(r[1])&&w.isPlainObject(t))for(r in t)h(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=v.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):h(e)?void 0!==n.ready?n.ready(e):e(w):w.makeArray(e,this)}).prototype=w.fn,j=w(v);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){for(;(e=e[t])&&1!==e.nodeType;);return e}w.fn.extend({has:function(e){var t=w(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=v.createDocumentFragment().appendChild(v.createElement("div")),(fe=v.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),d.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",d.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML="",d.option=!!ce.lastChild;var ge={thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};function ve(e,t){var n;return n=void 0!==e.getElementsByTagName?e.getElementsByTagName(t||"*"):void 0!==e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?w.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&w(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(e.scriptAttrs||{}).prop({charset:e.scriptCharset,src:e.url}).on("load error",n=function(e){t.remove(),n=null,e&&i("error"===e.type?404:200,e.type)}),v.head.appendChild(t[0])},abort:function(){n&&n()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;w.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||w.expando+"_"+Ct.guid++;return this[e]=!0,e}}),w.ajaxPrefilter("json jsonp",function(t,n,r){var i,o,a,s=!1!==t.jsonp&&(Vt.test(t.url)?"url":"string"==typeof t.data&&0===(t.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(t.data)&&"data");if(s||"jsonp"===t.dataTypes[0])return i=t.jsonpCallback=h(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(Vt,"$1"+i):!1!==t.jsonp&&(t.url+=(Et.test(t.url)?"&":"?")+t.jsonp+"="+i),t.converters["script json"]=function(){return a||w.error(i+" was not called"),a[0]},t.dataTypes[0]="json",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?w(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,Xt.push(i)),a&&h(o)&&o(a[0]),a=o=void 0}),"script"}),d.createHTMLDocument=((Ut=v.implementation.createHTMLDocument("").body).innerHTML="",2===Ut.childNodes.length),w.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(d.createHTMLDocument?((r=(t=v.implementation.createHTMLDocument("")).createElement("base")).href=v.location.href,t.head.appendChild(r)):t=v),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&w(o).remove(),w.merge([],i.childNodes)));var r,i,o},w.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(w.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},w.expr.pseudos.animated=function(e){return w.grep(w.timers,function(t){return e===t.elem}).length},w.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=w.css(e,"position"),c=w(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=w.css(e,"top"),u=w.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),h(t)&&(t=t.call(e,n,w.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},w.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){w.offset.setOffset(this,e,t)});var t,n,r=this[0];return r?r.getClientRects().length?(t=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:t.top+n.pageYOffset,left:t.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===w.css(r,"position"))t=r.getBoundingClientRect();else{for(t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;e&&(e===n.body||e===n.documentElement)&&"static"===w.css(e,"position");)e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=w(e).offset()).top+=w.css(e,"borderTopWidth",!0),i.left+=w.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-w.css(r,"marginTop",!0),left:t.left-i.left-w.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent;e&&"static"===w.css(e,"position");)e=e.offsetParent;return e||re})}}),w.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,t){var n="pageYOffset"===t;w.fn[e]=function(r){return $(this,function(e,r,i){var o;if(g(e)?o=e:9===e.nodeType&&(o=e.defaultView),void 0===i)return o?o[t]:e[r];o?o.scrollTo(n?o.pageXOffset:i,n?i:o.pageYOffset):e[r]=i},e,r,arguments.length)}}),w.each(["top","left"],function(e,t){w.cssHooks[t]=$e(d.pixelPosition,function(e,n){if(n)return n=Be(e,t),Me.test(n)?w(e).position()[t]+"px":n})}),w.each({Height:"height",Width:"width"},function(e,t){w.each({padding:"inner"+e,content:t,"":"outer"+e},function(n,r){w.fn[r]=function(i,o){var a=arguments.length&&(n||"boolean"!=typeof i),s=n||(!0===i||!0===o?"margin":"border");return $(this,function(t,n,i){var o;return g(t)?0===r.indexOf("outer")?t["inner"+e]:t.document.documentElement["client"+e]:9===t.nodeType?(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){w.fn[t]=function(e){return this.on(t,e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return 0{do{t+=Math.floor(1e6*Math.random())}while(document.getElementById(t));return t},e=t=>{let e=t.getAttribute("data-bs-target");if(!e||"#"===e){let i=t.getAttribute("href");if(!i||!i.includes("#")&&!i.startsWith("."))return null;i.includes("#")&&!i.startsWith("#")&&(i="#"+i.split("#")[1]),e=i&&"#"!==i?i.trim():null}return e},i=t=>{const i=e(t);return i&&document.querySelector(i)?i:null},s=t=>{const i=e(t);return i?document.querySelector(i):null},n=t=>{if(!t)return 0;let{transitionDuration:e,transitionDelay:i}=window.getComputedStyle(t);const s=Number.parseFloat(e),n=Number.parseFloat(i);return s||n?(e=e.split(",")[0],i=i.split(",")[0],1e3*(Number.parseFloat(e)+Number.parseFloat(i))):0},o=t=>{t.dispatchEvent(new Event("transitionend"))},r=t=>(t[0]||t).nodeType,a=(t,e)=>{let i=!1;const s=e+5;t.addEventListener("transitionend",(function e(){i=!0,t.removeEventListener("transitionend",e)})),setTimeout(()=>{i||o(t)},s)},l=(t,e,i)=>{Object.keys(i).forEach(s=>{const n=i[s],o=e[s],a=o&&r(o)?"element":null==(l=o)?""+l:{}.toString.call(l).match(/\s([a-z]+)/i)[1].toLowerCase();var l;if(!new RegExp(n).test(a))throw new TypeError(t.toUpperCase()+": "+`Option "${s}" provided type "${a}" `+`but expected type "${n}".`)})},c=t=>{if(!t)return!1;if(t.style&&t.parentNode&&t.parentNode.style){const e=getComputedStyle(t),i=getComputedStyle(t.parentNode);return"none"!==e.display&&"none"!==i.display&&"hidden"!==e.visibility}return!1},d=t=>!t||t.nodeType!==Node.ELEMENT_NODE||!!t.classList.contains("disabled")||(void 0!==t.disabled?t.disabled:t.hasAttribute("disabled")&&"false"!==t.getAttribute("disabled")),h=t=>{if(!document.documentElement.attachShadow)return null;if("function"==typeof t.getRootNode){const e=t.getRootNode();return e instanceof ShadowRoot?e:null}return t instanceof ShadowRoot?t:t.parentNode?h(t.parentNode):null},f=()=>function(){},u=t=>t.offsetHeight,p=()=>{const{jQuery:t}=window;return t&&!document.body.hasAttribute("data-bs-no-jquery")?t:null},g=()=>"rtl"===document.documentElement.dir,m=(t,e)=>{var i;i=()=>{const i=p();if(i){const s=i.fn[t];i.fn[t]=e.jQueryInterface,i.fn[t].Constructor=e,i.fn[t].noConflict=()=>(i.fn[t]=s,e.jQueryInterface)}},"loading"===document.readyState?document.addEventListener("DOMContentLoaded",i):i()},_=new Map;var b={set(t,e,i){_.has(t)||_.set(t,new Map);const s=_.get(t);s.has(e)||0===s.size?s.set(e,i):console.error(`Bootstrap doesn't allow more than one instance per element. Bound instance: ${Array.from(s.keys())[0]}.`)},get:(t,e)=>_.has(t)&&_.get(t).get(e)||null,remove(t,e){if(!_.has(t))return;const i=_.get(t);i.delete(e),0===i.size&&_.delete(t)}};const v=/[^.]*(?=\..*)\.|.*/,y=/\..*/,w=/::\d+$/,E={};let T=1;const A={mouseenter:"mouseover",mouseleave:"mouseout"},L=new Set(["click","dblclick","mouseup","mousedown","contextmenu","mousewheel","DOMMouseScroll","mouseover","mouseout","mousemove","selectstart","selectend","keydown","keypress","keyup","orientationchange","touchstart","touchmove","touchend","touchcancel","pointerdown","pointermove","pointerup","pointerleave","pointercancel","gesturestart","gesturechange","gestureend","focus","blur","change","reset","select","submit","focusin","focusout","load","unload","beforeunload","resize","move","DOMContentLoaded","readystatechange","error","abort","scroll"]);function O(t,e){return e&&`${e}::${T++}`||t.uidEvent||T++}function k(t){const e=O(t);return t.uidEvent=e,E[e]=E[e]||{},E[e]}function D(t,e,i=null){const s=Object.keys(t);for(let n=0,o=s.length;n{!function(t,e,i,s){const n=e[i]||{};Object.keys(n).forEach(o=>{if(o.includes(s)){const s=n[o];S(t,e,i,s.originalHandler,s.delegationSelector)}})}(t,l,i,e.slice(1))});const d=l[r]||{};Object.keys(d).forEach(i=>{const s=i.replace(w,"");if(!a||e.includes(s)){const e=d[i];S(t,l,r,e.originalHandler,e.delegationSelector)}})},trigger(t,e,i){if("string"!=typeof e||!t)return null;const s=p(),n=e.replace(y,""),o=e!==n,r=L.has(n);let a,l=!0,c=!0,d=!1,h=null;return o&&s&&(a=s.Event(e,i),s(t).trigger(a),l=!a.isPropagationStopped(),c=!a.isImmediatePropagationStopped(),d=a.isDefaultPrevented()),r?(h=document.createEvent("HTMLEvents"),h.initEvent(n,l,!0)):h=new CustomEvent(e,{bubbles:l,cancelable:!0}),void 0!==i&&Object.keys(i).forEach(t=>{Object.defineProperty(h,t,{get:()=>i[t]})}),d&&h.preventDefault(),c&&t.dispatchEvent(h),h.defaultPrevented&&void 0!==a&&a.preventDefault(),h}};class j{constructor(t){(t="string"==typeof t?document.querySelector(t):t)&&(this._element=t,b.set(this._element,this.constructor.DATA_KEY,this))}dispose(){b.remove(this._element,this.constructor.DATA_KEY),this._element=null}static getInstance(t){return b.get(t,this.DATA_KEY)}static get VERSION(){return"5.0.0-beta3"}}class P extends j{static get DATA_KEY(){return"bs.alert"}close(t){const e=t?this._getRootElement(t):this._element,i=this._triggerCloseEvent(e);null===i||i.defaultPrevented||this._removeElement(e)}_getRootElement(t){return s(t)||t.closest(".alert")}_triggerCloseEvent(t){return N.trigger(t,"close.bs.alert")}_removeElement(t){if(t.classList.remove("show"),!t.classList.contains("fade"))return void this._destroyElement(t);const e=n(t);N.one(t,"transitionend",()=>this._destroyElement(t)),a(t,e)}_destroyElement(t){t.parentNode&&t.parentNode.removeChild(t),N.trigger(t,"closed.bs.alert")}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.alert");e||(e=new P(this)),"close"===t&&e[t](this)}))}static handleDismiss(t){return function(e){e&&e.preventDefault(),t.close(this)}}}N.on(document,"click.bs.alert.data-api",'[data-bs-dismiss="alert"]',P.handleDismiss(new P)),m("alert",P);class I extends j{static get DATA_KEY(){return"bs.button"}toggle(){this._element.setAttribute("aria-pressed",this._element.classList.toggle("active"))}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.button");e||(e=new I(this)),"toggle"===t&&e[t]()}))}}function M(t){return"true"===t||"false"!==t&&(t===Number(t).toString()?Number(t):""===t||"null"===t?null:t)}function R(t){return t.replace(/[A-Z]/g,t=>"-"+t.toLowerCase())}N.on(document,"click.bs.button.data-api",'[data-bs-toggle="button"]',t=>{t.preventDefault();const e=t.target.closest('[data-bs-toggle="button"]');let i=b.get(e,"bs.button");i||(i=new I(e)),i.toggle()}),m("button",I);const B={setDataAttribute(t,e,i){t.setAttribute("data-bs-"+R(e),i)},removeDataAttribute(t,e){t.removeAttribute("data-bs-"+R(e))},getDataAttributes(t){if(!t)return{};const e={};return Object.keys(t.dataset).filter(t=>t.startsWith("bs")).forEach(i=>{let s=i.replace(/^bs/,"");s=s.charAt(0).toLowerCase()+s.slice(1,s.length),e[s]=M(t.dataset[i])}),e},getDataAttribute:(t,e)=>M(t.getAttribute("data-bs-"+R(e))),offset(t){const e=t.getBoundingClientRect();return{top:e.top+document.body.scrollTop,left:e.left+document.body.scrollLeft}},position:t=>({top:t.offsetTop,left:t.offsetLeft})},H={find:(t,e=document.documentElement)=>[].concat(...Element.prototype.querySelectorAll.call(e,t)),findOne:(t,e=document.documentElement)=>Element.prototype.querySelector.call(e,t),children:(t,e)=>[].concat(...t.children).filter(t=>t.matches(e)),parents(t,e){const i=[];let s=t.parentNode;for(;s&&s.nodeType===Node.ELEMENT_NODE&&3!==s.nodeType;)s.matches(e)&&i.push(s),s=s.parentNode;return i},prev(t,e){let i=t.previousElementSibling;for(;i;){if(i.matches(e))return[i];i=i.previousElementSibling}return[]},next(t,e){let i=t.nextElementSibling;for(;i;){if(i.matches(e))return[i];i=i.nextElementSibling}return[]}},W={interval:5e3,keyboard:!0,slide:!1,pause:"hover",wrap:!0,touch:!0},U={interval:"(number|boolean)",keyboard:"boolean",slide:"(boolean|string)",pause:"(string|boolean)",wrap:"boolean",touch:"boolean"},$="next",F="prev",z="left",K="right";class Y extends j{constructor(t,e){super(t),this._items=null,this._interval=null,this._activeElement=null,this._isPaused=!1,this._isSliding=!1,this.touchTimeout=null,this.touchStartX=0,this.touchDeltaX=0,this._config=this._getConfig(e),this._indicatorsElement=H.findOne(".carousel-indicators",this._element),this._touchSupported="ontouchstart"in document.documentElement||navigator.maxTouchPoints>0,this._pointerEvent=Boolean(window.PointerEvent),this._addEventListeners()}static get Default(){return W}static get DATA_KEY(){return"bs.carousel"}next(){this._isSliding||this._slide($)}nextWhenVisible(){!document.hidden&&c(this._element)&&this.next()}prev(){this._isSliding||this._slide(F)}pause(t){t||(this._isPaused=!0),H.findOne(".carousel-item-next, .carousel-item-prev",this._element)&&(o(this._element),this.cycle(!0)),clearInterval(this._interval),this._interval=null}cycle(t){t||(this._isPaused=!1),this._interval&&(clearInterval(this._interval),this._interval=null),this._config&&this._config.interval&&!this._isPaused&&(this._updateInterval(),this._interval=setInterval((document.visibilityState?this.nextWhenVisible:this.next).bind(this),this._config.interval))}to(t){this._activeElement=H.findOne(".active.carousel-item",this._element);const e=this._getItemIndex(this._activeElement);if(t>this._items.length-1||t<0)return;if(this._isSliding)return void N.one(this._element,"slid.bs.carousel",()=>this.to(t));if(e===t)return this.pause(),void this.cycle();const i=t>e?$:F;this._slide(i,this._items[t])}dispose(){N.off(this._element,".bs.carousel"),this._items=null,this._config=null,this._interval=null,this._isPaused=null,this._isSliding=null,this._activeElement=null,this._indicatorsElement=null,super.dispose()}_getConfig(t){return t={...W,...t},l("carousel",t,U),t}_handleSwipe(){const t=Math.abs(this.touchDeltaX);if(t<=40)return;const e=t/this.touchDeltaX;this.touchDeltaX=0,e&&this._slide(e>0?K:z)}_addEventListeners(){this._config.keyboard&&N.on(this._element,"keydown.bs.carousel",t=>this._keydown(t)),"hover"===this._config.pause&&(N.on(this._element,"mouseenter.bs.carousel",t=>this.pause(t)),N.on(this._element,"mouseleave.bs.carousel",t=>this.cycle(t))),this._config.touch&&this._touchSupported&&this._addTouchEventListeners()}_addTouchEventListeners(){const t=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType?this._pointerEvent||(this.touchStartX=t.touches[0].clientX):this.touchStartX=t.clientX},e=t=>{this.touchDeltaX=t.touches&&t.touches.length>1?0:t.touches[0].clientX-this.touchStartX},i=t=>{!this._pointerEvent||"pen"!==t.pointerType&&"touch"!==t.pointerType||(this.touchDeltaX=t.clientX-this.touchStartX),this._handleSwipe(),"hover"===this._config.pause&&(this.pause(),this.touchTimeout&&clearTimeout(this.touchTimeout),this.touchTimeout=setTimeout(t=>this.cycle(t),500+this._config.interval))};H.find(".carousel-item img",this._element).forEach(t=>{N.on(t,"dragstart.bs.carousel",t=>t.preventDefault())}),this._pointerEvent?(N.on(this._element,"pointerdown.bs.carousel",e=>t(e)),N.on(this._element,"pointerup.bs.carousel",t=>i(t)),this._element.classList.add("pointer-event")):(N.on(this._element,"touchstart.bs.carousel",e=>t(e)),N.on(this._element,"touchmove.bs.carousel",t=>e(t)),N.on(this._element,"touchend.bs.carousel",t=>i(t)))}_keydown(t){/input|textarea/i.test(t.target.tagName)||("ArrowLeft"===t.key?(t.preventDefault(),this._slide(z)):"ArrowRight"===t.key&&(t.preventDefault(),this._slide(K)))}_getItemIndex(t){return this._items=t&&t.parentNode?H.find(".carousel-item",t.parentNode):[],this._items.indexOf(t)}_getItemByOrder(t,e){const i=t===$,s=t===F,n=this._getItemIndex(e),o=this._items.length-1;if((s&&0===n||i&&n===o)&&!this._config.wrap)return e;const r=(n+(s?-1:1))%this._items.length;return-1===r?this._items[this._items.length-1]:this._items[r]}_triggerSlideEvent(t,e){const i=this._getItemIndex(t),s=this._getItemIndex(H.findOne(".active.carousel-item",this._element));return N.trigger(this._element,"slide.bs.carousel",{relatedTarget:t,direction:e,from:s,to:i})}_setActiveIndicatorElement(t){if(this._indicatorsElement){const e=H.findOne(".active",this._indicatorsElement);e.classList.remove("active"),e.removeAttribute("aria-current");const i=H.find("[data-bs-target]",this._indicatorsElement);for(let e=0;e{r.classList.remove(h,f),r.classList.add("active"),s.classList.remove("active",f,h),this._isSliding=!1,setTimeout(()=>{N.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:p,from:o,to:l})},0)}),a(s,t)}else s.classList.remove("active"),r.classList.add("active"),this._isSliding=!1,N.trigger(this._element,"slid.bs.carousel",{relatedTarget:r,direction:p,from:o,to:l});c&&this.cycle()}}_directionToOrder(t){return[K,z].includes(t)?g()?t===K?F:$:t===K?$:F:t}_orderToDirection(t){return[$,F].includes(t)?g()?t===$?z:K:t===$?K:z:t}static carouselInterface(t,e){let i=b.get(t,"bs.carousel"),s={...W,...B.getDataAttributes(t)};"object"==typeof e&&(s={...s,...e});const n="string"==typeof e?e:s.slide;if(i||(i=new Y(t,s)),"number"==typeof e)i.to(e);else if("string"==typeof n){if(void 0===i[n])throw new TypeError(`No method named "${n}"`);i[n]()}else s.interval&&s.ride&&(i.pause(),i.cycle())}static jQueryInterface(t){return this.each((function(){Y.carouselInterface(this,t)}))}static dataApiClickHandler(t){const e=s(this);if(!e||!e.classList.contains("carousel"))return;const i={...B.getDataAttributes(e),...B.getDataAttributes(this)},n=this.getAttribute("data-bs-slide-to");n&&(i.interval=!1),Y.carouselInterface(e,i),n&&b.get(e,"bs.carousel").to(n),t.preventDefault()}}N.on(document,"click.bs.carousel.data-api","[data-bs-slide], [data-bs-slide-to]",Y.dataApiClickHandler),N.on(window,"load.bs.carousel.data-api",()=>{const t=H.find('[data-bs-ride="carousel"]');for(let e=0,i=t.length;et===this._element);null!==n&&o.length&&(this._selector=n,this._triggerArray.push(e))}this._parent=this._config.parent?this._getParent():null,this._config.parent||this._addAriaAndCollapsedClass(this._element,this._triggerArray),this._config.toggle&&this.toggle()}static get Default(){return q}static get DATA_KEY(){return"bs.collapse"}toggle(){this._element.classList.contains("show")?this.hide():this.show()}show(){if(this._isTransitioning||this._element.classList.contains("show"))return;let t,e;this._parent&&(t=H.find(".show, .collapsing",this._parent).filter(t=>"string"==typeof this._config.parent?t.getAttribute("data-bs-parent")===this._config.parent:t.classList.contains("collapse")),0===t.length&&(t=null));const i=H.findOne(this._selector);if(t){const s=t.find(t=>i!==t);if(e=s?b.get(s,"bs.collapse"):null,e&&e._isTransitioning)return}if(N.trigger(this._element,"show.bs.collapse").defaultPrevented)return;t&&t.forEach(t=>{i!==t&&X.collapseInterface(t,"hide"),e||b.set(t,"bs.collapse",null)});const s=this._getDimension();this._element.classList.remove("collapse"),this._element.classList.add("collapsing"),this._element.style[s]=0,this._triggerArray.length&&this._triggerArray.forEach(t=>{t.classList.remove("collapsed"),t.setAttribute("aria-expanded",!0)}),this.setTransitioning(!0);const o="scroll"+(s[0].toUpperCase()+s.slice(1)),r=n(this._element);N.one(this._element,"transitionend",()=>{this._element.classList.remove("collapsing"),this._element.classList.add("collapse","show"),this._element.style[s]="",this.setTransitioning(!1),N.trigger(this._element,"shown.bs.collapse")}),a(this._element,r),this._element.style[s]=this._element[o]+"px"}hide(){if(this._isTransitioning||!this._element.classList.contains("show"))return;if(N.trigger(this._element,"hide.bs.collapse").defaultPrevented)return;const t=this._getDimension();this._element.style[t]=this._element.getBoundingClientRect()[t]+"px",u(this._element),this._element.classList.add("collapsing"),this._element.classList.remove("collapse","show");const e=this._triggerArray.length;if(e>0)for(let t=0;t{this.setTransitioning(!1),this._element.classList.remove("collapsing"),this._element.classList.add("collapse"),N.trigger(this._element,"hidden.bs.collapse")}),a(this._element,i)}setTransitioning(t){this._isTransitioning=t}dispose(){super.dispose(),this._config=null,this._parent=null,this._triggerArray=null,this._isTransitioning=null}_getConfig(t){return(t={...q,...t}).toggle=Boolean(t.toggle),l("collapse",t,V),t}_getDimension(){return this._element.classList.contains("width")?"width":"height"}_getParent(){let{parent:t}=this._config;r(t)?void 0===t.jquery&&void 0===t[0]||(t=t[0]):t=H.findOne(t);const e=`[data-bs-toggle="collapse"][data-bs-parent="${t}"]`;return H.find(e,t).forEach(t=>{const e=s(t);this._addAriaAndCollapsedClass(e,[t])}),t}_addAriaAndCollapsedClass(t,e){if(!t||!e.length)return;const i=t.classList.contains("show");e.forEach(t=>{i?t.classList.remove("collapsed"):t.classList.add("collapsed"),t.setAttribute("aria-expanded",i)})}static collapseInterface(t,e){let i=b.get(t,"bs.collapse");const s={...q,...B.getDataAttributes(t),..."object"==typeof e&&e?e:{}};if(!i&&s.toggle&&"string"==typeof e&&/show|hide/.test(e)&&(s.toggle=!1),i||(i=new X(t,s)),"string"==typeof e){if(void 0===i[e])throw new TypeError(`No method named "${e}"`);i[e]()}}static jQueryInterface(t){return this.each((function(){X.collapseInterface(this,t)}))}}N.on(document,"click.bs.collapse.data-api",'[data-bs-toggle="collapse"]',(function(t){("A"===t.target.tagName||t.delegateTarget&&"A"===t.delegateTarget.tagName)&&t.preventDefault();const e=B.getDataAttributes(this),s=i(this);H.find(s).forEach(t=>{const i=b.get(t,"bs.collapse");let s;i?(null===i._parent&&"string"==typeof e.parent&&(i._config.parent=e.parent,i._parent=i._getParent()),s="toggle"):s=e,X.collapseInterface(t,s)})})),m("collapse",X);var Q="top",G="bottom",Z="right",J="left",tt=[Q,G,Z,J],et=tt.reduce((function(t,e){return t.concat([e+"-start",e+"-end"])}),[]),it=[].concat(tt,["auto"]).reduce((function(t,e){return t.concat([e,e+"-start",e+"-end"])}),[]),st=["beforeRead","read","afterRead","beforeMain","main","afterMain","beforeWrite","write","afterWrite"];function nt(t){return t?(t.nodeName||"").toLowerCase():null}function ot(t){if(null==t)return window;if("[object Window]"!==t.toString()){var e=t.ownerDocument;return e&&e.defaultView||window}return t}function rt(t){return t instanceof ot(t).Element||t instanceof Element}function at(t){return t instanceof ot(t).HTMLElement||t instanceof HTMLElement}function lt(t){return"undefined"!=typeof ShadowRoot&&(t instanceof ot(t).ShadowRoot||t instanceof ShadowRoot)}var ct={name:"applyStyles",enabled:!0,phase:"write",fn:function(t){var e=t.state;Object.keys(e.elements).forEach((function(t){var i=e.styles[t]||{},s=e.attributes[t]||{},n=e.elements[t];at(n)&&nt(n)&&(Object.assign(n.style,i),Object.keys(s).forEach((function(t){var e=s[t];!1===e?n.removeAttribute(t):n.setAttribute(t,!0===e?"":e)})))}))},effect:function(t){var e=t.state,i={popper:{position:e.options.strategy,left:"0",top:"0",margin:"0"},arrow:{position:"absolute"},reference:{}};return Object.assign(e.elements.popper.style,i.popper),e.styles=i,e.elements.arrow&&Object.assign(e.elements.arrow.style,i.arrow),function(){Object.keys(e.elements).forEach((function(t){var s=e.elements[t],n=e.attributes[t]||{},o=Object.keys(e.styles.hasOwnProperty(t)?e.styles[t]:i[t]).reduce((function(t,e){return t[e]="",t}),{});at(s)&&nt(s)&&(Object.assign(s.style,o),Object.keys(n).forEach((function(t){s.removeAttribute(t)})))}))}},requires:["computeStyles"]};function dt(t){return t.split("-")[0]}function ht(t){var e=t.getBoundingClientRect();return{width:e.width,height:e.height,top:e.top,right:e.right,bottom:e.bottom,left:e.left,x:e.left,y:e.top}}function ft(t){var e=ht(t),i=t.offsetWidth,s=t.offsetHeight;return Math.abs(e.width-i)<=1&&(i=e.width),Math.abs(e.height-s)<=1&&(s=e.height),{x:t.offsetLeft,y:t.offsetTop,width:i,height:s}}function ut(t,e){var i=e.getRootNode&&e.getRootNode();if(t.contains(e))return!0;if(i&<(i)){var s=e;do{if(s&&t.isSameNode(s))return!0;s=s.parentNode||s.host}while(s)}return!1}function pt(t){return ot(t).getComputedStyle(t)}function gt(t){return["table","td","th"].indexOf(nt(t))>=0}function mt(t){return((rt(t)?t.ownerDocument:t.document)||window.document).documentElement}function _t(t){return"html"===nt(t)?t:t.assignedSlot||t.parentNode||(lt(t)?t.host:null)||mt(t)}function bt(t){return at(t)&&"fixed"!==pt(t).position?t.offsetParent:null}function vt(t){for(var e=ot(t),i=bt(t);i&>(i)&&"static"===pt(i).position;)i=bt(i);return i&&("html"===nt(i)||"body"===nt(i)&&"static"===pt(i).position)?e:i||function(t){for(var e=-1!==navigator.userAgent.toLowerCase().indexOf("firefox"),i=_t(t);at(i)&&["html","body"].indexOf(nt(i))<0;){var s=pt(i);if("none"!==s.transform||"none"!==s.perspective||"paint"===s.contain||-1!==["transform","perspective"].indexOf(s.willChange)||e&&"filter"===s.willChange||e&&s.filter&&"none"!==s.filter)return i;i=i.parentNode}return null}(t)||e}function yt(t){return["top","bottom"].indexOf(t)>=0?"x":"y"}var wt=Math.max,Et=Math.min,Tt=Math.round;function At(t,e,i){return wt(t,Et(e,i))}function Lt(t){return Object.assign({},{top:0,right:0,bottom:0,left:0},t)}function Ot(t,e){return e.reduce((function(e,i){return e[i]=t,e}),{})}var kt={name:"arrow",enabled:!0,phase:"main",fn:function(t){var e,i=t.state,s=t.name,n=t.options,o=i.elements.arrow,r=i.modifiersData.popperOffsets,a=dt(i.placement),l=yt(a),c=[J,Z].indexOf(a)>=0?"height":"width";if(o&&r){var d=function(t,e){return Lt("number"!=typeof(t="function"==typeof t?t(Object.assign({},e.rects,{placement:e.placement})):t)?t:Ot(t,tt))}(n.padding,i),h=ft(o),f="y"===l?Q:J,u="y"===l?G:Z,p=i.rects.reference[c]+i.rects.reference[l]-r[l]-i.rects.popper[c],g=r[l]-i.rects.reference[l],m=vt(o),_=m?"y"===l?m.clientHeight||0:m.clientWidth||0:0,b=p/2-g/2,v=d[f],y=_-h[c]-d[u],w=_/2-h[c]/2+b,E=At(v,w,y),T=l;i.modifiersData[s]=((e={})[T]=E,e.centerOffset=E-w,e)}},effect:function(t){var e=t.state,i=t.options.element,s=void 0===i?"[data-popper-arrow]":i;null!=s&&("string"!=typeof s||(s=e.elements.popper.querySelector(s)))&&ut(e.elements.popper,s)&&(e.elements.arrow=s)},requires:["popperOffsets"],requiresIfExists:["preventOverflow"]},Dt={top:"auto",right:"auto",bottom:"auto",left:"auto"};function xt(t){var e,i=t.popper,s=t.popperRect,n=t.placement,o=t.offsets,r=t.position,a=t.gpuAcceleration,l=t.adaptive,c=t.roundOffsets,d=!0===c?function(t){var e=t.x,i=t.y,s=window.devicePixelRatio||1;return{x:Tt(Tt(e*s)/s)||0,y:Tt(Tt(i*s)/s)||0}}(o):"function"==typeof c?c(o):o,h=d.x,f=void 0===h?0:h,u=d.y,p=void 0===u?0:u,g=o.hasOwnProperty("x"),m=o.hasOwnProperty("y"),_=J,b=Q,v=window;if(l){var y=vt(i),w="clientHeight",E="clientWidth";y===ot(i)&&"static"!==pt(y=mt(i)).position&&(w="scrollHeight",E="scrollWidth"),y=y,n===Q&&(b=G,p-=y[w]-s.height,p*=a?1:-1),n===J&&(_=Z,f-=y[E]-s.width,f*=a?1:-1)}var T,A=Object.assign({position:r},l&&Dt);return a?Object.assign({},A,((T={})[b]=m?"0":"",T[_]=g?"0":"",T.transform=(v.devicePixelRatio||1)<2?"translate("+f+"px, "+p+"px)":"translate3d("+f+"px, "+p+"px, 0)",T)):Object.assign({},A,((e={})[b]=m?p+"px":"",e[_]=g?f+"px":"",e.transform="",e))}var Ct={name:"computeStyles",enabled:!0,phase:"beforeWrite",fn:function(t){var e=t.state,i=t.options,s=i.gpuAcceleration,n=void 0===s||s,o=i.adaptive,r=void 0===o||o,a=i.roundOffsets,l=void 0===a||a,c={placement:dt(e.placement),popper:e.elements.popper,popperRect:e.rects.popper,gpuAcceleration:n};null!=e.modifiersData.popperOffsets&&(e.styles.popper=Object.assign({},e.styles.popper,xt(Object.assign({},c,{offsets:e.modifiersData.popperOffsets,position:e.options.strategy,adaptive:r,roundOffsets:l})))),null!=e.modifiersData.arrow&&(e.styles.arrow=Object.assign({},e.styles.arrow,xt(Object.assign({},c,{offsets:e.modifiersData.arrow,position:"absolute",adaptive:!1,roundOffsets:l})))),e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-placement":e.placement})},data:{}},St={passive:!0},Nt={name:"eventListeners",enabled:!0,phase:"write",fn:function(){},effect:function(t){var e=t.state,i=t.instance,s=t.options,n=s.scroll,o=void 0===n||n,r=s.resize,a=void 0===r||r,l=ot(e.elements.popper),c=[].concat(e.scrollParents.reference,e.scrollParents.popper);return o&&c.forEach((function(t){t.addEventListener("scroll",i.update,St)})),a&&l.addEventListener("resize",i.update,St),function(){o&&c.forEach((function(t){t.removeEventListener("scroll",i.update,St)})),a&&l.removeEventListener("resize",i.update,St)}},data:{}},jt={left:"right",right:"left",bottom:"top",top:"bottom"};function Pt(t){return t.replace(/left|right|bottom|top/g,(function(t){return jt[t]}))}var It={start:"end",end:"start"};function Mt(t){return t.replace(/start|end/g,(function(t){return It[t]}))}function Rt(t){var e=ot(t);return{scrollLeft:e.pageXOffset,scrollTop:e.pageYOffset}}function Bt(t){return ht(mt(t)).left+Rt(t).scrollLeft}function Ht(t){var e=pt(t),i=e.overflow,s=e.overflowX,n=e.overflowY;return/auto|scroll|overlay|hidden/.test(i+n+s)}function Wt(t,e){var i;void 0===e&&(e=[]);var s=function t(e){return["html","body","#document"].indexOf(nt(e))>=0?e.ownerDocument.body:at(e)&&Ht(e)?e:t(_t(e))}(t),n=s===(null==(i=t.ownerDocument)?void 0:i.body),o=ot(s),r=n?[o].concat(o.visualViewport||[],Ht(s)?s:[]):s,a=e.concat(r);return n?a:a.concat(Wt(_t(r)))}function Ut(t){return Object.assign({},t,{left:t.x,top:t.y,right:t.x+t.width,bottom:t.y+t.height})}function $t(t,e){return"viewport"===e?Ut(function(t){var e=ot(t),i=mt(t),s=e.visualViewport,n=i.clientWidth,o=i.clientHeight,r=0,a=0;return s&&(n=s.width,o=s.height,/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(r=s.offsetLeft,a=s.offsetTop)),{width:n,height:o,x:r+Bt(t),y:a}}(t)):at(e)?function(t){var e=ht(t);return e.top=e.top+t.clientTop,e.left=e.left+t.clientLeft,e.bottom=e.top+t.clientHeight,e.right=e.left+t.clientWidth,e.width=t.clientWidth,e.height=t.clientHeight,e.x=e.left,e.y=e.top,e}(e):Ut(function(t){var e,i=mt(t),s=Rt(t),n=null==(e=t.ownerDocument)?void 0:e.body,o=wt(i.scrollWidth,i.clientWidth,n?n.scrollWidth:0,n?n.clientWidth:0),r=wt(i.scrollHeight,i.clientHeight,n?n.scrollHeight:0,n?n.clientHeight:0),a=-s.scrollLeft+Bt(t),l=-s.scrollTop;return"rtl"===pt(n||i).direction&&(a+=wt(i.clientWidth,n?n.clientWidth:0)-o),{width:o,height:r,x:a,y:l}}(mt(t)))}function Ft(t){return t.split("-")[1]}function zt(t){var e,i=t.reference,s=t.element,n=t.placement,o=n?dt(n):null,r=n?Ft(n):null,a=i.x+i.width/2-s.width/2,l=i.y+i.height/2-s.height/2;switch(o){case Q:e={x:a,y:i.y-s.height};break;case G:e={x:a,y:i.y+i.height};break;case Z:e={x:i.x+i.width,y:l};break;case J:e={x:i.x-s.width,y:l};break;default:e={x:i.x,y:i.y}}var c=o?yt(o):null;if(null!=c){var d="y"===c?"height":"width";switch(r){case"start":e[c]=e[c]-(i[d]/2-s[d]/2);break;case"end":e[c]=e[c]+(i[d]/2-s[d]/2)}}return e}function Kt(t,e){void 0===e&&(e={});var i=e,s=i.placement,n=void 0===s?t.placement:s,o=i.boundary,r=void 0===o?"clippingParents":o,a=i.rootBoundary,l=void 0===a?"viewport":a,c=i.elementContext,d=void 0===c?"popper":c,h=i.altBoundary,f=void 0!==h&&h,u=i.padding,p=void 0===u?0:u,g=Lt("number"!=typeof p?p:Ot(p,tt)),m="popper"===d?"reference":"popper",_=t.elements.reference,b=t.rects.popper,v=t.elements[f?m:d],y=function(t,e,i){var s="clippingParents"===e?function(t){var e=Wt(_t(t)),i=["absolute","fixed"].indexOf(pt(t).position)>=0&&at(t)?vt(t):t;return rt(i)?e.filter((function(t){return rt(t)&&ut(t,i)&&"body"!==nt(t)})):[]}(t):[].concat(e),n=[].concat(s,[i]),o=n[0],r=n.reduce((function(e,i){var s=$t(t,i);return e.top=wt(s.top,e.top),e.right=Et(s.right,e.right),e.bottom=Et(s.bottom,e.bottom),e.left=wt(s.left,e.left),e}),$t(t,o));return r.width=r.right-r.left,r.height=r.bottom-r.top,r.x=r.left,r.y=r.top,r}(rt(v)?v:v.contextElement||mt(t.elements.popper),r,l),w=ht(_),E=zt({reference:w,element:b,strategy:"absolute",placement:n}),T=Ut(Object.assign({},b,E)),A="popper"===d?T:w,L={top:y.top-A.top+g.top,bottom:A.bottom-y.bottom+g.bottom,left:y.left-A.left+g.left,right:A.right-y.right+g.right},O=t.modifiersData.offset;if("popper"===d&&O){var k=O[n];Object.keys(L).forEach((function(t){var e=[Z,G].indexOf(t)>=0?1:-1,i=[Q,G].indexOf(t)>=0?"y":"x";L[t]+=k[i]*e}))}return L}function Yt(t,e){void 0===e&&(e={});var i=e,s=i.placement,n=i.boundary,o=i.rootBoundary,r=i.padding,a=i.flipVariations,l=i.allowedAutoPlacements,c=void 0===l?it:l,d=Ft(s),h=d?a?et:et.filter((function(t){return Ft(t)===d})):tt,f=h.filter((function(t){return c.indexOf(t)>=0}));0===f.length&&(f=h);var u=f.reduce((function(e,i){return e[i]=Kt(t,{placement:i,boundary:n,rootBoundary:o,padding:r})[dt(i)],e}),{});return Object.keys(u).sort((function(t,e){return u[t]-u[e]}))}var qt={name:"flip",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,s=t.name;if(!e.modifiersData[s]._skip){for(var n=i.mainAxis,o=void 0===n||n,r=i.altAxis,a=void 0===r||r,l=i.fallbackPlacements,c=i.padding,d=i.boundary,h=i.rootBoundary,f=i.altBoundary,u=i.flipVariations,p=void 0===u||u,g=i.allowedAutoPlacements,m=e.options.placement,_=dt(m),b=l||(_!==m&&p?function(t){if("auto"===dt(t))return[];var e=Pt(t);return[Mt(t),e,Mt(e)]}(m):[Pt(m)]),v=[m].concat(b).reduce((function(t,i){return t.concat("auto"===dt(i)?Yt(e,{placement:i,boundary:d,rootBoundary:h,padding:c,flipVariations:p,allowedAutoPlacements:g}):i)}),[]),y=e.rects.reference,w=e.rects.popper,E=new Map,T=!0,A=v[0],L=0;L=0,C=x?"width":"height",S=Kt(e,{placement:O,boundary:d,rootBoundary:h,altBoundary:f,padding:c}),N=x?D?Z:J:D?G:Q;y[C]>w[C]&&(N=Pt(N));var j=Pt(N),P=[];if(o&&P.push(S[k]<=0),a&&P.push(S[N]<=0,S[j]<=0),P.every((function(t){return t}))){A=O,T=!1;break}E.set(O,P)}if(T)for(var I=function(t){var e=v.find((function(e){var i=E.get(e);if(i)return i.slice(0,t).every((function(t){return t}))}));if(e)return A=e,"break"},M=p?3:1;M>0&&"break"!==I(M);M--);e.placement!==A&&(e.modifiersData[s]._skip=!0,e.placement=A,e.reset=!0)}},requiresIfExists:["offset"],data:{_skip:!1}};function Vt(t,e,i){return void 0===i&&(i={x:0,y:0}),{top:t.top-e.height-i.y,right:t.right-e.width+i.x,bottom:t.bottom-e.height+i.y,left:t.left-e.width-i.x}}function Xt(t){return[Q,Z,G,J].some((function(e){return t[e]>=0}))}var Qt={name:"hide",enabled:!0,phase:"main",requiresIfExists:["preventOverflow"],fn:function(t){var e=t.state,i=t.name,s=e.rects.reference,n=e.rects.popper,o=e.modifiersData.preventOverflow,r=Kt(e,{elementContext:"reference"}),a=Kt(e,{altBoundary:!0}),l=Vt(r,s),c=Vt(a,n,o),d=Xt(l),h=Xt(c);e.modifiersData[i]={referenceClippingOffsets:l,popperEscapeOffsets:c,isReferenceHidden:d,hasPopperEscaped:h},e.attributes.popper=Object.assign({},e.attributes.popper,{"data-popper-reference-hidden":d,"data-popper-escaped":h})}},Gt={name:"offset",enabled:!0,phase:"main",requires:["popperOffsets"],fn:function(t){var e=t.state,i=t.options,s=t.name,n=i.offset,o=void 0===n?[0,0]:n,r=it.reduce((function(t,i){return t[i]=function(t,e,i){var s=dt(t),n=[J,Q].indexOf(s)>=0?-1:1,o="function"==typeof i?i(Object.assign({},e,{placement:t})):i,r=o[0],a=o[1];return r=r||0,a=(a||0)*n,[J,Z].indexOf(s)>=0?{x:a,y:r}:{x:r,y:a}}(i,e.rects,o),t}),{}),a=r[e.placement],l=a.x,c=a.y;null!=e.modifiersData.popperOffsets&&(e.modifiersData.popperOffsets.x+=l,e.modifiersData.popperOffsets.y+=c),e.modifiersData[s]=r}},Zt={name:"popperOffsets",enabled:!0,phase:"read",fn:function(t){var e=t.state,i=t.name;e.modifiersData[i]=zt({reference:e.rects.reference,element:e.rects.popper,strategy:"absolute",placement:e.placement})},data:{}},Jt={name:"preventOverflow",enabled:!0,phase:"main",fn:function(t){var e=t.state,i=t.options,s=t.name,n=i.mainAxis,o=void 0===n||n,r=i.altAxis,a=void 0!==r&&r,l=i.boundary,c=i.rootBoundary,d=i.altBoundary,h=i.padding,f=i.tether,u=void 0===f||f,p=i.tetherOffset,g=void 0===p?0:p,m=Kt(e,{boundary:l,rootBoundary:c,padding:h,altBoundary:d}),_=dt(e.placement),b=Ft(e.placement),v=!b,y=yt(_),w="x"===y?"y":"x",E=e.modifiersData.popperOffsets,T=e.rects.reference,A=e.rects.popper,L="function"==typeof g?g(Object.assign({},e.rects,{placement:e.placement})):g,O={x:0,y:0};if(E){if(o||a){var k="y"===y?Q:J,D="y"===y?G:Z,x="y"===y?"height":"width",C=E[y],S=E[y]+m[k],N=E[y]-m[D],j=u?-A[x]/2:0,P="start"===b?T[x]:A[x],I="start"===b?-A[x]:-T[x],M=e.elements.arrow,R=u&&M?ft(M):{width:0,height:0},B=e.modifiersData["arrow#persistent"]?e.modifiersData["arrow#persistent"].padding:{top:0,right:0,bottom:0,left:0},H=B[k],W=B[D],U=At(0,T[x],R[x]),$=v?T[x]/2-j-U-H-L:P-U-H-L,F=v?-T[x]/2+j+U+W+L:I+U+W+L,z=e.elements.arrow&&vt(e.elements.arrow),K=z?"y"===y?z.clientTop||0:z.clientLeft||0:0,Y=e.modifiersData.offset?e.modifiersData.offset[e.placement][y]:0,q=E[y]+$-Y-K,V=E[y]+F-Y;if(o){var X=At(u?Et(S,q):S,C,u?wt(N,V):N);E[y]=X,O[y]=X-C}if(a){var tt="x"===y?Q:J,et="x"===y?G:Z,it=E[w],st=it+m[tt],nt=it-m[et],ot=At(u?Et(st,q):st,it,u?wt(nt,V):nt);E[w]=ot,O[w]=ot-it}}e.modifiersData[s]=O}},requiresIfExists:["offset"]};function te(t,e,i){void 0===i&&(i=!1);var s,n,o=mt(e),r=ht(t),a=at(e),l={scrollLeft:0,scrollTop:0},c={x:0,y:0};return(a||!a&&!i)&&(("body"!==nt(e)||Ht(o))&&(l=(s=e)!==ot(s)&&at(s)?{scrollLeft:(n=s).scrollLeft,scrollTop:n.scrollTop}:Rt(s)),at(e)?((c=ht(e)).x+=e.clientLeft,c.y+=e.clientTop):o&&(c.x=Bt(o))),{x:r.left+l.scrollLeft-c.x,y:r.top+l.scrollTop-c.y,width:r.width,height:r.height}}var ee={placement:"bottom",modifiers:[],strategy:"absolute"};function ie(){for(var t=arguments.length,e=new Array(t),i=0;i"applyStyles"===t.name&&!1===t.enabled);this._popper=re(e,this._menu,i),s&&B.setDataAttribute(this._menu,"popper","static")}"ontouchstart"in document.documentElement&&!t.closest(".navbar-nav")&&[].concat(...document.body.children).forEach(t=>N.on(t,"mouseover",null,(function(){}))),this._element.focus(),this._element.setAttribute("aria-expanded",!0),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),N.trigger(this._element,"shown.bs.dropdown",e)}}hide(){if(this._element.disabled||this._element.classList.contains("disabled")||!this._menu.classList.contains("show"))return;const t={relatedTarget:this._element};N.trigger(this._element,"hide.bs.dropdown",t).defaultPrevented||(this._popper&&this._popper.destroy(),this._menu.classList.toggle("show"),this._element.classList.toggle("show"),B.removeDataAttribute(this._menu,"popper"),N.trigger(this._element,"hidden.bs.dropdown",t))}dispose(){N.off(this._element,".bs.dropdown"),this._menu=null,this._popper&&(this._popper.destroy(),this._popper=null),super.dispose()}update(){this._inNavbar=this._detectNavbar(),this._popper&&this._popper.update()}_addEventListeners(){N.on(this._element,"click.bs.dropdown",t=>{t.preventDefault(),this.toggle()})}_getConfig(t){if(t={...this.constructor.Default,...B.getDataAttributes(this._element),...t},l("dropdown",t,this.constructor.DefaultType),"object"==typeof t.reference&&!r(t.reference)&&"function"!=typeof t.reference.getBoundingClientRect)throw new TypeError("dropdown".toUpperCase()+': Option "reference" provided type "object" without a required "getBoundingClientRect" method.');return t}_getMenuElement(){return H.next(this._element,".dropdown-menu")[0]}_getPlacement(){const t=this._element.parentNode;if(t.classList.contains("dropend"))return ue;if(t.classList.contains("dropstart"))return pe;const e="end"===getComputedStyle(this._menu).getPropertyValue("--bs-position").trim();return t.classList.contains("dropup")?e?de:ce:e?fe:he}_detectNavbar(){return null!==this._element.closest(".navbar")}_getOffset(){const{offset:t}=this._config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(){const t={placement:this._getPlacement(),modifiers:[{name:"preventOverflow",options:{boundary:this._config.boundary}},{name:"offset",options:{offset:this._getOffset()}}]};return"static"===this._config.display&&(t.modifiers=[{name:"applyStyles",enabled:!1}]),{...t,..."function"==typeof this._config.popperConfig?this._config.popperConfig(t):this._config.popperConfig}}static dropdownInterface(t,e){let i=b.get(t,"bs.dropdown");if(i||(i=new _e(t,"object"==typeof e?e:null)),"string"==typeof e){if(void 0===i[e])throw new TypeError(`No method named "${e}"`);i[e]()}}static jQueryInterface(t){return this.each((function(){_e.dropdownInterface(this,t)}))}static clearMenus(t){if(t){if(2===t.button||"keyup"===t.type&&"Tab"!==t.key)return;if(/input|select|textarea|form/i.test(t.target.tagName))return}const e=H.find('[data-bs-toggle="dropdown"]');for(let i=0,s=e.length;it.composedPath().includes(e)))continue;if("keyup"===t.type&&"Tab"===t.key&&o.contains(t.target))continue}N.trigger(e[i],"hide.bs.dropdown",n).defaultPrevented||("ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>N.off(t,"mouseover",null,(function(){}))),e[i].setAttribute("aria-expanded","false"),s._popper&&s._popper.destroy(),o.classList.remove("show"),e[i].classList.remove("show"),B.removeDataAttribute(o,"popper"),N.trigger(e[i],"hidden.bs.dropdown",n))}}}static getParentFromElement(t){return s(t)||t.parentNode}static dataApiKeydownHandler(t){if(/input|textarea/i.test(t.target.tagName)?"Space"===t.key||"Escape"!==t.key&&("ArrowDown"!==t.key&&"ArrowUp"!==t.key||t.target.closest(".dropdown-menu")):!le.test(t.key))return;if(t.preventDefault(),t.stopPropagation(),this.disabled||this.classList.contains("disabled"))return;const e=_e.getParentFromElement(this),i=this.classList.contains("show");if("Escape"===t.key)return(this.matches('[data-bs-toggle="dropdown"]')?this:H.prev(this,'[data-bs-toggle="dropdown"]')[0]).focus(),void _e.clearMenus();if(!i&&("ArrowUp"===t.key||"ArrowDown"===t.key))return void(this.matches('[data-bs-toggle="dropdown"]')?this:H.prev(this,'[data-bs-toggle="dropdown"]')[0]).click();if(!i||"Space"===t.key)return void _e.clearMenus();const s=H.find(".dropdown-menu .dropdown-item:not(.disabled):not(:disabled)",e).filter(c);if(!s.length)return;let n=s.indexOf(t.target);"ArrowUp"===t.key&&n>0&&n--,"ArrowDown"===t.key&&nthis.hide(t)),N.on(this._dialog,"mousedown.dismiss.bs.modal",()=>{N.one(this._element,"mouseup.dismiss.bs.modal",t=>{t.target===this._element&&(this._ignoreBackdropClick=!0)})}),this._showBackdrop(()=>this._showElement(t)))}hide(t){if(t&&t.preventDefault(),!this._isShown||this._isTransitioning)return;if(N.trigger(this._element,"hide.bs.modal").defaultPrevented)return;this._isShown=!1;const e=this._isAnimated();if(e&&(this._isTransitioning=!0),this._setEscapeEvent(),this._setResizeEvent(),N.off(document,"focusin.bs.modal"),this._element.classList.remove("show"),N.off(this._element,"click.dismiss.bs.modal"),N.off(this._dialog,"mousedown.dismiss.bs.modal"),e){const t=n(this._element);N.one(this._element,"transitionend",t=>this._hideModal(t)),a(this._element,t)}else this._hideModal()}dispose(){[window,this._element,this._dialog].forEach(t=>N.off(t,".bs.modal")),super.dispose(),N.off(document,"focusin.bs.modal"),this._config=null,this._dialog=null,this._backdrop=null,this._isShown=null,this._isBodyOverflowing=null,this._ignoreBackdropClick=null,this._isTransitioning=null,this._scrollbarWidth=null}handleUpdate(){this._adjustDialog()}_getConfig(t){return t={...be,...t},l("modal",t,ve),t}_showElement(t){const e=this._isAnimated(),i=H.findOne(".modal-body",this._dialog);this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE||document.body.appendChild(this._element),this._element.style.display="block",this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.scrollTop=0,i&&(i.scrollTop=0),e&&u(this._element),this._element.classList.add("show"),this._config.focus&&this._enforceFocus();const s=()=>{this._config.focus&&this._element.focus(),this._isTransitioning=!1,N.trigger(this._element,"shown.bs.modal",{relatedTarget:t})};if(e){const t=n(this._dialog);N.one(this._dialog,"transitionend",s),a(this._dialog,t)}else s()}_enforceFocus(){N.off(document,"focusin.bs.modal"),N.on(document,"focusin.bs.modal",t=>{document===t.target||this._element===t.target||this._element.contains(t.target)||this._element.focus()})}_setEscapeEvent(){this._isShown?N.on(this._element,"keydown.dismiss.bs.modal",t=>{this._config.keyboard&&"Escape"===t.key?(t.preventDefault(),this.hide()):this._config.keyboard||"Escape"!==t.key||this._triggerBackdropTransition()}):N.off(this._element,"keydown.dismiss.bs.modal")}_setResizeEvent(){this._isShown?N.on(window,"resize.bs.modal",()=>this._adjustDialog()):N.off(window,"resize.bs.modal")}_hideModal(){this._element.style.display="none",this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._isTransitioning=!1,this._showBackdrop(()=>{document.body.classList.remove("modal-open"),this._resetAdjustments(),this._resetScrollbar(),N.trigger(this._element,"hidden.bs.modal")})}_removeBackdrop(){this._backdrop.parentNode.removeChild(this._backdrop),this._backdrop=null}_showBackdrop(t){const e=this._isAnimated();if(this._isShown&&this._config.backdrop){if(this._backdrop=document.createElement("div"),this._backdrop.className="modal-backdrop",e&&this._backdrop.classList.add("fade"),document.body.appendChild(this._backdrop),N.on(this._element,"click.dismiss.bs.modal",t=>{this._ignoreBackdropClick?this._ignoreBackdropClick=!1:t.target===t.currentTarget&&("static"===this._config.backdrop?this._triggerBackdropTransition():this.hide())}),e&&u(this._backdrop),this._backdrop.classList.add("show"),!e)return void t();const i=n(this._backdrop);N.one(this._backdrop,"transitionend",t),a(this._backdrop,i)}else if(!this._isShown&&this._backdrop){this._backdrop.classList.remove("show");const i=()=>{this._removeBackdrop(),t()};if(e){const t=n(this._backdrop);N.one(this._backdrop,"transitionend",i),a(this._backdrop,t)}else i()}else t()}_isAnimated(){return this._element.classList.contains("fade")}_triggerBackdropTransition(){if(N.trigger(this._element,"hidePrevented.bs.modal").defaultPrevented)return;const t=this._element.scrollHeight>document.documentElement.clientHeight;t||(this._element.style.overflowY="hidden"),this._element.classList.add("modal-static");const e=n(this._dialog);N.off(this._element,"transitionend"),N.one(this._element,"transitionend",()=>{this._element.classList.remove("modal-static"),t||(N.one(this._element,"transitionend",()=>{this._element.style.overflowY=""}),a(this._element,e))}),a(this._element,e),this._element.focus()}_adjustDialog(){const t=this._element.scrollHeight>document.documentElement.clientHeight;(!this._isBodyOverflowing&&t&&!g()||this._isBodyOverflowing&&!t&&g())&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),(this._isBodyOverflowing&&!t&&!g()||!this._isBodyOverflowing&&t&&g())&&(this._element.style.paddingRight=this._scrollbarWidth+"px")}_resetAdjustments(){this._element.style.paddingLeft="",this._element.style.paddingRight=""}_checkScrollbar(){const t=document.body.getBoundingClientRect();this._isBodyOverflowing=Math.round(t.left+t.right)t+this._scrollbarWidth),this._setElementAttributes(".sticky-top","marginRight",t=>t-this._scrollbarWidth),this._setElementAttributes("body","paddingRight",t=>t+this._scrollbarWidth)),document.body.classList.add("modal-open")}_setElementAttributes(t,e,i){H.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+this._scrollbarWidth)return;const s=t.style[e],n=window.getComputedStyle(t)[e];B.setDataAttribute(t,e,s),t.style[e]=i(Number.parseFloat(n))+"px"})}_resetScrollbar(){this._resetElementAttributes(".fixed-top, .fixed-bottom, .is-fixed, .sticky-top","paddingRight"),this._resetElementAttributes(".sticky-top","marginRight"),this._resetElementAttributes("body","paddingRight")}_resetElementAttributes(t,e){H.find(t).forEach(t=>{const i=B.getDataAttribute(t,e);void 0===i&&t===document.body?t.style[e]="":(B.removeDataAttribute(t,e),t.style[e]=i)})}_getScrollbarWidth(){const t=document.createElement("div");t.className="modal-scrollbar-measure",document.body.appendChild(t);const e=t.getBoundingClientRect().width-t.clientWidth;return document.body.removeChild(t),e}static jQueryInterface(t,e){return this.each((function(){let i=b.get(this,"bs.modal");const s={...be,...B.getDataAttributes(this),..."object"==typeof t&&t?t:{}};if(i||(i=new ye(this,s)),"string"==typeof t){if(void 0===i[t])throw new TypeError(`No method named "${t}"`);i[t](e)}}))}}N.on(document,"click.bs.modal.data-api",'[data-bs-toggle="modal"]',(function(t){const e=s(this);"A"!==this.tagName&&"AREA"!==this.tagName||t.preventDefault(),N.one(e,"show.bs.modal",t=>{t.defaultPrevented||N.one(e,"hidden.bs.modal",()=>{c(this)&&this.focus()})});let i=b.get(e,"bs.modal");if(!i){const t={...B.getDataAttributes(e),...B.getDataAttributes(this)};i=new ye(e,t)}i.toggle(this)})),m("modal",ye);const we=()=>{const t=document.documentElement.clientWidth;return Math.abs(window.innerWidth-t)},Ee=(t,e,i)=>{const s=we();H.find(t).forEach(t=>{if(t!==document.body&&window.innerWidth>t.clientWidth+s)return;const n=t.style[e],o=window.getComputedStyle(t)[e];B.setDataAttribute(t,e,n),t.style[e]=i(Number.parseFloat(o))+"px"})},Te=(t,e)=>{H.find(t).forEach(t=>{const i=B.getDataAttribute(t,e);void 0===i&&t===document.body?t.style.removeProperty(e):(B.removeDataAttribute(t,e),t.style[e]=i)})},Ae={backdrop:!0,keyboard:!0,scroll:!1},Le={backdrop:"boolean",keyboard:"boolean",scroll:"boolean"};class Oe extends j{constructor(t,e){super(t),this._config=this._getConfig(e),this._isShown=!1,this._addEventListeners()}static get Default(){return Ae}static get DATA_KEY(){return"bs.offcanvas"}toggle(t){return this._isShown?this.hide():this.show(t)}show(t){this._isShown||N.trigger(this._element,"show.bs.offcanvas",{relatedTarget:t}).defaultPrevented||(this._isShown=!0,this._element.style.visibility="visible",this._config.backdrop&&document.body.classList.add("offcanvas-backdrop"),this._config.scroll||((t=we())=>{document.body.style.overflow="hidden",Ee(".fixed-top, .fixed-bottom, .is-fixed","paddingRight",e=>e+t),Ee(".sticky-top","marginRight",e=>e-t),Ee("body","paddingRight",e=>e+t)})(),this._element.classList.add("offcanvas-toggling"),this._element.removeAttribute("aria-hidden"),this._element.setAttribute("aria-modal",!0),this._element.setAttribute("role","dialog"),this._element.classList.add("show"),setTimeout(()=>{this._element.classList.remove("offcanvas-toggling"),N.trigger(this._element,"shown.bs.offcanvas",{relatedTarget:t}),this._enforceFocusOnElement(this._element)},n(this._element)))}hide(){this._isShown&&(N.trigger(this._element,"hide.bs.offcanvas").defaultPrevented||(this._element.classList.add("offcanvas-toggling"),N.off(document,"focusin.bs.offcanvas"),this._element.blur(),this._isShown=!1,this._element.classList.remove("show"),setTimeout(()=>{this._element.setAttribute("aria-hidden",!0),this._element.removeAttribute("aria-modal"),this._element.removeAttribute("role"),this._element.style.visibility="hidden",this._config.backdrop&&document.body.classList.remove("offcanvas-backdrop"),this._config.scroll||(document.body.style.overflow="auto",Te(".fixed-top, .fixed-bottom, .is-fixed","paddingRight"),Te(".sticky-top","marginRight"),Te("body","paddingRight")),N.trigger(this._element,"hidden.bs.offcanvas"),this._element.classList.remove("offcanvas-toggling")},n(this._element))))}_getConfig(t){return t={...Ae,...B.getDataAttributes(this._element),..."object"==typeof t?t:{}},l("offcanvas",t,Le),t}_enforceFocusOnElement(t){N.off(document,"focusin.bs.offcanvas"),N.on(document,"focusin.bs.offcanvas",e=>{document===e.target||t===e.target||t.contains(e.target)||t.focus()}),t.focus()}_addEventListeners(){N.on(this._element,"click.dismiss.bs.offcanvas",'[data-bs-dismiss="offcanvas"]',()=>this.hide()),N.on(document,"keydown",t=>{this._config.keyboard&&"Escape"===t.key&&this.hide()}),N.on(document,"click.bs.offcanvas.data-api",t=>{const e=H.findOne(i(t.target));this._element.contains(t.target)||e===this._element||this.hide()})}static jQueryInterface(t){return this.each((function(){const e=b.get(this,"bs.offcanvas")||new Oe(this,"object"==typeof t?t:{});if("string"==typeof t){if(void 0===e[t]||t.startsWith("_")||"constructor"===t)throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}N.on(document,"click.bs.offcanvas.data-api",'[data-bs-toggle="offcanvas"]',(function(t){const e=s(this);if(["A","AREA"].includes(this.tagName)&&t.preventDefault(),d(this))return;N.one(e,"hidden.bs.offcanvas",()=>{c(this)&&this.focus()});const i=H.findOne(".offcanvas.show, .offcanvas-toggling");i&&i!==e||(b.get(e,"bs.offcanvas")||new Oe(e)).toggle(this)})),N.on(window,"load.bs.offcanvas.data-api",()=>{H.find(".offcanvas.show").forEach(t=>(b.get(t,"bs.offcanvas")||new Oe(t)).show())}),m("offcanvas",Oe);const ke=new Set(["background","cite","href","itemtype","longdesc","poster","src","xlink:href"]),De=/^(?:(?:https?|mailto|ftp|tel|file):|[^#&/:?]*(?:[#/?]|$))/i,xe=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[\d+/a-z]+=*$/i,Ce=(t,e)=>{const i=t.nodeName.toLowerCase();if(e.includes(i))return!ke.has(i)||Boolean(De.test(t.nodeValue)||xe.test(t.nodeValue));const s=e.filter(t=>t instanceof RegExp);for(let t=0,e=s.length;t{Ce(t,a)||i.removeAttribute(t.nodeName)})}return s.body.innerHTML}const Ne=new RegExp("(^|\\s)bs-tooltip\\S+","g"),je=new Set(["sanitize","allowList","sanitizeFn"]),Pe={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(array|string|function)",container:"(string|element|boolean)",fallbackPlacements:"array",boundary:"(string|element)",customClass:"(string|function)",sanitize:"boolean",sanitizeFn:"(null|function)",allowList:"object",popperConfig:"(null|object|function)"},Ie={AUTO:"auto",TOP:"top",RIGHT:g()?"left":"right",BOTTOM:"bottom",LEFT:g()?"right":"left"},Me={animation:!0,template:'',trigger:"hover focus",title:"",delay:0,html:!1,selector:!1,placement:"top",offset:[0,0],container:!1,fallbackPlacements:["top","right","bottom","left"],boundary:"clippingParents",customClass:"",sanitize:!0,sanitizeFn:null,allowList:{"*":["class","dir","id","lang","role",/^aria-[\w-]*$/i],a:["target","href","title","rel"],area:[],b:[],br:[],col:[],code:[],div:[],em:[],hr:[],h1:[],h2:[],h3:[],h4:[],h5:[],h6:[],i:[],img:["src","srcset","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},popperConfig:null},Re={HIDE:"hide.bs.tooltip",HIDDEN:"hidden.bs.tooltip",SHOW:"show.bs.tooltip",SHOWN:"shown.bs.tooltip",INSERTED:"inserted.bs.tooltip",CLICK:"click.bs.tooltip",FOCUSIN:"focusin.bs.tooltip",FOCUSOUT:"focusout.bs.tooltip",MOUSEENTER:"mouseenter.bs.tooltip",MOUSELEAVE:"mouseleave.bs.tooltip"};class Be extends j{constructor(t,e){if(void 0===ae)throw new TypeError("Bootstrap's tooltips require Popper (https://popper.js.org)");super(t),this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.config=this._getConfig(e),this.tip=null,this._setListeners()}static get Default(){return Me}static get NAME(){return"tooltip"}static get DATA_KEY(){return"bs.tooltip"}static get Event(){return Re}static get EVENT_KEY(){return".bs.tooltip"}static get DefaultType(){return Pe}enable(){this._isEnabled=!0}disable(){this._isEnabled=!1}toggleEnabled(){this._isEnabled=!this._isEnabled}toggle(t){if(this._isEnabled)if(t){const e=this._initializeOnDelegatedTarget(t);e._activeTrigger.click=!e._activeTrigger.click,e._isWithActiveTrigger()?e._enter(null,e):e._leave(null,e)}else{if(this.getTipElement().classList.contains("show"))return void this._leave(null,this);this._enter(null,this)}}dispose(){clearTimeout(this._timeout),N.off(this._element,this.constructor.EVENT_KEY),N.off(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.tip&&this.tip.parentNode&&this.tip.parentNode.removeChild(this.tip),this._isEnabled=null,this._timeout=null,this._hoverState=null,this._activeTrigger=null,this._popper&&this._popper.destroy(),this._popper=null,this.config=null,this.tip=null,super.dispose()}show(){if("none"===this._element.style.display)throw new Error("Please use show on visible elements");if(!this.isWithContent()||!this._isEnabled)return;const e=N.trigger(this._element,this.constructor.Event.SHOW),i=h(this._element),s=null===i?this._element.ownerDocument.documentElement.contains(this._element):i.contains(this._element);if(e.defaultPrevented||!s)return;const o=this.getTipElement(),r=t(this.constructor.NAME);o.setAttribute("id",r),this._element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&o.classList.add("fade");const l="function"==typeof this.config.placement?this.config.placement.call(this,o,this._element):this.config.placement,c=this._getAttachment(l);this._addAttachmentClass(c);const d=this._getContainer();b.set(o,this.constructor.DATA_KEY,this),this._element.ownerDocument.documentElement.contains(this.tip)||(d.appendChild(o),N.trigger(this._element,this.constructor.Event.INSERTED)),this._popper?this._popper.update():this._popper=re(this._element,o,this._getPopperConfig(c)),o.classList.add("show");const f="function"==typeof this.config.customClass?this.config.customClass():this.config.customClass;f&&o.classList.add(...f.split(" ")),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>{N.on(t,"mouseover",(function(){}))});const u=()=>{const t=this._hoverState;this._hoverState=null,N.trigger(this._element,this.constructor.Event.SHOWN),"out"===t&&this._leave(null,this)};if(this.tip.classList.contains("fade")){const t=n(this.tip);N.one(this.tip,"transitionend",u),a(this.tip,t)}else u()}hide(){if(!this._popper)return;const t=this.getTipElement(),e=()=>{this._isWithActiveTrigger()||("show"!==this._hoverState&&t.parentNode&&t.parentNode.removeChild(t),this._cleanTipClass(),this._element.removeAttribute("aria-describedby"),N.trigger(this._element,this.constructor.Event.HIDDEN),this._popper&&(this._popper.destroy(),this._popper=null))};if(!N.trigger(this._element,this.constructor.Event.HIDE).defaultPrevented){if(t.classList.remove("show"),"ontouchstart"in document.documentElement&&[].concat(...document.body.children).forEach(t=>N.off(t,"mouseover",f)),this._activeTrigger.click=!1,this._activeTrigger.focus=!1,this._activeTrigger.hover=!1,this.tip.classList.contains("fade")){const i=n(t);N.one(t,"transitionend",e),a(t,i)}else e();this._hoverState=""}}update(){null!==this._popper&&this._popper.update()}isWithContent(){return Boolean(this.getTitle())}getTipElement(){if(this.tip)return this.tip;const t=document.createElement("div");return t.innerHTML=this.config.template,this.tip=t.children[0],this.tip}setContent(){const t=this.getTipElement();this.setElementContent(H.findOne(".tooltip-inner",t),this.getTitle()),t.classList.remove("fade","show")}setElementContent(t,e){if(null!==t)return"object"==typeof e&&r(e)?(e.jquery&&(e=e[0]),void(this.config.html?e.parentNode!==t&&(t.innerHTML="",t.appendChild(e)):t.textContent=e.textContent)):void(this.config.html?(this.config.sanitize&&(e=Se(e,this.config.allowList,this.config.sanitizeFn)),t.innerHTML=e):t.textContent=e)}getTitle(){let t=this._element.getAttribute("data-bs-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this._element):this.config.title),t}updateAttachment(t){return"right"===t?"end":"left"===t?"start":t}_initializeOnDelegatedTarget(t,e){const i=this.constructor.DATA_KEY;return(e=e||b.get(t.delegateTarget,i))||(e=new this.constructor(t.delegateTarget,this._getDelegateConfig()),b.set(t.delegateTarget,i,e)),e}_getOffset(){const{offset:t}=this.config;return"string"==typeof t?t.split(",").map(t=>Number.parseInt(t,10)):"function"==typeof t?e=>t(e,this._element):t}_getPopperConfig(t){const e={placement:t,modifiers:[{name:"flip",options:{altBoundary:!0,fallbackPlacements:this.config.fallbackPlacements}},{name:"offset",options:{offset:this._getOffset()}},{name:"preventOverflow",options:{boundary:this.config.boundary}},{name:"arrow",options:{element:`.${this.constructor.NAME}-arrow`}},{name:"onChange",enabled:!0,phase:"afterWrite",fn:t=>this._handlePopperPlacementChange(t)}],onFirstUpdate:t=>{t.options.placement!==t.placement&&this._handlePopperPlacementChange(t)}};return{...e,..."function"==typeof this.config.popperConfig?this.config.popperConfig(e):this.config.popperConfig}}_addAttachmentClass(t){this.getTipElement().classList.add("bs-tooltip-"+this.updateAttachment(t))}_getContainer(){return!1===this.config.container?document.body:r(this.config.container)?this.config.container:H.findOne(this.config.container)}_getAttachment(t){return Ie[t.toUpperCase()]}_setListeners(){this.config.trigger.split(" ").forEach(t=>{if("click"===t)N.on(this._element,this.constructor.Event.CLICK,this.config.selector,t=>this.toggle(t));else if("manual"!==t){const e="hover"===t?this.constructor.Event.MOUSEENTER:this.constructor.Event.FOCUSIN,i="hover"===t?this.constructor.Event.MOUSELEAVE:this.constructor.Event.FOCUSOUT;N.on(this._element,e,this.config.selector,t=>this._enter(t)),N.on(this._element,i,this.config.selector,t=>this._leave(t))}}),this._hideModalHandler=()=>{this._element&&this.hide()},N.on(this._element.closest(".modal"),"hide.bs.modal",this._hideModalHandler),this.config.selector?this.config={...this.config,trigger:"manual",selector:""}:this._fixTitle()}_fixTitle(){const t=this._element.getAttribute("title"),e=typeof this._element.getAttribute("data-bs-original-title");(t||"string"!==e)&&(this._element.setAttribute("data-bs-original-title",t||""),!t||this._element.getAttribute("aria-label")||this._element.textContent||this._element.setAttribute("aria-label",t),this._element.setAttribute("title",""))}_enter(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusin"===t.type?"focus":"hover"]=!0),e.getTipElement().classList.contains("show")||"show"===e._hoverState?e._hoverState="show":(clearTimeout(e._timeout),e._hoverState="show",e.config.delay&&e.config.delay.show?e._timeout=setTimeout(()=>{"show"===e._hoverState&&e.show()},e.config.delay.show):e.show())}_leave(t,e){e=this._initializeOnDelegatedTarget(t,e),t&&(e._activeTrigger["focusout"===t.type?"focus":"hover"]=e._element.contains(t.relatedTarget)),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState="out",e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(()=>{"out"===e._hoverState&&e.hide()},e.config.delay.hide):e.hide())}_isWithActiveTrigger(){for(const t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1}_getConfig(t){const e=B.getDataAttributes(this._element);return Object.keys(e).forEach(t=>{je.has(t)&&delete e[t]}),t&&"object"==typeof t.container&&t.container.jquery&&(t.container=t.container[0]),"number"==typeof(t={...this.constructor.Default,...e,..."object"==typeof t&&t?t:{}}).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),l("tooltip",t,this.constructor.DefaultType),t.sanitize&&(t.template=Se(t.template,t.allowList,t.sanitizeFn)),t}_getDelegateConfig(){const t={};if(this.config)for(const e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(Ne);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}_handlePopperPlacementChange(t){const{state:e}=t;e&&(this.tip=e.elements.popper,this._cleanTipClass(),this._addAttachmentClass(this._getAttachment(e.placement)))}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.tooltip");const i="object"==typeof t&&t;if((e||!/dispose|hide/.test(t))&&(e||(e=new Be(this,i)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m("tooltip",Be);const He=new RegExp("(^|\\s)bs-popover\\S+","g"),We={...Be.Default,placement:"right",offset:[0,8],trigger:"click",content:"",template:''},Ue={...Be.DefaultType,content:"(string|element|function)"},$e={HIDE:"hide.bs.popover",HIDDEN:"hidden.bs.popover",SHOW:"show.bs.popover",SHOWN:"shown.bs.popover",INSERTED:"inserted.bs.popover",CLICK:"click.bs.popover",FOCUSIN:"focusin.bs.popover",FOCUSOUT:"focusout.bs.popover",MOUSEENTER:"mouseenter.bs.popover",MOUSELEAVE:"mouseleave.bs.popover"};class Fe extends Be{static get Default(){return We}static get NAME(){return"popover"}static get DATA_KEY(){return"bs.popover"}static get Event(){return $e}static get EVENT_KEY(){return".bs.popover"}static get DefaultType(){return Ue}isWithContent(){return this.getTitle()||this._getContent()}setContent(){const t=this.getTipElement();this.setElementContent(H.findOne(".popover-header",t),this.getTitle());let e=this._getContent();"function"==typeof e&&(e=e.call(this._element)),this.setElementContent(H.findOne(".popover-body",t),e),t.classList.remove("fade","show")}_addAttachmentClass(t){this.getTipElement().classList.add("bs-popover-"+this.updateAttachment(t))}_getContent(){return this._element.getAttribute("data-bs-content")||this.config.content}_cleanTipClass(){const t=this.getTipElement(),e=t.getAttribute("class").match(He);null!==e&&e.length>0&&e.map(t=>t.trim()).forEach(e=>t.classList.remove(e))}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.popover");const i="object"==typeof t?t:null;if((e||!/dispose|hide/.test(t))&&(e||(e=new Fe(this,i),b.set(this,"bs.popover",e)),"string"==typeof t)){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}m("popover",Fe);const ze={offset:10,method:"auto",target:""},Ke={offset:"number",method:"string",target:"(string|element)"};class Ye extends j{constructor(t,e){super(t),this._scrollElement="BODY"===this._element.tagName?window:this._element,this._config=this._getConfig(e),this._selector=`${this._config.target} .nav-link, ${this._config.target} .list-group-item, ${this._config.target} .dropdown-item`,this._offsets=[],this._targets=[],this._activeTarget=null,this._scrollHeight=0,N.on(this._scrollElement,"scroll.bs.scrollspy",()=>this._process()),this.refresh(),this._process()}static get Default(){return ze}static get DATA_KEY(){return"bs.scrollspy"}refresh(){const t=this._scrollElement===this._scrollElement.window?"offset":"position",e="auto"===this._config.method?t:this._config.method,s="position"===e?this._getScrollTop():0;this._offsets=[],this._targets=[],this._scrollHeight=this._getScrollHeight(),H.find(this._selector).map(t=>{const n=i(t),o=n?H.findOne(n):null;if(o){const t=o.getBoundingClientRect();if(t.width||t.height)return[B[e](o).top+s,n]}return null}).filter(t=>t).sort((t,e)=>t[0]-e[0]).forEach(t=>{this._offsets.push(t[0]),this._targets.push(t[1])})}dispose(){super.dispose(),N.off(this._scrollElement,".bs.scrollspy"),this._scrollElement=null,this._config=null,this._selector=null,this._offsets=null,this._targets=null,this._activeTarget=null,this._scrollHeight=null}_getConfig(e){if("string"!=typeof(e={...ze,..."object"==typeof e&&e?e:{}}).target&&r(e.target)){let{id:i}=e.target;i||(i=t("scrollspy"),e.target.id=i),e.target="#"+i}return l("scrollspy",e,Ke),e}_getScrollTop(){return this._scrollElement===window?this._scrollElement.pageYOffset:this._scrollElement.scrollTop}_getScrollHeight(){return this._scrollElement.scrollHeight||Math.max(document.body.scrollHeight,document.documentElement.scrollHeight)}_getOffsetHeight(){return this._scrollElement===window?window.innerHeight:this._scrollElement.getBoundingClientRect().height}_process(){const t=this._getScrollTop()+this._config.offset,e=this._getScrollHeight(),i=this._config.offset+e-this._getOffsetHeight();if(this._scrollHeight!==e&&this.refresh(),t>=i){const t=this._targets[this._targets.length-1];this._activeTarget!==t&&this._activate(t)}else{if(this._activeTarget&&t0)return this._activeTarget=null,void this._clear();for(let e=this._offsets.length;e--;)this._activeTarget!==this._targets[e]&&t>=this._offsets[e]&&(void 0===this._offsets[e+1]||t`${e}[data-bs-target="${t}"],${e}[href="${t}"]`),i=H.findOne(e.join(","));i.classList.contains("dropdown-item")?(H.findOne(".dropdown-toggle",i.closest(".dropdown")).classList.add("active"),i.classList.add("active")):(i.classList.add("active"),H.parents(i,".nav, .list-group").forEach(t=>{H.prev(t,".nav-link, .list-group-item").forEach(t=>t.classList.add("active")),H.prev(t,".nav-item").forEach(t=>{H.children(t,".nav-link").forEach(t=>t.classList.add("active"))})})),N.trigger(this._scrollElement,"activate.bs.scrollspy",{relatedTarget:t})}_clear(){H.find(this._selector).filter(t=>t.classList.contains("active")).forEach(t=>t.classList.remove("active"))}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.scrollspy");if(e||(e=new Ye(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(window,"load.bs.scrollspy.data-api",()=>{H.find('[data-bs-spy="scroll"]').forEach(t=>new Ye(t,B.getDataAttributes(t)))}),m("scrollspy",Ye);class qe extends j{static get DATA_KEY(){return"bs.tab"}show(){if(this._element.parentNode&&this._element.parentNode.nodeType===Node.ELEMENT_NODE&&this._element.classList.contains("active")||d(this._element))return;let t;const e=s(this._element),i=this._element.closest(".nav, .list-group");if(i){const e="UL"===i.nodeName||"OL"===i.nodeName?":scope > li > .active":".active";t=H.find(e,i),t=t[t.length-1]}const n=t?N.trigger(t,"hide.bs.tab",{relatedTarget:this._element}):null;if(N.trigger(this._element,"show.bs.tab",{relatedTarget:t}).defaultPrevented||null!==n&&n.defaultPrevented)return;this._activate(this._element,i);const o=()=>{N.trigger(t,"hidden.bs.tab",{relatedTarget:this._element}),N.trigger(this._element,"shown.bs.tab",{relatedTarget:t})};e?this._activate(e,e.parentNode,o):o()}_activate(t,e,i){const s=(!e||"UL"!==e.nodeName&&"OL"!==e.nodeName?H.children(e,".active"):H.find(":scope > li > .active",e))[0],o=i&&s&&s.classList.contains("fade"),r=()=>this._transitionComplete(t,s,i);if(s&&o){const t=n(s);s.classList.remove("show"),N.one(s,"transitionend",r),a(s,t)}else r()}_transitionComplete(t,e,i){if(e){e.classList.remove("active");const t=H.findOne(":scope > .dropdown-menu .active",e.parentNode);t&&t.classList.remove("active"),"tab"===e.getAttribute("role")&&e.setAttribute("aria-selected",!1)}t.classList.add("active"),"tab"===t.getAttribute("role")&&t.setAttribute("aria-selected",!0),u(t),t.classList.contains("fade")&&t.classList.add("show"),t.parentNode&&t.parentNode.classList.contains("dropdown-menu")&&(t.closest(".dropdown")&&H.find(".dropdown-toggle").forEach(t=>t.classList.add("active")),t.setAttribute("aria-expanded",!0)),i&&i()}static jQueryInterface(t){return this.each((function(){const e=b.get(this,"bs.tab")||new qe(this);if("string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t]()}}))}}N.on(document,"click.bs.tab.data-api",'[data-bs-toggle="tab"], [data-bs-toggle="pill"], [data-bs-toggle="list"]',(function(t){t.preventDefault(),(b.get(this,"bs.tab")||new qe(this)).show()})),m("tab",qe);const Ve={animation:"boolean",autohide:"boolean",delay:"number"},Xe={animation:!0,autohide:!0,delay:5e3};class Qe extends j{constructor(t,e){super(t),this._config=this._getConfig(e),this._timeout=null,this._setListeners()}static get DefaultType(){return Ve}static get Default(){return Xe}static get DATA_KEY(){return"bs.toast"}show(){if(N.trigger(this._element,"show.bs.toast").defaultPrevented)return;this._clearTimeout(),this._config.animation&&this._element.classList.add("fade");const t=()=>{this._element.classList.remove("showing"),this._element.classList.add("show"),N.trigger(this._element,"shown.bs.toast"),this._config.autohide&&(this._timeout=setTimeout(()=>{this.hide()},this._config.delay))};if(this._element.classList.remove("hide"),u(this._element),this._element.classList.add("showing"),this._config.animation){const e=n(this._element);N.one(this._element,"transitionend",t),a(this._element,e)}else t()}hide(){if(!this._element.classList.contains("show"))return;if(N.trigger(this._element,"hide.bs.toast").defaultPrevented)return;const t=()=>{this._element.classList.add("hide"),N.trigger(this._element,"hidden.bs.toast")};if(this._element.classList.remove("show"),this._config.animation){const e=n(this._element);N.one(this._element,"transitionend",t),a(this._element,e)}else t()}dispose(){this._clearTimeout(),this._element.classList.contains("show")&&this._element.classList.remove("show"),N.off(this._element,"click.dismiss.bs.toast"),super.dispose(),this._config=null}_getConfig(t){return t={...Xe,...B.getDataAttributes(this._element),..."object"==typeof t&&t?t:{}},l("toast",t,this.constructor.DefaultType),t}_setListeners(){N.on(this._element,"click.dismiss.bs.toast",'[data-bs-dismiss="toast"]',()=>this.hide())}_clearTimeout(){clearTimeout(this._timeout),this._timeout=null}static jQueryInterface(t){return this.each((function(){let e=b.get(this,"bs.toast");if(e||(e=new Qe(this,"object"==typeof t&&t)),"string"==typeof t){if(void 0===e[t])throw new TypeError(`No method named "${t}"`);e[t](this)}}))}}return m("toast",Qe),{Alert:P,Button:I,Carousel:Y,Collapse:X,Dropdown:_e,Modal:ye,Offcanvas:Oe,Popover:Fe,ScrollSpy:Ye,Tab:qe,Toast:Qe,Tooltip:Be}}));
+
+
+/* Jquery migrate 3.3.0*/
+
+void 0===jQuery.migrateMute&&(jQuery.migrateMute=!0),function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],function(t){return e(t,window)}):"object"==typeof module&&module.exports?module.exports=e(require("jquery"),window):e(jQuery,window)}(function(e,t){"use strict";function r(t){return 0<=function(e,t){var r,n=/^(\d+)\.(\d+)\.(\d+)/,o=n.exec(e)||[],i=n.exec(t)||[];for(r=1;r<=3;r++){if(+o[r]>+i[r])return 1;if(+o[r]<+i[r])return-1}return 0}(e.fn.jquery,t)}e.migrateVersion="3.3.0",t.console&&t.console.log&&(e&&r("3.0.0")||t.console.log("JQMIGRATE: jQuery 3.0.0+ REQUIRED"),e.migrateWarnings&&t.console.log("JQMIGRATE: Migrate plugin loaded multiple times"),t.console.log("JQMIGRATE: Migrate is installed"+(e.migrateMute?"":" with logging active")+", version "+e.migrateVersion));var n={};function o(r){var o=t.console;e.migrateDeduplicateWarnings&&n[r]||(n[r]=!0,e.migrateWarnings.push(r),o&&o.warn&&!e.migrateMute&&(o.warn("JQMIGRATE: "+r),e.migrateTrace&&o.trace&&o.trace()))}function i(e,t,r,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get:function(){return o(n),r},set:function(e){o(n),r=e}})}function a(e,t,r,n){e[t]=function(){return o(n),r.apply(this,arguments)}}e.migrateDeduplicateWarnings=!0,e.migrateWarnings=[],void 0===e.migrateTrace&&(e.migrateTrace=!0),e.migrateReset=function(){n={},e.migrateWarnings.length=0},"BackCompat"===t.document.compatMode&&o("jQuery is not compatible with Quirks Mode");var s,u={},c=e.fn.init,d=e.find,l=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/,p=/\[(\s*[-\w]+\s*)([~|^$*]?=)\s*([-\w#]*?#[-\w#]*)\s*\]/g,f=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;for(s in e.fn.init=function(e){var t=Array.prototype.slice.call(arguments);return"string"==typeof e&&"#"===e&&(o("jQuery( '#' ) is not a valid selector"),t[0]=[]),c.apply(this,t)},e.fn.init.prototype=e.fn,e.find=function(e){var r=Array.prototype.slice.call(arguments);if("string"==typeof e&&l.test(e))try{t.document.querySelector(e)}catch(n){e=e.replace(p,function(e,t,r,n){return"["+t+r+'"'+n+'"]'});try{t.document.querySelector(e),o("Attribute selector with '#' must be quoted: "+r[0]),r[0]=e}catch(e){o("Attribute selector with '#' was not fixed: "+r[0])}}return d.apply(this,r)},d)Object.prototype.hasOwnProperty.call(d,s)&&(e.find[s]=d[s]);if(a(e.fn,"size",function(){return this.length},"jQuery.fn.size() is deprecated and removed; use the .length property"),a(e,"parseJSON",function(){return JSON.parse.apply(null,arguments)},"jQuery.parseJSON is deprecated; use JSON.parse"),a(e,"holdReady",e.holdReady,"jQuery.holdReady is deprecated"),a(e,"unique",e.uniqueSort,"jQuery.unique is deprecated; use jQuery.uniqueSort"),i(e.expr,"filters",e.expr.pseudos,"jQuery.expr.filters is deprecated; use jQuery.expr.pseudos"),i(e.expr,":",e.expr.pseudos,"jQuery.expr[':'] is deprecated; use jQuery.expr.pseudos"),r("3.1.1")&&a(e,"trim",function(e){return null==e?"":(e+"").replace(f,"")},"jQuery.trim is deprecated; use String.prototype.trim"),r("3.2.0")&&a(e,"nodeName",function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},"jQuery.nodeName is deprecated"),r("3.3.0")&&(a(e,"isNumeric",function(e){var t=typeof e;return("number"==t||"string"==t)&&!isNaN(e-parseFloat(e))},"jQuery.isNumeric() is deprecated"),e.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){u["[object "+t+"]"]=t.toLowerCase()}),a(e,"type",function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?u[Object.prototype.toString.call(e)]||"object":typeof e},"jQuery.type is deprecated"),a(e,"isFunction",function(e){return"function"==typeof e},"jQuery.isFunction() is deprecated"),a(e,"isWindow",function(e){return null!=e&&e===e.window},"jQuery.isWindow() is deprecated"),a(e,"isArray",Array.isArray,"jQuery.isArray is deprecated; use Array.isArray")),e.ajax){var y=e.ajax;e.ajax=function(){var e=y.apply(this,arguments);return e.promise&&(a(e,"success",e.done,"jQXHR.success is deprecated and removed"),a(e,"error",e.fail,"jQXHR.error is deprecated and removed"),a(e,"complete",e.always,"jQXHR.complete is deprecated and removed")),e}}var m=e.fn.removeAttr,g=e.fn.toggleClass,h=/\S+/g;function v(e){return e.replace(/-([a-z])/g,function(e,t){return t.toUpperCase()})}e.fn.removeAttr=function(t){var r=this;return e.each(t.match(h),function(t,n){e.expr.match.bool.test(n)&&(o("jQuery.fn.removeAttr no longer sets boolean properties: "+n),r.prop(n,!1))}),m.apply(this,arguments)};var j,Q=!(e.fn.toggleClass=function(t){return void 0!==t&&"boolean"!=typeof t?g.apply(this,arguments):(o("jQuery.fn.toggleClass( boolean ) is deprecated"),this.each(function(){var r=this.getAttribute&&this.getAttribute("class")||"";r&&e.data(this,"__className__",r),this.setAttribute&&this.setAttribute("class",r||!1===t?"":e.data(this,"__className__")||"")}))}),b=/^[a-z]/,w=/^(?:Border(?:Top|Right|Bottom|Left)?(?:Width|)|(?:Margin|Padding)?(?:Top|Right|Bottom|Left)?|(?:Min|Max)?(?:Width|Height))$/;e.swap&&e.each(["height","width","reliableMarginRight"],function(t,r){var n=e.cssHooks[r]&&e.cssHooks[r].get;n&&(e.cssHooks[r].get=function(){var e;return Q=!0,e=n.apply(this,arguments),Q=!1,e})}),e.swap=function(e,t,r,n){var i,a,s={};for(a in Q||o("jQuery.swap() is undocumented and deprecated"),t)s[a]=e.style[a],e.style[a]=t[a];for(a in i=r.apply(e,n||[]),t)e.style[a]=s[a];return i},r("3.4.0")&&"undefined"!=typeof Proxy&&(e.cssProps=new Proxy(e.cssProps||{},{set:function(){return o("JQMIGRATE: jQuery.cssProps is deprecated"),Reflect.set.apply(this,arguments)}})),e.cssNumber||(e.cssNumber={}),j=e.fn.css,e.fn.css=function(t,r){var n=this;return"string"!=typeof t&&e.each(t,function(t,r){e.fn.css.call(n,t,r)}),"number"!=typeof r||function(e){return b.test(e)&&w.test(e[0].toUpperCase()+e.slice(1))}(v(t))||o("Use of number-typed values is deprecated in jQuery.fn.css"),j.apply(this,arguments)};var x=e.data;if(e.data=function(t,r,n){var i,a,s;if(r&&"object"==typeof r&&2===arguments.length){for(s in i=e.hasData(t)&&x.call(this,t),a={},r)s!==v(s)?(o("jQuery.data() always sets/gets camelCased names: "+s),i[s]=r[s]):a[s]=r[s];return x.call(this,t,a),r}return r&&"string"==typeof r&&r!==v(r)&&(i=e.hasData(t)&&x.call(this,t))&&r in i?(o("jQuery.data() always sets/gets camelCased names: "+r),2$2>");t!==e&&C(e)!==C(t)&&o("HTML tags must be properly nested and closed: "+e)}e.event.props=[],e.event.fixHooks={},i(e.event.props,"concat",e.event.props.concat,"jQuery.event.props.concat() is deprecated and removed"),e.event.fix=function(t){var r,n=t.type,i=this.fixHooks[n],a=e.event.props;if(a.length)for(o("jQuery.event.props are deprecated and removed: "+a.join());a.length;)e.event.addProp(a.pop());if(i&&!i._migrated_&&(i._migrated_=!0,o("jQuery.event.fixHooks are deprecated and removed: "+n),(a=i.props)&&a.length))for(;a.length;)e.event.addProp(a.pop());return r=N.call(this,t),i&&i.filter?i.filter(r,t):r},e.event.add=function(e,r){return e===t&&"load"===r&&"complete"===t.document.readyState&&o("jQuery(window).on('load'...) called after load event occurred"),R.apply(this,arguments)},e.each(["load","unload","error"],function(t,r){e.fn[r]=function(){var e=Array.prototype.slice.call(arguments,0);return"load"===r&&"string"==typeof e[0]?H.apply(this,e):(o("jQuery.fn."+r+"() is deprecated"),e.splice(0,0,r),arguments.length?this.on.apply(this,e):(this.triggerHandler.apply(this,e),this))}}),e.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(t,r){e.fn[r]=function(e,t){return o("jQuery.fn."+r+"() event shorthand is deprecated"),0\x20\t\r\n\f]*)[^>]*)\/>/gi,q=e.htmlPrefilter;e.UNSAFE_restoreLegacyHtmlPrefilter=function(){e.htmlPrefilter=function(e){return T(e),e.replace(P,"<$1>$2>")}},e.htmlPrefilter=function(e){return T(e),q(e)};var D=e.fn.offset;if(e.fn.offset=function(){var r,n=this[0];if(n&&n.nodeType)return r=(n.ownerDocument||t.document).documentElement,e.contains(r,n)?D.apply(this,arguments):(o("jQuery.fn.offset() requires an element connected to a document"),{top:0,left:0});o("jQuery.fn.offset() requires a valid DOM element")},e.ajax){var E=e.param;e.param=function(t,r){var n=e.ajaxSettings&&e.ajaxSettings.traditional;return void 0===r&&n&&(o("jQuery.param() no longer uses jQuery.ajaxSettings.traditional"),r=n),E.call(this,t,r)}}var _=e.fn.andSelf||e.fn.addBack;if(e.fn.andSelf=function(){return o("jQuery.fn.andSelf() is deprecated and removed, use jQuery.fn.addBack()"),_.apply(this,arguments)},e.Deferred){var F=e.Deferred,O=[["resolve","done",e.Callbacks("once memory"),e.Callbacks("once memory"),"resolved"],["reject","fail",e.Callbacks("once memory"),e.Callbacks("once memory"),"rejected"],["notify","progress",e.Callbacks("memory"),e.Callbacks("memory")]];e.Deferred=function(t){var r=F(),n=r.promise();return r.pipe=n.pipe=function(){var t=arguments;return o("deferred.pipe() is deprecated"),e.Deferred(function(o){e.each(O,function(e,i){var a="function"==typeof t[e]&&t[e];r[i[1]](function(){var e=a&&a.apply(this,arguments);e&&"function"==typeof e.promise?e.promise().done(o.resolve).fail(o.reject).progress(o.notify):o[i[0]+"With"](this===n?o.promise():this,a?[e]:arguments)})}),t=null}).promise()},t&&t.call(r,r),r},e.Deferred.exceptionHook=F.exceptionHook}return e});
+
+/*! modernizr 3.11.2 (Custom Build) | MIT */
+
+!function(e,t,n,r){function o(e,t){return typeof e===t}function i(e){var t=b.className,n=w._config.classPrefix||"";if(S&&(t=t.baseVal),w._config.enableJSClass){var r=new RegExp("(^|\\s)"+n+"no-js(\\s|$)");t=t.replace(r,"$1"+n+"js$2")}w._config.enableClasses&&(e.length>0&&(t+=" "+n+e.join(" "+n)),S?b.className.baseVal=t:b.className=t)}function s(e,t){if("object"==typeof e)for(var n in e)T(e,n)&&s(n,e[n]);else{var r=(e=e.toLowerCase()).split("."),o=w[r[0]];if(2===r.length&&(o=o[r[1]]),void 0!==o)return w;t="function"==typeof t?t():t,1===r.length?w[r[0]]=t:(!w[r[0]]||w[r[0]]instanceof Boolean||(w[r[0]]=new Boolean(w[r[0]])),w[r[0]][r[1]]=t),i([(t&&!1!==t?"":"no-")+r.join("-")]),w._trigger(e,t)}return w}function a(){return"function"!=typeof n.createElement?n.createElement(arguments[0]):S?n.createElementNS.call(n,"http://www.w3.org/2000/svg",arguments[0]):n.createElement.apply(n,arguments)}function l(e,t,r,o){var i,s,l,u,f="modernizr",c=a("div"),d=function(){var e=n.body;return e||((e=a(S?"svg":"body")).fake=!0),e}();if(parseInt(r,10))for(;r--;)(l=a("div")).id=o?o[r]:f+(r+1),c.appendChild(l);return(i=a("style")).type="text/css",i.id="s"+f,(d.fake?d:c).appendChild(i),d.appendChild(c),i.styleSheet?i.styleSheet.cssText=e:i.appendChild(n.createTextNode(e)),c.id=f,d.fake&&(d.style.background="",d.style.overflow="hidden",u=b.style.overflow,b.style.overflow="hidden",b.appendChild(d)),s=t(c,e),d.fake?(d.parentNode.removeChild(d),b.style.overflow=u,b.offsetHeight):c.parentNode.removeChild(c),!!s}function u(e,n,r){var o;if("getComputedStyle"in t){o=getComputedStyle.call(t,e,n);var i=t.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(i){i[i.error?"error":"log"].call(i,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else o=!n&&e.currentStyle&&e.currentStyle[r];return o}function f(e,t){return!!~(""+e).indexOf(t)}function c(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function d(e,n){var o=e.length;if("CSS"in t&&"supports"in t.CSS){for(;o--;)if(t.CSS.supports(c(e[o]),n))return!0;return!1}if("CSSSupportsRule"in t){for(var i=[];o--;)i.push("("+c(e[o])+":"+n+")");return l("@supports ("+(i=i.join(" or "))+") { #modernizr { position: absolute; } }",function(e){return"absolute"===u(e,null,"position")})}return r}function p(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function A(e,t,n,i){function s(){u&&(delete z.style,delete z.modElem)}if(i=!o(i,"undefined")&&i,!o(n,"undefined")){var l=d(e,n);if(!o(l,"undefined"))return l}for(var u,c,A,m,h,v=["modernizr","tspan","samp"];!z.style&&v.length;)u=!0,z.modElem=a(v.shift()),z.style=z.modElem.style;for(A=e.length,c=0;c
+// +----------------------------------------------------------------------
+
+// [ 应用入口文件 ]
+namespace think;
+if ( $_SERVER['REQUEST_METHOD'] == 'OPTIONS' ) {
+ $origin = rtrim($_SERVER['HTTP_REFERER'],'/');
+ header("Access-Control-Allow-Origin:".$origin);
+ header("Access-Control-Allow-Credentials: true");
+ header("Access-Control-Allow-Headers:Authorization,Content-Type,If-Match,If-Modified-Since,If-None-Match,If-Unmodified-Since,X-Requested-With,x_requested_with,x-token,whitelist");
+ header('Access-Control-Allow-Methods: GET, POST, PUT,DELETE,OPTIONS,PATCH');
+ exit;
+}
+require __DIR__ . '/../vendor/autoload.php';
+
+// 执行HTTP应用并响应
+$http = (new App())->http;
+
+$response = $http->run();
+
+$response->send();
+
+$http->end($response);
diff --git a/public/php/Uploader.class.php b/public/php/Uploader.class.php
new file mode 100644
index 0000000..b7d6bf8
--- /dev/null
+++ b/public/php/Uploader.class.php
@@ -0,0 +1,372 @@
+ "临时文件错误",
+ "ERROR_TMP_FILE_NOT_FOUND" => "找不到临时文件",
+ "ERROR_SIZE_EXCEED" => "文件大小超出网站限制",
+ "ERROR_TYPE_NOT_ALLOWED" => "文件类型不允许",
+ "ERROR_CREATE_DIR" => "目录创建失败",
+ "ERROR_DIR_NOT_WRITEABLE" => "目录没有写权限",
+ "ERROR_FILE_MOVE" => "文件保存时出错",
+ "ERROR_FILE_NOT_FOUND" => "找不到上传文件",
+ "ERROR_WRITE_CONTENT" => "写入文件内容错误",
+ "ERROR_UNKNOWN" => "未知错误",
+ "ERROR_DEAD_LINK" => "链接不可用",
+ "ERROR_HTTP_LINK" => "链接不是http链接",
+ "ERROR_HTTP_CONTENTTYPE" => "链接contentType不正确",
+ "INVALID_URL" => "非法 URL",
+ "INVALID_IP" => "非法 IP"
+ );
+
+ /**
+ * 构造函数
+ * @param string $fileField 表单名称
+ * @param array $config 配置项
+ * @param bool $base64 是否解析base64编码,可省略。若开启,则$fileField代表的是base64编码的字符串表单名
+ */
+ public function __construct($fileField, $config, $type = "upload")
+ {
+ $this->fileField = $fileField;
+ $this->config = $config;
+ $this->type = $type;
+ if ($type == "remote") {
+ $this->saveRemote();
+ } else if($type == "base64") {
+ $this->upBase64();
+ } else {
+ $this->upFile();
+ }
+
+ $this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);
+ }
+
+ /**
+ * 上传文件的主处理方法
+ * @return mixed
+ */
+ private function upFile()
+ {
+ $file = $this->file = $_FILES[$this->fileField];
+ if (!$file) {
+ $this->stateInfo = $this->getStateInfo("ERROR_FILE_NOT_FOUND");
+ return;
+ }
+ if ($this->file['error']) {
+ $this->stateInfo = $this->getStateInfo($file['error']);
+ return;
+ } else if (!file_exists($file['tmp_name'])) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TMP_FILE_NOT_FOUND");
+ return;
+ } else if (!is_uploaded_file($file['tmp_name'])) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TMPFILE");
+ return;
+ }
+
+ $this->oriName = $file['name'];
+ $this->fileSize = $file['size'];
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //检查是否不允许的文件格式
+ if (!$this->checkType()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_TYPE_NOT_ALLOWED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(move_uploaded_file($file["tmp_name"], $this->filePath) && file_exists($this->filePath))) { //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_FILE_MOVE");
+ } else { //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+ }
+
+ /**
+ * 处理base64编码的图片上传
+ * @return mixed
+ */
+ private function upBase64()
+ {
+ $base64Data = $_POST[$this->fileField];
+ $img = base64_decode($base64Data);
+
+ $this->oriName = $this->config['oriName'];
+ $this->fileSize = strlen($img);
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
+ } else { //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+
+ }
+
+ /**
+ * 拉取远程图片
+ * @return mixed
+ */
+ private function saveRemote()
+ {
+ $imgUrl = htmlspecialchars($this->fileField);
+ $imgUrl = str_replace("&", "&", $imgUrl);
+
+ //http开头验证
+ if (strpos($imgUrl, "http") !== 0) {
+ $this->stateInfo = $this->getStateInfo("ERROR_HTTP_LINK");
+ return;
+ }
+
+ preg_match('/(^https*:\/\/[^:\/]+)/', $imgUrl, $matches);
+ $host_with_protocol = count($matches) > 1 ? $matches[1] : '';
+
+ // 判断是否是合法 url
+ if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {
+ $this->stateInfo = $this->getStateInfo("INVALID_URL");
+ return;
+ }
+
+ preg_match('/^https*:\/\/(.+)/', $host_with_protocol, $matches);
+ $host_without_protocol = count($matches) > 1 ? $matches[1] : '';
+
+ // 此时提取出来的可能是 ip 也有可能是域名,先获取 ip
+ $ip = gethostbyname($host_without_protocol);
+ // 判断是否是私有 ip
+ if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {
+ $this->stateInfo = $this->getStateInfo("INVALID_IP");
+ return;
+ }
+
+ //获取请求头并检测死链
+ $heads = get_headers($imgUrl, 1);
+ if (!(stristr($heads[0], "200") && stristr($heads[0], "OK"))) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DEAD_LINK");
+ return;
+ }
+ //格式验证(扩展名验证和Content-Type验证)
+ $fileType = strtolower(strrchr($imgUrl, '.'));
+ if (!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], "image")) {
+ $this->stateInfo = $this->getStateInfo("ERROR_HTTP_CONTENTTYPE");
+ return;
+ }
+
+ //打开输出缓冲区并获取远程图片
+ ob_start();
+ $context = stream_context_create(
+ array('http' => array(
+ 'follow_location' => false // don't follow redirects
+ ))
+ );
+ readfile($imgUrl, false, $context);
+ $img = ob_get_contents();
+ ob_end_clean();
+ preg_match("/[\/]([^\/]*)[\.]?[^\.\/]*$/", $imgUrl, $m);
+
+ $this->oriName = $m ? $m[1]:"";
+ $this->fileSize = strlen($img);
+ $this->fileType = $this->getFileExt();
+ $this->fullName = $this->getFullName();
+ $this->filePath = $this->getFilePath();
+ $this->fileName = $this->getFileName();
+ $dirname = dirname($this->filePath);
+
+ //检查文件大小是否超出限制
+ if (!$this->checkSize()) {
+ $this->stateInfo = $this->getStateInfo("ERROR_SIZE_EXCEED");
+ return;
+ }
+
+ //创建目录失败
+ if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_CREATE_DIR");
+ return;
+ } else if (!is_writeable($dirname)) {
+ $this->stateInfo = $this->getStateInfo("ERROR_DIR_NOT_WRITEABLE");
+ return;
+ }
+
+ //移动文件
+ if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败
+ $this->stateInfo = $this->getStateInfo("ERROR_WRITE_CONTENT");
+ } else { //移动成功
+ $this->stateInfo = $this->stateMap[0];
+ }
+
+ }
+
+ /**
+ * 上传错误检查
+ * @param $errCode
+ * @return string
+ */
+ private function getStateInfo($errCode)
+ {
+ return !$this->stateMap[$errCode] ? $this->stateMap["ERROR_UNKNOWN"] : $this->stateMap[$errCode];
+ }
+
+ /**
+ * 获取文件扩展名
+ * @return string
+ */
+ private function getFileExt()
+ {
+ return strtolower(strrchr($this->oriName, '.'));
+ }
+
+ /**
+ * 重命名文件
+ * @return string
+ */
+ private function getFullName()
+ {
+ //替换日期事件
+ $t = time();
+ $d = explode('-', date("Y-y-m-d-H-i-s"));
+ $format = $this->config["pathFormat"];
+ $format = str_replace("{yyyy}", $d[0], $format);
+ $format = str_replace("{yy}", $d[1], $format);
+ $format = str_replace("{mm}", $d[2], $format);
+ $format = str_replace("{dd}", $d[3], $format);
+ $format = str_replace("{hh}", $d[4], $format);
+ $format = str_replace("{ii}", $d[5], $format);
+ $format = str_replace("{ss}", $d[6], $format);
+ $format = str_replace("{time}", $t, $format);
+
+ //过滤文件名的非法自负,并替换文件名
+ $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));
+ $oriName = preg_replace("/[\|\?\"\<\>\/\*\\\\]+/", '', $oriName);
+ $format = str_replace("{filename}", $oriName, $format);
+
+ //替换随机字符串
+ $randNum = rand(1, 10000000000) . rand(1, 10000000000);
+ if (preg_match("/\{rand\:([\d]*)\}/i", $format, $matches)) {
+ $format = preg_replace("/\{rand\:[\d]*\}/i", substr($randNum, 0, $matches[1]), $format);
+ }
+
+ $ext = $this->getFileExt();
+ return $format . $ext;
+ }
+
+ /**
+ * 获取文件名
+ * @return string
+ */
+ private function getFileName () {
+ return substr($this->filePath, strrpos($this->filePath, '/') + 1);
+ }
+
+ /**
+ * 获取文件完整路径
+ * @return string
+ */
+ private function getFilePath()
+ {
+ $fullname = $this->fullName;
+ $rootPath = $_SERVER['DOCUMENT_ROOT'];
+
+ if (substr($fullname, 0, 1) != '/') {
+ $fullname = '/' . $fullname;
+ }
+
+ return $rootPath . $fullname;
+ }
+
+ /**
+ * 文件类型检测
+ * @return bool
+ */
+ private function checkType()
+ {
+ return in_array($this->getFileExt(), $this->config["allowFiles"]);
+ }
+
+ /**
+ * 文件大小检测
+ * @return bool
+ */
+ private function checkSize()
+ {
+ return $this->fileSize <= ($this->config["maxSize"]);
+ }
+
+ /**
+ * 获取当前上传成功文件的各项信息
+ * @return array
+ */
+ public function getFileInfo()
+ {
+ return array(
+ "state" => $this->stateInfo,
+ "url" => $this->fullName,
+ "title" => $this->fileName,
+ "original" => $this->oriName,
+ "type" => $this->fileType,
+ "size" => $this->fileSize
+ );
+ }
+
+}
\ No newline at end of file
diff --git a/public/php/action_crawler.php b/public/php/action_crawler.php
new file mode 100644
index 0000000..b9e18df
--- /dev/null
+++ b/public/php/action_crawler.php
@@ -0,0 +1,44 @@
+ $CONFIG['catcherPathFormat'],
+ "maxSize" => $CONFIG['catcherMaxSize'],
+ "allowFiles" => $CONFIG['catcherAllowFiles'],
+ "oriName" => "remote.png"
+);
+$fieldName = $CONFIG['catcherFieldName'];
+
+/* 抓取远程图片 */
+$list = array();
+if (isset($_POST[$fieldName])) {
+ $source = $_POST[$fieldName];
+} else {
+ $source = $_GET[$fieldName];
+}
+foreach ($source as $imgUrl) {
+ $item = new Uploader($imgUrl, $config, "remote");
+ $info = $item->getFileInfo();
+ array_push($list, array(
+ "state" => $info["state"],
+ "url" => $info["url"],
+ "size" => $info["size"],
+ "title" => htmlspecialchars($info["title"]),
+ "original" => htmlspecialchars($info["original"]),
+ "source" => htmlspecialchars($imgUrl)
+ ));
+}
+
+/* 返回抓取数据 */
+return json_encode(array(
+ 'state'=> count($list) ? 'SUCCESS':'ERROR',
+ 'list'=> $list
+));
\ No newline at end of file
diff --git a/public/php/action_list.php b/public/php/action_list.php
new file mode 100644
index 0000000..bf9cd62
--- /dev/null
+++ b/public/php/action_list.php
@@ -0,0 +1,92 @@
+ "no match file",
+ "list" => array(),
+ "start" => $start,
+ "total" => count($files)
+ ));
+}
+
+/* 获取指定范围的列表 */
+$len = count($files);
+for ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){
+ $list[] = $files[$i];
+}
+//倒序
+//for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){
+// $list[] = $files[$i];
+//}
+
+/* 返回数据 */
+$result = json_encode(array(
+ "state" => "SUCCESS",
+ "list" => $list,
+ "start" => $start,
+ "total" => count($files)
+));
+
+return $result;
+
+
+/**
+ * 遍历获取目录下的指定类型的文件
+ * @param $path
+ * @param array $files
+ * @return array
+ */
+function getfiles($path, $allowFiles, &$files = array())
+{
+ if (!is_dir($path)) return null;
+ if(substr($path, strlen($path) - 1) != '/') $path .= '/';
+ $handle = opendir($path);
+ while (false !== ($file = readdir($handle))) {
+ if ($file != '.' && $file != '..') {
+ $path2 = $path . $file;
+ if (is_dir($path2)) {
+ getfiles($path2, $allowFiles, $files);
+ } else {
+ if (preg_match("/\.(".$allowFiles.")$/i", $file)) {
+ $files[] = array(
+ 'url'=> substr($path2, strlen($_SERVER['DOCUMENT_ROOT'])),
+ 'mtime'=> filemtime($path2)
+ );
+ }
+ }
+ }
+ }
+ return $files;
+}
\ No newline at end of file
diff --git a/public/php/action_upload.php b/public/php/action_upload.php
new file mode 100644
index 0000000..d55b659
--- /dev/null
+++ b/public/php/action_upload.php
@@ -0,0 +1,66 @@
+ $CONFIG['imagePathFormat'],
+ "maxSize" => $CONFIG['imageMaxSize'],
+ "allowFiles" => $CONFIG['imageAllowFiles']
+ );
+ $fieldName = $CONFIG['imageFieldName'];
+ break;
+ case 'uploadscrawl':
+ $config = array(
+ "pathFormat" => $CONFIG['scrawlPathFormat'],
+ "maxSize" => $CONFIG['scrawlMaxSize'],
+ "allowFiles" => $CONFIG['scrawlAllowFiles'],
+ "oriName" => "scrawl.png"
+ );
+ $fieldName = $CONFIG['scrawlFieldName'];
+ $base64 = "base64";
+ break;
+ case 'uploadvideo':
+ $config = array(
+ "pathFormat" => $CONFIG['videoPathFormat'],
+ "maxSize" => $CONFIG['videoMaxSize'],
+ "allowFiles" => $CONFIG['videoAllowFiles']
+ );
+ $fieldName = $CONFIG['videoFieldName'];
+ break;
+ case 'uploadfile':
+ default:
+ $config = array(
+ "pathFormat" => $CONFIG['filePathFormat'],
+ "maxSize" => $CONFIG['fileMaxSize'],
+ "allowFiles" => $CONFIG['fileAllowFiles']
+ );
+ $fieldName = $CONFIG['fileFieldName'];
+ break;
+}
+
+/* 生成上传实例对象并完成上传 */
+$up = new Uploader($fieldName, $config, $base64);
+
+/**
+ * 得到上传文件所对应的各个参数,数组结构
+ * array(
+ * "state" => "", //上传状态,上传成功时必须返回"SUCCESS"
+ * "url" => "", //返回的地址
+ * "title" => "", //新文件名
+ * "original" => "", //原始文件名
+ * "type" => "" //文件类型
+ * "size" => "", //文件大小
+ * )
+ */
+
+/* 返回数据 */
+return json_encode($up->getFileInfo());
diff --git a/public/php/config.json b/public/php/config.json
new file mode 100644
index 0000000..20ba137
--- /dev/null
+++ b/public/php/config.json
@@ -0,0 +1,94 @@
+/* 前后端通信相关的配置,注释只允许使用多行方式 */
+{
+ /* 上传图片配置项 */
+ "imageActionName": "uploadimage", /* 执行上传图片的action名称 */
+ "imageFieldName": "upfile", /* 提交的图片表单名称 */
+ "imageMaxSize": 2048000, /* 上传大小限制,单位B */
+ "imageAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 上传图片格式显示 */
+ "imageCompressEnable": true, /* 是否压缩图片,默认是true */
+ "imageCompressBorder": 1600, /* 图片压缩最长边限制 */
+ "imageInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageUrlPrefix": "http://cms.oricogroup.com/", /* 图片访问路径前缀 */
+ "imagePathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */
+ /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */
+ /* {time} 会替换成时间戳 */
+ /* {yyyy} 会替换成四位年份 */
+ /* {yy} 会替换成两位年份 */
+ /* {mm} 会替换成两位月份 */
+ /* {dd} 会替换成两位日期 */
+ /* {hh} 会替换成两位小时 */
+ /* {ii} 会替换成两位分钟 */
+ /* {ss} 会替换成两位秒 */
+ /* 非法字符 \ : * ? " < > | */
+ /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */
+
+ /* 涂鸦图片上传配置项 */
+ "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */
+ "scrawlFieldName": "upfile", /* 提交的图片表单名称 */
+ "scrawlPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */
+ "scrawlUrlPrefix": "http://cms.oricogroup.com/", /* 图片访问路径前缀 */
+ "scrawlInsertAlign": "none",
+
+ /* 截图工具上传 */
+ "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */
+ "snapscreenPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "snapscreenUrlPrefix": "http://cms.oricogroup.com/", /* 图片访问路径前缀 */
+ "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */
+
+ /* 抓取远程图片配置 */
+ "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"],
+ "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */
+ "catcherFieldName": "source", /* 提交的图片列表表单名称 */
+ "catcherPathFormat": "/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "catcherUrlPrefix": "http://cms.oricogroup.com/", /* 图片访问路径前缀 */
+ "catcherMaxSize": 2048000, /* 上传大小限制,单位B */
+ "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */
+
+ /* 上传视频配置 */
+ "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */
+ "videoFieldName": "upfile", /* 提交的视频表单名称 */
+ "videoPathFormat": "/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "videoUrlPrefix": "http://cms.oricogroup.com/", /* 视频访问路径前缀 */
+ "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */
+ "videoAllowFiles": [
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */
+
+ /* 上传文件配置 */
+ "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */
+ "fileFieldName": "upfile", /* 提交的文件表单名称 */
+ "filePathFormat": "/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */
+ "fileUrlPrefix": "http://cms.oricogroup.com/", /* 文件访问路径前缀 */
+ "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */
+ "fileAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ], /* 上传文件格式显示 */
+
+ /* 列出指定目录下的图片 */
+ "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */
+ "imageManagerListPath": "/ueditor/php/upload/image/", /* 指定要列出图片的目录 */
+ "imageManagerListSize": 20, /* 每次列出文件数量 */
+ "imageManagerUrlPrefix": "http://cms.oricogroup.com/", /* 图片访问路径前缀 */
+ "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */
+ "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */
+
+ /* 列出指定目录下的文件 */
+ "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */
+ "fileManagerListPath": "/ueditor/php/upload/file/", /* 指定要列出文件的目录 */
+ "fileManagerUrlPrefix": "http://cms.oricogroup.com/", /* 文件访问路径前缀 */
+ "fileManagerListSize": 20, /* 每次列出文件数量 */
+ "fileManagerAllowFiles": [
+ ".png", ".jpg", ".jpeg", ".gif", ".bmp",
+ ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg",
+ ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid",
+ ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso",
+ ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml"
+ ] /* 列出的文件类型 */
+
+}
\ No newline at end of file
diff --git a/public/php/controller.php b/public/php/controller.php
new file mode 100644
index 0000000..a60adc1
--- /dev/null
+++ b/public/php/controller.php
@@ -0,0 +1,60 @@
+ '请求地址出错'
+ ));
+ break;
+}
+
+/* 输出结果 */
+if (isset($_GET["callback"])) {
+ if (preg_match("/^[\w_]+$/", $_GET["callback"])) {
+ echo htmlspecialchars($_GET["callback"]) . '(' . $result . ')';
+ } else {
+ echo json_encode(array(
+ 'state'=> 'callback参数不合法'
+ ));
+ }
+} else {
+ echo $result;
+}
\ No newline at end of file
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..eb05362
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow:
diff --git a/public/router.php b/public/router.php
new file mode 100644
index 0000000..9b39a62
--- /dev/null
+++ b/public/router.php
@@ -0,0 +1,19 @@
+
+// +----------------------------------------------------------------------
+// $Id$
+
+if (is_file($_SERVER["DOCUMENT_ROOT"] . $_SERVER["SCRIPT_NAME"])) {
+ return false;
+} else {
+ $_SERVER["SCRIPT_FILENAME"] = __DIR__ . '/index.php';
+
+ require __DIR__ . "/index.php";
+}
diff --git a/public/static/.gitignore b/public/static/.gitignore
new file mode 100755
index 0000000..c96a04f
--- /dev/null
+++ b/public/static/.gitignore
@@ -0,0 +1,2 @@
+*
+!.gitignore
\ No newline at end of file
diff --git a/public/upload b/public/upload
new file mode 100644
index 0000000..5b445ab
--- /dev/null
+++ b/public/upload
@@ -0,0 +1,175 @@
+
+
+
+
+
+
+ Title
+
+
+
+
+
+
+
+
+ 选择文件
+
+
+
+
+
+
+
+
diff --git a/route/app.php b/route/app.php
new file mode 100644
index 0000000..52c6f3c
--- /dev/null
+++ b/route/app.php
@@ -0,0 +1,18 @@
+
+// +----------------------------------------------------------------------
+use think\facade\Route;
+
+return [
+ //全局错误路由
+ Route::miss(function(){
+ return json(["status"=>504,'message'=>'不支持直接请求,请使用正确的接口地址和参数','route'=>request()->url(),'create_time'=>time(),'date_time'=>date("Y-m-d H:i:s",time())]);
+ })
+];
diff --git a/think b/think
new file mode 100644
index 0000000..2429d22
--- /dev/null
+++ b/think
@@ -0,0 +1,10 @@
+#!/usr/bin/env php
+console->run();
\ No newline at end of file