From 7396f45ccafb1f7410f6c9c5f5f15a1c11eeae4f Mon Sep 17 00:00:00 2001 From: clunt Date: Tue, 8 Feb 2022 11:36:50 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=9D=E5=A7=8B=E8=AF=9D=E9=A1=B9=E7=9B=AE?= =?UTF-8?q?=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 20 + bin/clean.bat | 12 + bin/package.bat | 12 + bin/run.bat | 14 + doc/光惠影环境使用手册.docx | Bin 0 -> 426497 bytes ghy-admin/pom.xml | 134 + .../src/main/java/com/ghy/CodeDetector.java | 201 + .../src/main/java/com/ghy/GhyApplication.java | 30 + .../java/com/ghy/GhyServletInitializer.java | 18 + ghy-admin/src/main/java/com/ghy/Test.java | 65 + .../controller/common/CommonController.java | 156 + .../demo/controller/DemoDialogController.java | 98 + .../demo/controller/DemoFormController.java | 390 + .../demo/controller/DemoIconController.java | 35 + .../controller/DemoOperateController.java | 326 + .../demo/controller/DemoReportController.java | 53 + .../demo/controller/DemoTableController.java | 599 + .../controller/demo/domain/CustomerModel.java | 116 + .../controller/demo/domain/GoodsModel.java | 99 + .../demo/domain/UserOperateModel.java | 152 + .../controller/monitor/CacheController.java | 90 + .../controller/monitor/DruidController.java | 26 + .../controller/monitor/ServerController.java | 31 + .../monitor/SysLogininforController.java | 94 + .../monitor/SysOperlogController.java | 90 + .../monitor/SysUserOnlineController.java | 88 + .../system/SysCaptchaController.java | 92 + .../system/SysConfigController.java | 158 + .../controller/system/SysDeptController.java | 208 + .../system/SysDictDataController.java | 121 + .../system/SysDictTypeController.java | 189 + .../controller/system/SysIndexController.java | 178 + .../controller/system/SysLoginController.java | 82 + .../controller/system/SysMenuController.java | 198 + .../system/SysNoticeController.java | 113 + .../controller/system/SysPostController.java | 163 + .../system/SysProfileController.java | 187 + .../system/SysRegisterController.java | 46 + .../controller/system/SysRoleController.java | 302 + .../controller/system/SysUserController.java | 298 + .../web/controller/tool/BuildController.java | 26 + .../controller/tool/SwaggerController.java | 24 + .../web/controller/tool/TestController.java | 181 + .../ghy/web/core/config/SwaggerConfig.java | 67 + .../src/main/resources/application-druid.yml | 57 + ghy-admin/src/main/resources/application.yml | 142 + ghy-admin/src/main/resources/banner.txt | 24 + .../main/resources/ehcache/ehcache-shiro.xml | 91 + ghy-admin/src/main/resources/logback.xml | 93 + .../main/resources/mybatis/mybatis-config.xml | 20 + .../ajax/libs/beautifyhtml/beautifyhtml.js | 617 + .../ajax/libs/blockUI/jquery.blockUI.js | 620 + .../libs/bootstrap-fileinput/fileinput.css | 671 + .../libs/bootstrap-fileinput/fileinput.js | 6404 ++++++++++ .../bootstrap-fileinput/fileinput.min.css | 12 + .../libs/bootstrap-fileinput/fileinput.min.js | 11 + .../libs/bootstrap-fileinput/loading-sm.gif | Bin 0 -> 2670 bytes .../ajax/libs/bootstrap-fileinput/loading.gif | Bin 0 -> 847 bytes .../bootstrap-select/bootstrap-select.css | 459 + .../libs/bootstrap-select/bootstrap-select.js | 3247 +++++ .../bootstrap-select/bootstrap-select.min.css | 6 + .../bootstrap-select/bootstrap-select.min.js | 8 + .../bootstrap-table/bootstrap-table.min.css | 6 + .../bootstrap-table/bootstrap-table.min.js | 6 + .../bootstrap-table-auto-refresh.js | 93 + .../columns/bootstrap-table-fixed-columns.js | 404 + .../bootstrap-table-custom-view.js | 108 + .../editable/bootstrap-editable.css | 663 + .../editable/bootstrap-editable.min.js | 7 + .../editable/bootstrap-table-editable.js | 187 + .../extensions/editable/clear.png | Bin 0 -> 244 bytes .../extensions/editable/loading.gif | Bin 0 -> 1849 bytes .../export/bootstrap-table-export.js | 333 + .../extensions/export/tableExport.min.js | 92 + .../mobile/bootstrap-table-mobile.js | 124 + .../extensions/print/bootstrap-table-print.js | 284 + .../bootstrap-table-reorder-columns.js | 213 + .../reorder-columns/jquery.dragtable.js | 22 + .../bootstrap-table-reorder-rows.js | 118 + .../reorder-rows/jquery.tablednd.js | 603 + .../resizable/bootstrap-table-resizable.js | 67 + .../resizable/jquery.resizableColumns.min.js | 8 + .../extensions/tree/bootstrap-table-tree.js | 763 ++ .../tree/bootstrap-table-tree.min.js | 5 + .../locale/bootstrap-table-zh-CN.js | 109 + .../locale/bootstrap-table-zh-CN.min.js | 1 + .../static/ajax/libs/cropper/cropper.css | 304 + .../static/ajax/libs/cropper/cropper.js | 3631 ++++++ .../static/ajax/libs/cropper/cropper.min.css | 9 + .../static/ajax/libs/cropper/cropper.min.js | 10 + .../ajax/libs/cxselect/jquery.cxselect.js | 406 + .../ajax/libs/cxselect/jquery.cxselect.min.js | 11 + .../datapicker/bootstrap-datetimepicker.css | 418 + .../datapicker/bootstrap-datetimepicker.js | 1978 +++ .../bootstrap-datetimepicker.min.css | 9 + .../bootstrap-datetimepicker.min.js | 1 + .../duallistbox/bootstrap-duallistbox.css | 86 + .../libs/duallistbox/bootstrap-duallistbox.js | 844 ++ .../duallistbox/bootstrap-duallistbox.min.css | 9 + .../duallistbox/bootstrap-duallistbox.min.js | 10 + .../static/ajax/libs/flot/curvedLines.js | 315 + .../static/ajax/libs/flot/jquery.flot.js | 2599 ++++ .../static/ajax/libs/flot/jquery.flot.pie.js | 750 ++ .../ajax/libs/flot/jquery.flot.resize.js | 60 + .../ajax/libs/flot/jquery.flot.spline.js | 212 + .../ajax/libs/flot/jquery.flot.symbol.js | 71 + .../ajax/libs/flot/jquery.flot.tooltip.min.js | 12 + .../ajax/libs/fullscreen/jquery.fullscreen.js | 182 + .../ajax/libs/highlight/default.min.css | 79 + .../ajax/libs/highlight/highlight.min.js | 1102 ++ .../static/ajax/libs/iCheck/custom.css | 72 + .../static/ajax/libs/iCheck/green-login.png | Bin 0 -> 3785 bytes .../static/ajax/libs/iCheck/green.png | Bin 0 -> 20818 bytes .../static/ajax/libs/iCheck/green@2x.png | Bin 0 -> 7708 bytes .../static/ajax/libs/iCheck/icheck.min.js | 11 + .../ajax/libs/jasny/jasny-bootstrap.css | 620 + .../static/ajax/libs/jasny/jasny-bootstrap.js | 1025 ++ .../ajax/libs/jasny/jasny-bootstrap.min.css | 7 + .../ajax/libs/jasny/jasny-bootstrap.min.js | 6 + .../jquery-layout/jquery.layout-latest.css | 1 + .../jquery-layout/jquery.layout-latest.js | 2 + .../3.5/css/default/img/diy/1_close.png | Bin 0 -> 601 bytes .../3.5/css/default/img/diy/1_open.png | Bin 0 -> 580 bytes .../3.5/css/default/img/diy/2.png | Bin 0 -> 570 bytes .../3.5/css/default/img/diy/3.png | Bin 0 -> 762 bytes .../3.5/css/default/img/diy/4.png | Bin 0 -> 399 bytes .../3.5/css/default/img/diy/5.png | Bin 0 -> 710 bytes .../3.5/css/default/img/diy/6.png | Bin 0 -> 432 bytes .../3.5/css/default/img/diy/7.png | Bin 0 -> 534 bytes .../3.5/css/default/img/diy/8.png | Bin 0 -> 529 bytes .../3.5/css/default/img/diy/9.png | Bin 0 -> 467 bytes .../3.5/css/default/img/line_conn.gif | Bin 0 -> 45 bytes .../3.5/css/default/img/loading.gif | Bin 0 -> 381 bytes .../3.5/css/default/img/zTreeStandard.gif | Bin 0 -> 5564 bytes .../3.5/css/default/img/zTreeStandard.png | Bin 0 -> 11173 bytes .../3.5/css/default/zTreeStyle.css | 102 + .../3.5/css/metro/img/line_conn.gif | Bin 0 -> 45 bytes .../3.5/css/metro/img/line_conn.png | Bin 0 -> 933 bytes .../3.5/css/metro/img/loading.gif | Bin 0 -> 381 bytes .../jquery-ztree/3.5/css/metro/img/metro.gif | Bin 0 -> 3981 bytes .../jquery-ztree/3.5/css/metro/img/metro.png | Bin 0 -> 7273 bytes .../jquery-ztree/3.5/css/metro/zTreeStyle.css | 107 + .../3.5/css/simple/img/left_menu.gif | Bin 0 -> 216 bytes .../3.5/css/simple/img/left_menu.png | Bin 0 -> 421 bytes .../3.5/css/simple/img/line_conn.gif | Bin 0 -> 45 bytes .../3.5/css/simple/img/loading.gif | Bin 0 -> 381 bytes .../3.5/css/simple/img/zTreeStandard.gif | Bin 0 -> 5564 bytes .../3.5/css/simple/img/zTreeStandard.png | Bin 0 -> 11173 bytes .../3.5/css/simple/zTreeStyle.css | 118 + .../3.5/js/jquery.ztree.all-3.5.js | 3820 ++++++ .../3.5/js/jquery.ztree.core-3.5.js | 1650 +++ .../3.5/js/jquery.ztree.excheck-3.5.js | 624 + .../3.5/js/jquery.ztree.exedit-3.5.js | 1178 ++ .../3.5/js/jquery.ztree.exhide-3.5.js | 366 + .../ajax/libs/jquery-ztree/3.5/log v3.x.txt | 170 + .../ajax/libs/jsonview/jquery.jsonview.css | 50 + .../ajax/libs/jsonview/jquery.jsonview.js | 250 + .../static/ajax/libs/layer/layer.min.js | 2 + .../libs/layer/theme/default/icon-ext.png | Bin 0 -> 5911 bytes .../ajax/libs/layer/theme/default/icon.png | Bin 0 -> 11493 bytes .../ajax/libs/layer/theme/default/layer.css | 184 + .../libs/layer/theme/default/loading-0.gif | Bin 0 -> 5793 bytes .../libs/layer/theme/default/loading-1.gif | Bin 0 -> 701 bytes .../libs/layer/theme/default/loading-2.gif | Bin 0 -> 1787 bytes .../ajax/libs/layer/theme/moon/default.png | Bin 0 -> 7563 bytes .../ajax/libs/layer/theme/moon/style.css | 138 + .../modules/laydate/default/font/iconfont.eot | Bin 0 -> 2456 bytes .../modules/laydate/default/font/iconfont.svg | 45 + .../modules/laydate/default/font/iconfont.ttf | Bin 0 -> 2272 bytes .../laydate/default/font/iconfont.woff | Bin 0 -> 1492 bytes .../css/modules/laydate/default/laydate.css | 2 + .../static/ajax/libs/layui/layui.min.js | 2 + .../static/ajax/libs/layui/modules/laydate.js | 2 + .../libs/report/echarts/echarts-all.min.js | 52 + .../libs/report/peity/jquery.peity.min.js | 13 + .../report/sparkline/jquery.sparkline.min.js | 5 + .../libs/select2/select2-bootstrap.min.css | 7 + .../static/ajax/libs/select2/select2.css | 481 + .../static/ajax/libs/select2/select2.js | 6108 +++++++++ .../static/ajax/libs/select2/select2.min.css | 1 + .../static/ajax/libs/select2/select2.min.js | 8 + .../smartwizard/jquery.smartWizard.min.js | 13 + .../libs/smartwizard/smart_wizard_all.min.css | 11 + .../ajax/libs/suggest/bootstrap-suggest.js | 1180 ++ .../libs/suggest/bootstrap-suggest.min.js | 9 + .../ajax/libs/summernote/font/summernote.eot | Bin 0 -> 12072 bytes .../ajax/libs/summernote/font/summernote.ttf | Bin 0 -> 11896 bytes .../ajax/libs/summernote/font/summernote.woff | Bin 0 -> 7428 bytes .../libs/summernote/font/summernote.woff2 | Bin 0 -> 6156 bytes .../ajax/libs/summernote/summernote-zh-CN.js | 155 + .../ajax/libs/summernote/summernote.css | 13 + .../static/ajax/libs/summernote/summernote.js | 10227 ++++++++++++++++ .../ajax/libs/summernote/summernote.min.js | 2 + .../libs/typeahead/bootstrap-typeahead.js | 774 ++ .../libs/typeahead/bootstrap-typeahead.min.js | 1 + .../libs/validate/additional-methods.min.js | 4 + .../libs/validate/jquery.validate.extend.js | 185 + .../ajax/libs/validate/jquery.validate.min.js | 4 + .../static/ajax/libs/validate/messages_zh.js | 25 + .../main/resources/static/css/animate.min.css | 12 + .../resources/static/css/bootstrap.min.css | 5 + .../resources/static/css/font-awesome.min.css | 4 + .../static/css/jquery.contextMenu.min.css | 15 + .../src/main/resources/static/css/login.css | 161 + .../main/resources/static/css/login.min.css | 1 + .../src/main/resources/static/css/skins.css | 1028 ++ .../src/main/resources/static/css/style.css | 7052 +++++++++++ .../main/resources/static/css/style.min.css | 1 + .../resources/static/css/zen-checkbox.css | 149 + .../src/main/resources/static/favicon.ico | Bin 0 -> 16958 bytes .../src/main/resources/static/file/rml.txt | 1 + .../resources/static/fonts/FontAwesome.otf | Bin 0 -> 134808 bytes .../static/fonts/Simple-Line-Icons.woff2 | Bin 0 -> 30064 bytes .../static/fonts/fontawesome-webfont.eot | Bin 0 -> 165742 bytes .../static/fonts/fontawesome-webfont.svg | 2671 ++++ .../static/fonts/fontawesome-webfont.ttf | Bin 0 -> 165548 bytes .../static/fonts/fontawesome-webfont.woff | Bin 0 -> 98024 bytes .../static/fonts/fontawesome-webfont.woff2 | Bin 0 -> 77160 bytes .../fonts/glyphicons-halflings-regular.eot | Bin 0 -> 20127 bytes .../fonts/glyphicons-halflings-regular.svg | 288 + .../fonts/glyphicons-halflings-regular.ttf | Bin 0 -> 45404 bytes .../fonts/glyphicons-halflings-regular.woff | Bin 0 -> 23424 bytes .../fonts/glyphicons-halflings-regular.woff2 | Bin 0 -> 18028 bytes .../main/resources/static/fonts/zenicon.woff | Bin 0 -> 84992 bytes .../src/main/resources/static/html/ie.html | 46 + .../resources/static/i18n/messages.properties | 36 + .../src/main/resources/static/img/blue.png | Bin 0 -> 4088 bytes .../resources/static/img/loading-upload.gif | Bin 0 -> 1688 bytes .../src/main/resources/static/img/loading.gif | Bin 0 -> 2538 bytes .../src/main/resources/static/img/locked.png | Bin 0 -> 1132 bytes .../resources/static/img/login-background.jpg | Bin 0 -> 142718 bytes .../src/main/resources/static/img/pay.png | Bin 0 -> 140720 bytes .../src/main/resources/static/img/profile.jpg | Bin 0 -> 81131 bytes .../main/resources/static/img/progress.png | Bin 0 -> 1269 bytes .../src/main/resources/static/img/qr_code.png | Bin 0 -> 8602 bytes .../src/main/resources/static/img/user.png | Bin 0 -> 1106 bytes .../main/resources/static/js/bootstrap.min.js | 6 + .../src/main/resources/static/js/cron.js | 926 ++ .../static/js/jquery-ui-1.10.4.min.js | 12 + .../static/js/jquery.contextMenu.min.js | 1 + .../static/js/jquery.i18n.properties.min.js | 9 + .../main/resources/static/js/jquery.min.js | 2 + .../main/resources/static/js/jquery.tmpl.js | 492 + .../js/plugins/metisMenu/jquery.metisMenu.js | 120 + .../slimscroll/jquery.slimscroll.min.js | 8 + .../main/resources/static/js/resize-tabs.js | 1 + .../src/main/resources/static/js/three.min.js | 767 ++ ghy-admin/src/main/resources/static/ruoyi.png | Bin 0 -> 5645 bytes .../main/resources/static/ruoyi/css/ry-ui.css | 1179 ++ .../src/main/resources/static/ruoyi/index.js | 649 + .../main/resources/static/ruoyi/js/common.js | 546 + .../main/resources/static/ruoyi/js/ry-ui.js | 1742 +++ .../src/main/resources/static/ruoyi/login.js | 95 + .../main/resources/static/ruoyi/register.js | 82 + .../templates/demo/form/autocomplete.html | 323 + .../resources/templates/demo/form/basic.html | 593 + .../resources/templates/demo/form/button.html | 620 + .../resources/templates/demo/form/cards.html | 319 + .../templates/demo/form/cxselect.html | 161 + .../templates/demo/form/datetime.html | 236 + .../templates/demo/form/duallistbox.html | 65 + .../resources/templates/demo/form/grid.html | 432 + .../templates/demo/form/invoice.html | 122 + .../resources/templates/demo/form/jasny.html | 118 + .../templates/demo/form/labels_tips.html | 237 + .../templates/demo/form/localrefresh.html | 61 + .../resources/templates/demo/form/select.html | 148 + .../templates/demo/form/sortable.html | 198 + .../templates/demo/form/summernote.html | 93 + .../templates/demo/form/tabs_panels.html | 353 + .../templates/demo/form/timeline.html | 113 + .../resources/templates/demo/form/upload.html | 71 + .../templates/demo/form/validate.html | 193 + .../resources/templates/demo/form/wizard.html | 339 + .../templates/demo/icon/fontawesome.html | 1944 +++ .../templates/demo/icon/glyphicons.html | 1364 +++ .../templates/demo/modal/dialog.html | 215 + .../resources/templates/demo/modal/form.html | 102 + .../resources/templates/demo/modal/layer.html | 288 + .../resources/templates/demo/modal/table.html | 124 + .../templates/demo/modal/table/check.html | 86 + .../templates/demo/modal/table/frame1.html | 53 + .../templates/demo/modal/table/frame2.html | 24 + .../templates/demo/modal/table/parent.html | 102 + .../templates/demo/modal/table/radio.html | 86 + .../resources/templates/demo/operate/add.html | 78 + .../templates/demo/operate/detail.html | 71 + .../templates/demo/operate/edit.html | 79 + .../templates/demo/operate/other.html | 77 + .../templates/demo/operate/table.html | 125 + .../templates/demo/report/echarts.html | 1264 ++ .../templates/demo/report/metrics.html | 478 + .../templates/demo/report/peity.html | 206 + .../templates/demo/report/sparkline.html | 232 + .../templates/demo/table/button.html | 92 + .../resources/templates/demo/table/child.html | 116 + .../resources/templates/demo/table/curd.html | 178 + .../templates/demo/table/customView.html | 122 + .../resources/templates/demo/table/data.html | 76 + .../templates/demo/table/detail.html | 86 + .../templates/demo/table/dynamicColumns.html | 123 + .../templates/demo/table/editable.html | 128 + .../resources/templates/demo/table/event.html | 133 + .../templates/demo/table/export.html | 85 + .../templates/demo/table/exportSelected.html | 120 + .../templates/demo/table/fixedColumns.html | 145 + .../templates/demo/table/footer.html | 95 + .../templates/demo/table/groupHeader.html | 80 + .../templates/demo/table/headerStyle.html | 91 + .../resources/templates/demo/table/image.html | 79 + .../resources/templates/demo/table/multi.html | 224 + .../resources/templates/demo/table/other.html | 106 + .../templates/demo/table/pageGo.html | 77 + .../templates/demo/table/params.html | 158 + .../resources/templates/demo/table/print.html | 131 + .../templates/demo/table/refresh.html | 79 + .../templates/demo/table/remember.html | 86 + .../templates/demo/table/reorderColumns.html | 84 + .../templates/demo/table/reorderRows.html | 88 + .../templates/demo/table/resizable.html | 78 + .../templates/demo/table/search.html | 202 + .../templates/demo/table/subdata.html | 219 + .../main/resources/templates/error/404.html | 27 + .../main/resources/templates/error/500.html | 28 + .../resources/templates/error/service.html | 20 + .../resources/templates/error/unauth.html | 28 + .../src/main/resources/templates/include.html | 222 + .../resources/templates/index-topnav.html | 442 + .../src/main/resources/templates/index.html | 377 + .../src/main/resources/templates/lock.html | 208 + .../src/main/resources/templates/login.html | 82 + .../src/main/resources/templates/main.html | 1464 +++ .../src/main/resources/templates/main_v1.html | 336 + .../templates/monitor/cache/cache.html | 184 + .../monitor/logininfor/logininfor.html | 133 + .../templates/monitor/online/online.html | 152 + .../templates/monitor/operlog/detail.html | 74 + .../templates/monitor/operlog/operlog.html | 169 + .../templates/monitor/server/server.html | 254 + .../main/resources/templates/register.html | 80 + .../src/main/resources/templates/skin.html | 165 + .../templates/system/config/add.html | 82 + .../templates/system/config/config.html | 144 + .../templates/system/config/edit.html | 86 + .../resources/templates/system/dept/add.html | 133 + .../resources/templates/system/dept/dept.html | 112 + .../resources/templates/system/dept/edit.html | 141 + .../resources/templates/system/dept/tree.html | 52 + .../templates/system/dict/data/add.html | 100 + .../templates/system/dict/data/data.html | 151 + .../templates/system/dict/data/edit.html | 101 + .../templates/system/dict/type/add.html | 77 + .../templates/system/dict/type/edit.html | 81 + .../templates/system/dict/type/tree.html | 42 + .../templates/system/dict/type/type.html | 148 + .../resources/templates/system/menu/add.html | 202 + .../resources/templates/system/menu/edit.html | 230 + .../resources/templates/system/menu/icon.html | 928 ++ .../resources/templates/system/menu/menu.html | 161 + .../resources/templates/system/menu/tree.html | 49 + .../templates/system/notice/add.html | 98 + .../templates/system/notice/edit.html | 103 + .../templates/system/notice/notice.html | 117 + .../resources/templates/system/post/add.html | 103 + .../resources/templates/system/post/edit.html | 110 + .../resources/templates/system/post/post.html | 120 + .../resources/templates/system/role/add.html | 180 + .../templates/system/role/authUser.html | 142 + .../templates/system/role/dataScope.html | 137 + .../resources/templates/system/role/edit.html | 189 + .../resources/templates/system/role/role.html | 169 + .../templates/system/role/selectUser.html | 113 + .../resources/templates/system/user/add.html | 268 + .../templates/system/user/authRole.html | 109 + .../resources/templates/system/user/edit.html | 232 + .../templates/system/user/profile/avatar.html | 261 + .../system/user/profile/profile.html | 304 + .../system/user/profile/resetPwd.html | 104 + .../templates/system/user/resetPwd.html | 45 + .../resources/templates/system/user/user.html | 282 + .../resources/templates/tool/build/build.html | 168 + ghy-admin/src/main/resources/test1.zip | Bin 0 -> 321240 bytes ghy-admin/src/main/resources/test1/1.jpg | Bin 0 -> 179100 bytes ghy-admin/src/main/resources/test1/1.xls | Bin 0 -> 30720 bytes ghy-admin/src/main/resources/test1/2.jpg | Bin 0 -> 153188 bytes ghy-common/pom.xml | 106 + .../com/ghy/common/annotation/DataScope.java | 28 + .../com/ghy/common/annotation/DataSource.java | 28 + .../java/com/ghy/common/annotation/Excel.java | 176 + .../com/ghy/common/annotation/Excels.java | 18 + .../java/com/ghy/common/annotation/Log.java | 45 + .../ghy/common/annotation/RepeatSubmit.java | 29 + .../java/com/ghy/common/config/GhyConfig.java | 124 + .../com/ghy/common/config/ServerConfig.java | 33 + .../DynamicDataSourceContextHolder.java | 45 + .../config/thread/ThreadPoolConfig.java | 62 + .../com/ghy/common/constant/Constants.java | 115 + .../com/ghy/common/constant/GenConstants.java | 111 + .../common/constant/PermissionConstants.java | 27 + .../common/constant/ScheduleConstants.java | 50 + .../ghy/common/constant/ShiroConstants.java | 79 + .../ghy/common/constant/UserConstants.java | 110 + .../core/controller/BaseController.java | 221 + .../ghy/common/core/domain/AjaxResult.java | 196 + .../ghy/common/core/domain/BaseEntity.java | 114 + .../com/ghy/common/core/domain/CxSelect.java | 69 + .../ghy/common/core/domain/TreeEntity.java | 63 + .../com/ghy/common/core/domain/Ztree.java | 104 + .../common/core/domain/entity/SysDept.java | 202 + .../core/domain/entity/SysDictData.java | 176 + .../core/domain/entity/SysDictType.java | 93 + .../common/core/domain/entity/SysMenu.java | 214 + .../common/core/domain/entity/SysRole.java | 197 + .../common/core/domain/entity/SysUser.java | 384 + .../com/ghy/common/core/page/PageDomain.java | 89 + .../ghy/common/core/page/TableDataInfo.java | 85 + .../ghy/common/core/page/TableSupport.java | 55 + .../com/ghy/common/core/text/CharsetKit.java | 86 + .../com/ghy/common/core/text/Convert.java | 1005 ++ .../ghy/common/core/text/StrFormatter.java | 92 + .../com/ghy/common/enums/BusinessStatus.java | 19 + .../com/ghy/common/enums/BusinessType.java | 59 + .../com/ghy/common/enums/DataSourceType.java | 19 + .../com/ghy/common/enums/OnlineStatus.java | 24 + .../com/ghy/common/enums/OperatorType.java | 24 + .../java/com/ghy/common/enums/UserStatus.java | 30 + .../common/exception/DemoModeException.java | 15 + .../ghy/common/exception/GlobalException.java | 58 + .../common/exception/ServiceException.java | 57 + .../ghy/common/exception/UtilException.java | 26 + .../common/exception/base/BaseException.java | 97 + .../common/exception/file/FileException.java | 19 + .../FileNameLengthLimitExceededException.java | 16 + .../file/FileSizeLimitExceededException.java | 16 + .../file/InvalidExtensionException.java | 81 + .../common/exception/job/TaskException.java | 34 + .../exception/user/CaptchaException.java | 16 + .../exception/user/RoleBlockedException.java | 16 + .../exception/user/UserBlockedException.java | 16 + .../exception/user/UserDeleteException.java | 16 + .../common/exception/user/UserException.java | 18 + .../user/UserNotExistsException.java | 16 + .../user/UserPasswordNotMatchException.java | 16 + .../UserPasswordRetryLimitCountException.java | 16 + ...UserPasswordRetryLimitExceedException.java | 16 + .../main/java/com/ghy/common/json/JSON.java | 187 + .../java/com/ghy/common/json/JSONObject.java | 749 ++ .../com/ghy/common/utils/AddressUtils.java | 55 + .../main/java/com/ghy/common/utils/Arith.java | 114 + .../java/com/ghy/common/utils/CacheUtils.java | 197 + .../com/ghy/common/utils/CookieUtils.java | 138 + .../java/com/ghy/common/utils/DateUtils.java | 163 + .../java/com/ghy/common/utils/DictUtils.java | 191 + .../com/ghy/common/utils/ExceptionUtil.java | 40 + .../java/com/ghy/common/utils/IpUtils.java | 194 + .../java/com/ghy/common/utils/LogUtils.java | 135 + .../com/ghy/common/utils/MapDataUtil.java | 54 + .../com/ghy/common/utils/MessageUtils.java | 26 + .../java/com/ghy/common/utils/PageUtils.java | 30 + .../com/ghy/common/utils/ServletUtils.java | 180 + .../java/com/ghy/common/utils/ShiroUtils.java | 86 + .../com/ghy/common/utils/StringUtils.java | 555 + .../java/com/ghy/common/utils/Threads.java | 99 + .../java/com/ghy/common/utils/YamlUtil.java | 87 + .../com/ghy/common/utils/bean/BeanUtils.java | 110 + .../ghy/common/utils/bean/BeanValidators.java | 24 + .../ghy/common/utils/file/FileTypeUtils.java | 76 + .../common/utils/file/FileUploadUtils.java | 234 + .../com/ghy/common/utils/file/FileUtils.java | 256 + .../com/ghy/common/utils/file/ImageUtils.java | 101 + .../ghy/common/utils/file/MimeTypeUtils.java | 59 + .../com/ghy/common/utils/html/EscapeUtil.java | 167 + .../com/ghy/common/utils/html/HTMLFilter.java | 570 + .../com/ghy/common/utils/http/HttpUtils.java | 274 + .../common/utils/poi/ExcelHandlerAdapter.java | 19 + .../com/ghy/common/utils/poi/ExcelUtil.java | 1389 +++ .../common/utils/reflect/ReflectUtils.java | 410 + .../common/utils/security/CipherUtils.java | 36 + .../ghy/common/utils/security/Md5Utils.java | 66 + .../utils/security/PermissionUtils.java | 118 + .../ghy/common/utils/spring/SpringUtils.java | 146 + .../com/ghy/common/utils/sql/SqlUtil.java | 61 + .../com/ghy/common/utils/uuid/IdUtils.java | 49 + .../java/com/ghy/common/utils/uuid/UUID.java | 484 + .../src/main/java/com/ghy/common/xss/Xss.java | 27 + .../java/com/ghy/common/xss/XssFilter.java | 74 + .../xss/XssHttpServletRequestWrapper.java | 39 + .../java/com/ghy/common/xss/XssValidator.java | 29 + ghy-framework/pom.xml | 82 + .../framework/aspectj/DataScopeAspect.java | 148 + .../framework/aspectj/DataSourceAspect.java | 72 + .../com/ghy/framework/aspectj/LogAspect.java | 242 + .../framework/config/ApplicationConfig.java | 20 + .../ghy/framework/config/CaptchaConfig.java | 83 + .../com/ghy/framework/config/DruidConfig.java | 128 + .../ghy/framework/config/FilterConfig.java | 44 + .../com/ghy/framework/config/I18nConfig.java | 43 + .../framework/config/KaptchaTextCreator.java | 76 + .../ghy/framework/config/MyBatisConfig.java | 132 + .../ghy/framework/config/ResourcesConfig.java | 58 + .../com/ghy/framework/config/ShiroConfig.java | 415 + .../config/properties/DruidProperties.java | 77 + .../datasource/DynamicDataSource.java | 27 + .../interceptor/RepeatSubmitInterceptor.java | 55 + .../impl/SameUrlDataInterceptor.java | 83 + .../ghy/framework/manager/AsyncManager.java | 55 + .../framework/manager/ShutdownManager.java | 87 + .../manager/factory/AsyncFactory.java | 136 + .../ghy/framework/shiro/realm/UserRealm.java | 158 + .../shiro/service/SysLoginService.java | 144 + .../shiro/service/SysPasswordService.java | 85 + .../shiro/service/SysRegisterService.java | 83 + .../shiro/service/SysShiroService.java | 62 + .../shiro/session/OnlineSession.java | 165 + .../shiro/session/OnlineSessionDAO.java | 117 + .../shiro/session/OnlineSessionFactory.java | 43 + .../shiro/util/AuthorizationUtils.java | 30 + .../shiro/web/filter/LogoutFilter.java | 90 + .../filter/captcha/CaptchaValidateFilter.java | 79 + .../filter/kickout/KickoutSessionFilter.java | 176 + .../filter/online/OnlineSessionFilter.java | 99 + .../filter/sync/SyncOnlineSessionFilter.java | 39 + .../web/session/OnlineWebSessionManager.java | 175 + .../SpringSessionValidationScheduler.java | 131 + .../com/ghy/framework/web/domain/Server.java | 241 + .../ghy/framework/web/domain/server/Cpu.java | 101 + .../ghy/framework/web/domain/server/Jvm.java | 122 + .../ghy/framework/web/domain/server/Mem.java | 61 + .../ghy/framework/web/domain/server/Sys.java | 84 + .../framework/web/domain/server/SysFile.java | 114 + .../web/exception/GlobalExceptionHandler.java | 116 + .../framework/web/service/CacheService.java | 83 + .../framework/web/service/ConfigService.java | 28 + .../framework/web/service/DictService.java | 46 + .../web/service/PermissionService.java | 262 + ghy-generator/pom.xml | 40 + .../com/ghy/generator/config/GenConfig.java | 73 + .../generator/controller/GenController.java | 304 + .../com/ghy/generator/domain/GenTable.java | 372 + .../ghy/generator/domain/GenTableColumn.java | 373 + .../mapper/GenTableColumnMapper.java | 60 + .../ghy/generator/mapper/GenTableMapper.java | 91 + .../service/IGenTableColumnService.java | 44 + .../generator/service/IGenTableService.java | 129 + .../impl/GenTableColumnServiceImpl.java | 69 + .../service/impl/GenTableServiceImpl.java | 514 + .../java/com/ghy/generator/util/GenUtils.java | 253 + .../generator/util/VelocityInitializer.java | 34 + .../com/ghy/generator/util/VelocityUtils.java | 385 + .../src/main/resources/generator.yml | 11 + .../mapper/generator/GenTableColumnMapper.xml | 127 + .../mapper/generator/GenTableMapper.xml | 194 + .../templates/tool/gen/createTable.html | 30 + .../resources/templates/tool/gen/edit.html | 607 + .../resources/templates/tool/gen/gen.html | 218 + .../templates/tool/gen/importTable.html | 95 + .../src/main/resources/vm/html/add.html.vm | 381 + .../src/main/resources/vm/html/edit.html.vm | 392 + .../main/resources/vm/html/list-tree.html.vm | 156 + .../src/main/resources/vm/html/list.html.vm | 154 + .../src/main/resources/vm/html/tree.html.vm | 51 + .../main/resources/vm/java/controller.java.vm | 202 + .../src/main/resources/vm/java/domain.java.vm | 105 + .../src/main/resources/vm/java/mapper.java.vm | 91 + .../main/resources/vm/java/service.java.vm | 73 + .../resources/vm/java/serviceImpl.java.vm | 213 + .../main/resources/vm/java/sub-domain.java.vm | 76 + .../src/main/resources/vm/sql/sql.vm | 22 + .../src/main/resources/vm/xml/mapper.xml.vm | 147 + ghy-quartz/pom.xml | 40 + .../com/ghy/quartz/config/ScheduleConfig.java | 57 + .../quartz/controller/SysJobController.java | 247 + .../controller/SysJobLogController.java | 103 + .../java/com/ghy/quartz/domain/SysJob.java | 169 + .../java/com/ghy/quartz/domain/SysJobLog.java | 155 + .../ghy/quartz/mapper/SysJobLogMapper.java | 64 + .../com/ghy/quartz/mapper/SysJobMapper.java | 67 + .../ghy/quartz/service/ISysJobLogService.java | 56 + .../ghy/quartz/service/ISysJobService.java | 102 + .../service/impl/SysJobLogServiceImpl.java | 88 + .../service/impl/SysJobServiceImpl.java | 256 + .../main/java/com/ghy/quartz/task/RyTask.java | 28 + .../ghy/quartz/util/AbstractQuartzJob.java | 107 + .../java/com/ghy/quartz/util/CronUtils.java | 94 + .../com/ghy/quartz/util/JobInvokeUtil.java | 182 + .../QuartzDisallowConcurrentExecution.java | 21 + .../ghy/quartz/util/QuartzJobExecution.java | 19 + .../com/ghy/quartz/util/ScheduleUtils.java | 135 + .../mapper/quartz/SysJobLogMapper.xml | 93 + .../resources/mapper/quartz/SysJobMapper.xml | 111 + .../resources/templates/monitor/job/add.html | 109 + .../resources/templates/monitor/job/cron.html | 1172 ++ .../templates/monitor/job/detail.html | 99 + .../resources/templates/monitor/job/edit.html | 111 + .../resources/templates/monitor/job/job.html | 198 + .../templates/monitor/job/jobLog.html | 138 + ghy-system/pom.xml | 28 + .../java/com/ghy/system/domain/SysConfig.java | 110 + .../com/ghy/system/domain/SysLogininfor.java | 159 + .../java/com/ghy/system/domain/SysNotice.java | 102 + .../com/ghy/system/domain/SysOperLog.java | 277 + .../java/com/ghy/system/domain/SysPost.java | 122 + .../com/ghy/system/domain/SysRoleDept.java | 46 + .../com/ghy/system/domain/SysRoleMenu.java | 46 + .../com/ghy/system/domain/SysUserOnline.java | 177 + .../com/ghy/system/domain/SysUserPost.java | 46 + .../com/ghy/system/domain/SysUserRole.java | 46 + .../ghy/system/mapper/SysConfigMapper.java | 68 + .../com/ghy/system/mapper/SysDeptMapper.java | 117 + .../ghy/system/mapper/SysDictDataMapper.java | 95 + .../ghy/system/mapper/SysDictTypeMapper.java | 83 + .../system/mapper/SysLogininforMapper.java | 42 + .../com/ghy/system/mapper/SysMenuMapper.java | 124 + .../ghy/system/mapper/SysNoticeMapper.java | 52 + .../ghy/system/mapper/SysOperLogMapper.java | 48 + .../com/ghy/system/mapper/SysPostMapper.java | 83 + .../ghy/system/mapper/SysRoleDeptMapper.java | 44 + .../com/ghy/system/mapper/SysRoleMapper.java | 84 + .../ghy/system/mapper/SysRoleMenuMapper.java | 44 + .../com/ghy/system/mapper/SysUserMapper.java | 124 + .../system/mapper/SysUserOnlineMapper.java | 52 + .../ghy/system/mapper/SysUserPostMapper.java | 44 + .../ghy/system/mapper/SysUserRoleMapper.java | 70 + .../ghy/system/service/ISysConfigService.java | 83 + .../ghy/system/service/ISysDeptService.java | 117 + .../system/service/ISysDictDataService.java | 61 + .../system/service/ISysDictTypeService.java | 109 + .../system/service/ISysLogininforService.java | 40 + .../ghy/system/service/ISysMenuService.java | 131 + .../ghy/system/service/ISysNoticeService.java | 52 + .../system/service/ISysOperLogService.java | 48 + .../ghy/system/service/ISysPostService.java | 92 + .../ghy/system/service/ISysRoleService.java | 166 + .../system/service/ISysUserOnlineService.java | 75 + .../ghy/system/service/ISysUserService.java | 214 + .../service/impl/SysConfigServiceImpl.java | 214 + .../service/impl/SysDeptServiceImpl.java | 335 + .../service/impl/SysDictDataServiceImpl.java | 114 + .../service/impl/SysDictTypeServiceImpl.java | 257 + .../impl/SysLogininforServiceImpl.java | 66 + .../service/impl/SysMenuServiceImpl.java | 389 + .../service/impl/SysNoticeServiceImpl.java | 82 + .../service/impl/SysOperLogServiceImpl.java | 77 + .../service/impl/SysPostServiceImpl.java | 181 + .../service/impl/SysRoleServiceImpl.java | 414 + .../impl/SysUserOnlineServiceImpl.java | 141 + .../service/impl/SysUserServiceImpl.java | 549 + .../mapper/system/SysConfigMapper.xml | 112 + .../resources/mapper/system/SysDeptMapper.xml | 158 + .../mapper/system/SysDictDataMapper.xml | 123 + .../mapper/system/SysDictTypeMapper.xml | 105 + .../mapper/system/SysLogininforMapper.xml | 56 + .../resources/mapper/system/SysMenuMapper.xml | 184 + .../mapper/system/SysNoticeMapper.xml | 85 + .../mapper/system/SysOperLogMapper.xml | 82 + .../resources/mapper/system/SysPostMapper.xml | 110 + .../mapper/system/SysRoleDeptMapper.xml | 34 + .../resources/mapper/system/SysRoleMapper.xml | 134 + .../mapper/system/SysRoleMenuMapper.xml | 34 + .../resources/mapper/system/SysUserMapper.xml | 230 + .../mapper/system/SysUserOnlineMapper.xml | 57 + .../mapper/system/SysUserPostMapper.xml | 34 + .../mapper/system/SysUserRoleMapper.xml | 48 + pom.xml | 287 + ry.bat | 67 + ry.sh | 86 + sql/quartz.sql | 174 + sql/ruoyi.html | 2890 +++++ sql/ruoyi.pdm | 4851 ++++++++ sql/ry_20210924.sql | 713 ++ 670 files changed, 154787 insertions(+) create mode 100644 LICENSE create mode 100644 bin/clean.bat create mode 100644 bin/package.bat create mode 100644 bin/run.bat create mode 100644 doc/光惠影环境使用手册.docx create mode 100644 ghy-admin/pom.xml create mode 100644 ghy-admin/src/main/java/com/ghy/CodeDetector.java create mode 100644 ghy-admin/src/main/java/com/ghy/GhyApplication.java create mode 100644 ghy-admin/src/main/java/com/ghy/GhyServletInitializer.java create mode 100644 ghy-admin/src/main/java/com/ghy/Test.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/common/CommonController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoDialogController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoFormController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoIconController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoOperateController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoReportController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoTableController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/CustomerModel.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/GoodsModel.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/UserOperateModel.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/CacheController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/DruidController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/ServerController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysLogininforController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysOperlogController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysUserOnlineController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysCaptchaController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysConfigController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysDeptController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictDataController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictTypeController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysIndexController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysLoginController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysMenuController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysNoticeController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysPostController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysProfileController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysRegisterController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysRoleController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/system/SysUserController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/tool/BuildController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/tool/SwaggerController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/controller/tool/TestController.java create mode 100644 ghy-admin/src/main/java/com/ghy/web/core/config/SwaggerConfig.java create mode 100644 ghy-admin/src/main/resources/application-druid.yml create mode 100644 ghy-admin/src/main/resources/application.yml create mode 100644 ghy-admin/src/main/resources/banner.txt create mode 100644 ghy-admin/src/main/resources/ehcache/ehcache-shiro.xml create mode 100644 ghy-admin/src/main/resources/logback.xml create mode 100644 ghy-admin/src/main/resources/mybatis/mybatis-config.xml create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-table-editable.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/clear.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/loading.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/export/bootstrap-table-export.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/export/tableExport.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/mobile/bootstrap-table-mobile.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/print/bootstrap-table-print.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/reorder-columns/bootstrap-table-reorder-columns.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/reorder-columns/jquery.dragtable.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/reorder-rows/bootstrap-table-reorder-rows.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/reorder-rows/jquery.tablednd.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/resizable/bootstrap-table-resizable.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/resizable/jquery.resizableColumns.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/tree/bootstrap-table-tree.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/locale/bootstrap-table-zh-CN.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cropper/cropper.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cropper/cropper.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cropper/cropper.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cropper/cropper.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cxselect/jquery.cxselect.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/cxselect/jquery.cxselect.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/datapicker/bootstrap-datetimepicker.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/datapicker/bootstrap-datetimepicker.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/datapicker/bootstrap-datetimepicker.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/datapicker/bootstrap-datetimepicker.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/duallistbox/bootstrap-duallistbox.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/duallistbox/bootstrap-duallistbox.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/duallistbox/bootstrap-duallistbox.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/duallistbox/bootstrap-duallistbox.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/curvedLines.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.pie.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.resize.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.spline.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.symbol.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/flot/jquery.flot.tooltip.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/fullscreen/jquery.fullscreen.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/highlight/default.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/highlight/highlight.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/iCheck/custom.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/iCheck/green-login.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/iCheck/green.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/iCheck/green@2x.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/iCheck/icheck.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jasny/jasny-bootstrap.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jasny/jasny-bootstrap.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jasny/jasny-bootstrap.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jasny/jasny-bootstrap.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-layout/jquery.layout-latest.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-layout/jquery.layout-latest.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/1_close.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/1_open.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/2.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/3.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/4.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/5.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/6.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/7.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/8.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/diy/9.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/line_conn.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/loading.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/zTreeStandard.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/img/zTreeStandard.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/default/zTreeStyle.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/img/line_conn.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/img/line_conn.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/img/loading.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/img/metro.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/img/metro.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/metro/zTreeStyle.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/left_menu.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/left_menu.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/line_conn.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/loading.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/zTreeStandard.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/img/zTreeStandard.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/css/simple/zTreeStyle.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.all-3.5.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.core-3.5.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.excheck-3.5.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.exedit-3.5.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/js/jquery.ztree.exhide-3.5.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jquery-ztree/3.5/log v3.x.txt create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jsonview/jquery.jsonview.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/jsonview/jquery.jsonview.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/layer.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/icon-ext.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/icon.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/layer.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/loading-0.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/loading-1.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/default/loading-2.gif create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/moon/default.png create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layer/theme/moon/style.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/css/modules/laydate/default/font/iconfont.eot create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/css/modules/laydate/default/font/iconfont.svg create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/css/modules/laydate/default/font/iconfont.ttf create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/css/modules/laydate/default/font/iconfont.woff create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/css/modules/laydate/default/laydate.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/layui.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/layui/modules/laydate.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/report/echarts/echarts-all.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/report/peity/jquery.peity.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/report/sparkline/jquery.sparkline.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/select2/select2-bootstrap.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/select2/select2.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/select2/select2.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/select2/select2.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/select2/select2.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/smartwizard/jquery.smartWizard.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/smartwizard/smart_wizard_all.min.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/suggest/bootstrap-suggest.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/suggest/bootstrap-suggest.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/font/summernote.eot create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/font/summernote.ttf create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/font/summernote.woff create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/font/summernote.woff2 create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/summernote-zh-CN.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/summernote.css create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/summernote.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/summernote/summernote.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/typeahead/bootstrap-typeahead.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/typeahead/bootstrap-typeahead.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/validate/additional-methods.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/validate/jquery.validate.extend.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/validate/jquery.validate.min.js create mode 100644 ghy-admin/src/main/resources/static/ajax/libs/validate/messages_zh.js create mode 100644 ghy-admin/src/main/resources/static/css/animate.min.css create mode 100644 ghy-admin/src/main/resources/static/css/bootstrap.min.css create mode 100644 ghy-admin/src/main/resources/static/css/font-awesome.min.css create mode 100644 ghy-admin/src/main/resources/static/css/jquery.contextMenu.min.css create mode 100644 ghy-admin/src/main/resources/static/css/login.css create mode 100644 ghy-admin/src/main/resources/static/css/login.min.css create mode 100644 ghy-admin/src/main/resources/static/css/skins.css create mode 100644 ghy-admin/src/main/resources/static/css/style.css create mode 100644 ghy-admin/src/main/resources/static/css/style.min.css create mode 100644 ghy-admin/src/main/resources/static/css/zen-checkbox.css create mode 100644 ghy-admin/src/main/resources/static/favicon.ico create mode 100644 ghy-admin/src/main/resources/static/file/rml.txt create mode 100644 ghy-admin/src/main/resources/static/fonts/FontAwesome.otf create mode 100644 ghy-admin/src/main/resources/static/fonts/Simple-Line-Icons.woff2 create mode 100644 ghy-admin/src/main/resources/static/fonts/fontawesome-webfont.eot create mode 100644 ghy-admin/src/main/resources/static/fonts/fontawesome-webfont.svg create mode 100644 ghy-admin/src/main/resources/static/fonts/fontawesome-webfont.ttf create mode 100644 ghy-admin/src/main/resources/static/fonts/fontawesome-webfont.woff create mode 100644 ghy-admin/src/main/resources/static/fonts/fontawesome-webfont.woff2 create mode 100644 ghy-admin/src/main/resources/static/fonts/glyphicons-halflings-regular.eot create mode 100644 ghy-admin/src/main/resources/static/fonts/glyphicons-halflings-regular.svg create mode 100644 ghy-admin/src/main/resources/static/fonts/glyphicons-halflings-regular.ttf create mode 100644 ghy-admin/src/main/resources/static/fonts/glyphicons-halflings-regular.woff create mode 100644 ghy-admin/src/main/resources/static/fonts/glyphicons-halflings-regular.woff2 create mode 100644 ghy-admin/src/main/resources/static/fonts/zenicon.woff create mode 100644 ghy-admin/src/main/resources/static/html/ie.html create mode 100644 ghy-admin/src/main/resources/static/i18n/messages.properties create mode 100644 ghy-admin/src/main/resources/static/img/blue.png create mode 100644 ghy-admin/src/main/resources/static/img/loading-upload.gif create mode 100644 ghy-admin/src/main/resources/static/img/loading.gif create mode 100644 ghy-admin/src/main/resources/static/img/locked.png create mode 100644 ghy-admin/src/main/resources/static/img/login-background.jpg create mode 100644 ghy-admin/src/main/resources/static/img/pay.png create mode 100644 ghy-admin/src/main/resources/static/img/profile.jpg create mode 100644 ghy-admin/src/main/resources/static/img/progress.png create mode 100644 ghy-admin/src/main/resources/static/img/qr_code.png create mode 100644 ghy-admin/src/main/resources/static/img/user.png create mode 100644 ghy-admin/src/main/resources/static/js/bootstrap.min.js create mode 100644 ghy-admin/src/main/resources/static/js/cron.js create mode 100644 ghy-admin/src/main/resources/static/js/jquery-ui-1.10.4.min.js create mode 100644 ghy-admin/src/main/resources/static/js/jquery.contextMenu.min.js create mode 100644 ghy-admin/src/main/resources/static/js/jquery.i18n.properties.min.js create mode 100644 ghy-admin/src/main/resources/static/js/jquery.min.js create mode 100644 ghy-admin/src/main/resources/static/js/jquery.tmpl.js create mode 100644 ghy-admin/src/main/resources/static/js/plugins/metisMenu/jquery.metisMenu.js create mode 100644 ghy-admin/src/main/resources/static/js/plugins/slimscroll/jquery.slimscroll.min.js create mode 100644 ghy-admin/src/main/resources/static/js/resize-tabs.js create mode 100644 ghy-admin/src/main/resources/static/js/three.min.js create mode 100644 ghy-admin/src/main/resources/static/ruoyi.png create mode 100644 ghy-admin/src/main/resources/static/ruoyi/css/ry-ui.css create mode 100644 ghy-admin/src/main/resources/static/ruoyi/index.js create mode 100644 ghy-admin/src/main/resources/static/ruoyi/js/common.js create mode 100644 ghy-admin/src/main/resources/static/ruoyi/js/ry-ui.js create mode 100644 ghy-admin/src/main/resources/static/ruoyi/login.js create mode 100644 ghy-admin/src/main/resources/static/ruoyi/register.js create mode 100644 ghy-admin/src/main/resources/templates/demo/form/autocomplete.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/basic.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/button.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/cards.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/cxselect.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/datetime.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/duallistbox.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/grid.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/invoice.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/jasny.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/labels_tips.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/localrefresh.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/select.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/sortable.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/summernote.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/tabs_panels.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/timeline.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/upload.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/validate.html create mode 100644 ghy-admin/src/main/resources/templates/demo/form/wizard.html create mode 100644 ghy-admin/src/main/resources/templates/demo/icon/fontawesome.html create mode 100644 ghy-admin/src/main/resources/templates/demo/icon/glyphicons.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/dialog.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/form.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/layer.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table/check.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table/frame1.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table/frame2.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table/parent.html create mode 100644 ghy-admin/src/main/resources/templates/demo/modal/table/radio.html create mode 100644 ghy-admin/src/main/resources/templates/demo/operate/add.html create mode 100644 ghy-admin/src/main/resources/templates/demo/operate/detail.html create mode 100644 ghy-admin/src/main/resources/templates/demo/operate/edit.html create mode 100644 ghy-admin/src/main/resources/templates/demo/operate/other.html create mode 100644 ghy-admin/src/main/resources/templates/demo/operate/table.html create mode 100644 ghy-admin/src/main/resources/templates/demo/report/echarts.html create mode 100644 ghy-admin/src/main/resources/templates/demo/report/metrics.html create mode 100644 ghy-admin/src/main/resources/templates/demo/report/peity.html create mode 100644 ghy-admin/src/main/resources/templates/demo/report/sparkline.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/button.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/child.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/curd.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/customView.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/data.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/detail.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/dynamicColumns.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/editable.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/event.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/export.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/exportSelected.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/fixedColumns.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/footer.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/groupHeader.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/headerStyle.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/image.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/multi.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/other.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/pageGo.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/params.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/print.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/refresh.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/remember.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/reorderColumns.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/reorderRows.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/resizable.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/search.html create mode 100644 ghy-admin/src/main/resources/templates/demo/table/subdata.html create mode 100644 ghy-admin/src/main/resources/templates/error/404.html create mode 100644 ghy-admin/src/main/resources/templates/error/500.html create mode 100644 ghy-admin/src/main/resources/templates/error/service.html create mode 100644 ghy-admin/src/main/resources/templates/error/unauth.html create mode 100644 ghy-admin/src/main/resources/templates/include.html create mode 100644 ghy-admin/src/main/resources/templates/index-topnav.html create mode 100644 ghy-admin/src/main/resources/templates/index.html create mode 100644 ghy-admin/src/main/resources/templates/lock.html create mode 100644 ghy-admin/src/main/resources/templates/login.html create mode 100644 ghy-admin/src/main/resources/templates/main.html create mode 100644 ghy-admin/src/main/resources/templates/main_v1.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/cache/cache.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/logininfor/logininfor.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/online/online.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/operlog/detail.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/operlog/operlog.html create mode 100644 ghy-admin/src/main/resources/templates/monitor/server/server.html create mode 100644 ghy-admin/src/main/resources/templates/register.html create mode 100644 ghy-admin/src/main/resources/templates/skin.html create mode 100644 ghy-admin/src/main/resources/templates/system/config/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/config/config.html create mode 100644 ghy-admin/src/main/resources/templates/system/config/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/dept/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/dept/dept.html create mode 100644 ghy-admin/src/main/resources/templates/system/dept/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/dept/tree.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/data/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/data/data.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/data/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/type/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/type/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/type/tree.html create mode 100644 ghy-admin/src/main/resources/templates/system/dict/type/type.html create mode 100644 ghy-admin/src/main/resources/templates/system/menu/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/menu/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/menu/icon.html create mode 100644 ghy-admin/src/main/resources/templates/system/menu/menu.html create mode 100644 ghy-admin/src/main/resources/templates/system/menu/tree.html create mode 100644 ghy-admin/src/main/resources/templates/system/notice/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/notice/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/notice/notice.html create mode 100644 ghy-admin/src/main/resources/templates/system/post/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/post/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/post/post.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/authUser.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/dataScope.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/role.html create mode 100644 ghy-admin/src/main/resources/templates/system/role/selectUser.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/add.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/authRole.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/edit.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/profile/avatar.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/profile/profile.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/profile/resetPwd.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/resetPwd.html create mode 100644 ghy-admin/src/main/resources/templates/system/user/user.html create mode 100644 ghy-admin/src/main/resources/templates/tool/build/build.html create mode 100644 ghy-admin/src/main/resources/test1.zip create mode 100644 ghy-admin/src/main/resources/test1/1.jpg create mode 100644 ghy-admin/src/main/resources/test1/1.xls create mode 100644 ghy-admin/src/main/resources/test1/2.jpg create mode 100644 ghy-common/pom.xml create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/DataScope.java create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/DataSource.java create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/Excel.java create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/Excels.java create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/Log.java create mode 100644 ghy-common/src/main/java/com/ghy/common/annotation/RepeatSubmit.java create mode 100644 ghy-common/src/main/java/com/ghy/common/config/GhyConfig.java create mode 100644 ghy-common/src/main/java/com/ghy/common/config/ServerConfig.java create mode 100644 ghy-common/src/main/java/com/ghy/common/config/datasource/DynamicDataSourceContextHolder.java create mode 100644 ghy-common/src/main/java/com/ghy/common/config/thread/ThreadPoolConfig.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/Constants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/GenConstants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/PermissionConstants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/ScheduleConstants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/ShiroConstants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/constant/UserConstants.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/controller/BaseController.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/AjaxResult.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/BaseEntity.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/CxSelect.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/TreeEntity.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/Ztree.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysDept.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysDictData.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysDictType.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysMenu.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysRole.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/domain/entity/SysUser.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/page/PageDomain.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/page/TableDataInfo.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/page/TableSupport.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/text/CharsetKit.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/text/Convert.java create mode 100644 ghy-common/src/main/java/com/ghy/common/core/text/StrFormatter.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/BusinessStatus.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/BusinessType.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/DataSourceType.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/OnlineStatus.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/OperatorType.java create mode 100644 ghy-common/src/main/java/com/ghy/common/enums/UserStatus.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/DemoModeException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/GlobalException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/ServiceException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/UtilException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/base/BaseException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/file/FileException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/file/FileNameLengthLimitExceededException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/file/FileSizeLimitExceededException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/file/InvalidExtensionException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/job/TaskException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/CaptchaException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/RoleBlockedException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserBlockedException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserDeleteException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserNotExistsException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserPasswordNotMatchException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserPasswordRetryLimitCountException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/exception/user/UserPasswordRetryLimitExceedException.java create mode 100644 ghy-common/src/main/java/com/ghy/common/json/JSON.java create mode 100644 ghy-common/src/main/java/com/ghy/common/json/JSONObject.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/AddressUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/Arith.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/CacheUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/CookieUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/DateUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/DictUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/ExceptionUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/IpUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/LogUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/MapDataUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/MessageUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/PageUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/ServletUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/ShiroUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/StringUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/Threads.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/YamlUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/bean/BeanUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/bean/BeanValidators.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/file/FileTypeUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/file/FileUploadUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/file/FileUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/file/ImageUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/file/MimeTypeUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/html/EscapeUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/html/HTMLFilter.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/http/HttpUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/poi/ExcelHandlerAdapter.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/poi/ExcelUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/reflect/ReflectUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/security/CipherUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/security/Md5Utils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/security/PermissionUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/spring/SpringUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/sql/SqlUtil.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/uuid/IdUtils.java create mode 100644 ghy-common/src/main/java/com/ghy/common/utils/uuid/UUID.java create mode 100644 ghy-common/src/main/java/com/ghy/common/xss/Xss.java create mode 100644 ghy-common/src/main/java/com/ghy/common/xss/XssFilter.java create mode 100644 ghy-common/src/main/java/com/ghy/common/xss/XssHttpServletRequestWrapper.java create mode 100644 ghy-common/src/main/java/com/ghy/common/xss/XssValidator.java create mode 100644 ghy-framework/pom.xml create mode 100644 ghy-framework/src/main/java/com/ghy/framework/aspectj/DataScopeAspect.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/aspectj/DataSourceAspect.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/aspectj/LogAspect.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/ApplicationConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/CaptchaConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/DruidConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/FilterConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/I18nConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/KaptchaTextCreator.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/MyBatisConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/ResourcesConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/ShiroConfig.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/config/properties/DruidProperties.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/datasource/DynamicDataSource.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/interceptor/RepeatSubmitInterceptor.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/interceptor/impl/SameUrlDataInterceptor.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/manager/AsyncManager.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/manager/ShutdownManager.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/manager/factory/AsyncFactory.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/realm/UserRealm.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/service/SysLoginService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/service/SysPasswordService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/service/SysRegisterService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/service/SysShiroService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/session/OnlineSession.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/session/OnlineSessionDAO.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/session/OnlineSessionFactory.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/util/AuthorizationUtils.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/filter/LogoutFilter.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/filter/captcha/CaptchaValidateFilter.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/filter/kickout/KickoutSessionFilter.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/filter/online/OnlineSessionFilter.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/filter/sync/SyncOnlineSessionFilter.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/session/OnlineWebSessionManager.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/shiro/web/session/SpringSessionValidationScheduler.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/Server.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/server/Cpu.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/server/Jvm.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/server/Mem.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/server/Sys.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/domain/server/SysFile.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/exception/GlobalExceptionHandler.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/service/CacheService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/service/ConfigService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/service/DictService.java create mode 100644 ghy-framework/src/main/java/com/ghy/framework/web/service/PermissionService.java create mode 100644 ghy-generator/pom.xml create mode 100644 ghy-generator/src/main/java/com/ghy/generator/config/GenConfig.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/controller/GenController.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/domain/GenTable.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/domain/GenTableColumn.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/mapper/GenTableColumnMapper.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/mapper/GenTableMapper.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/service/IGenTableColumnService.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/service/IGenTableService.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/service/impl/GenTableColumnServiceImpl.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/service/impl/GenTableServiceImpl.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/util/GenUtils.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/util/VelocityInitializer.java create mode 100644 ghy-generator/src/main/java/com/ghy/generator/util/VelocityUtils.java create mode 100644 ghy-generator/src/main/resources/generator.yml create mode 100644 ghy-generator/src/main/resources/mapper/generator/GenTableColumnMapper.xml create mode 100644 ghy-generator/src/main/resources/mapper/generator/GenTableMapper.xml create mode 100644 ghy-generator/src/main/resources/templates/tool/gen/createTable.html create mode 100644 ghy-generator/src/main/resources/templates/tool/gen/edit.html create mode 100644 ghy-generator/src/main/resources/templates/tool/gen/gen.html create mode 100644 ghy-generator/src/main/resources/templates/tool/gen/importTable.html create mode 100644 ghy-generator/src/main/resources/vm/html/add.html.vm create mode 100644 ghy-generator/src/main/resources/vm/html/edit.html.vm create mode 100644 ghy-generator/src/main/resources/vm/html/list-tree.html.vm create mode 100644 ghy-generator/src/main/resources/vm/html/list.html.vm create mode 100644 ghy-generator/src/main/resources/vm/html/tree.html.vm create mode 100644 ghy-generator/src/main/resources/vm/java/controller.java.vm create mode 100644 ghy-generator/src/main/resources/vm/java/domain.java.vm create mode 100644 ghy-generator/src/main/resources/vm/java/mapper.java.vm create mode 100644 ghy-generator/src/main/resources/vm/java/service.java.vm create mode 100644 ghy-generator/src/main/resources/vm/java/serviceImpl.java.vm create mode 100644 ghy-generator/src/main/resources/vm/java/sub-domain.java.vm create mode 100644 ghy-generator/src/main/resources/vm/sql/sql.vm create mode 100644 ghy-generator/src/main/resources/vm/xml/mapper.xml.vm create mode 100644 ghy-quartz/pom.xml create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/config/ScheduleConfig.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/controller/SysJobController.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/controller/SysJobLogController.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/domain/SysJob.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/domain/SysJobLog.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/mapper/SysJobLogMapper.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/mapper/SysJobMapper.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/service/ISysJobLogService.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/service/ISysJobService.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/service/impl/SysJobLogServiceImpl.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/service/impl/SysJobServiceImpl.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/task/RyTask.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/AbstractQuartzJob.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/CronUtils.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/JobInvokeUtil.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/QuartzDisallowConcurrentExecution.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/QuartzJobExecution.java create mode 100644 ghy-quartz/src/main/java/com/ghy/quartz/util/ScheduleUtils.java create mode 100644 ghy-quartz/src/main/resources/mapper/quartz/SysJobLogMapper.xml create mode 100644 ghy-quartz/src/main/resources/mapper/quartz/SysJobMapper.xml create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/add.html create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/cron.html create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/detail.html create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/edit.html create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/job.html create mode 100644 ghy-quartz/src/main/resources/templates/monitor/job/jobLog.html create mode 100644 ghy-system/pom.xml create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysConfig.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysLogininfor.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysNotice.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysOperLog.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysPost.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysRoleDept.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysRoleMenu.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysUserOnline.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysUserPost.java create mode 100644 ghy-system/src/main/java/com/ghy/system/domain/SysUserRole.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysConfigMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysDeptMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysDictDataMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysDictTypeMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysLogininforMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysMenuMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysNoticeMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysOperLogMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysPostMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysRoleDeptMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysRoleMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysRoleMenuMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysUserMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysUserOnlineMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysUserPostMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/mapper/SysUserRoleMapper.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysConfigService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysDeptService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysDictDataService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysDictTypeService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysLogininforService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysMenuService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysNoticeService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysOperLogService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysPostService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysRoleService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysUserOnlineService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/ISysUserService.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysConfigServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysDeptServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysDictDataServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysDictTypeServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysLogininforServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysMenuServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysNoticeServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysOperLogServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysPostServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysRoleServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysUserOnlineServiceImpl.java create mode 100644 ghy-system/src/main/java/com/ghy/system/service/impl/SysUserServiceImpl.java create mode 100644 ghy-system/src/main/resources/mapper/system/SysConfigMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysDeptMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysDictDataMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysDictTypeMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysLogininforMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysMenuMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysNoticeMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysOperLogMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysPostMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysRoleDeptMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysRoleMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysRoleMenuMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysUserMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysUserOnlineMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysUserPostMapper.xml create mode 100644 ghy-system/src/main/resources/mapper/system/SysUserRoleMapper.xml create mode 100644 pom.xml create mode 100644 ry.bat create mode 100644 ry.sh create mode 100644 sql/quartz.sql create mode 100644 sql/ruoyi.html create mode 100644 sql/ruoyi.pdm create mode 100644 sql/ry_20210924.sql diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..8564f294 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2018 RuoYi + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/bin/clean.bat b/bin/clean.bat new file mode 100644 index 00000000..24c09741 --- /dev/null +++ b/bin/clean.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] target· +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean + +pause \ No newline at end of file diff --git a/bin/package.bat b/bin/package.bat new file mode 100644 index 00000000..c693ec06 --- /dev/null +++ b/bin/package.bat @@ -0,0 +1,12 @@ +@echo off +echo. +echo [Ϣ] Weḅwar/jarļ +echo. + +%~d0 +cd %~dp0 + +cd .. +call mvn clean package -Dmaven.test.skip=true + +pause \ No newline at end of file diff --git a/bin/run.bat b/bin/run.bat new file mode 100644 index 00000000..41efbd0f --- /dev/null +++ b/bin/run.bat @@ -0,0 +1,14 @@ +@echo off +echo. +echo [Ϣ] ʹJarWeb̡ +echo. + +cd %~dp0 +cd ../ruoyi-admin/target + +set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m + +java -jar %JAVA_OPTS% ruoyi-admin.jar + +cd bin +pause \ No newline at end of file diff --git a/doc/光惠影环境使用手册.docx b/doc/光惠影环境使用手册.docx new file mode 100644 index 0000000000000000000000000000000000000000..fa5b62d7dcc9b9a31cc58db611ecac7b00cc385a GIT binary patch literal 426497 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

lksLB!Nmj-*B*fUrQfrUk(X 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%0Ak)Rl1D+4<~C+3nV#reCkhh! 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

ry>@!6&DKiX&7 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≀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

3mMKSNM*HIJBki30ER}0(^exCYM!!! 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 r0@aV!V?s9pwLgK-&%h8 + + + ghy + com.ghy + 1.0.0 + + 4.0.0 + jar + ghy-admin + + + web服务入口 + + + + + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + io.springfox + springfox-boot-starter + + + + + io.swagger + swagger-models + 1.6.2 + + + + + mysql + mysql-connector-java + + + + + com.ghy + ghy-framework + + + + + com.ghy + ghy-quartz + + + + + com.ghy + ghy-generator + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.1.1.RELEASE + + true + + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 3.0.0 + + false + ${project.artifactId} + + + + + ${project.artifactId} + + + \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/CodeDetector.java b/ghy-admin/src/main/java/com/ghy/CodeDetector.java new file mode 100644 index 00000000..273e3810 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/CodeDetector.java @@ -0,0 +1,201 @@ +package com.ghy; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.BitSet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CodeDetector { + + private static Logger logger = LoggerFactory.getLogger(CodeDetector.class); + + private static int BYTE_SIZE = 8; + public static String CODE_UTF8 = "UTF-8"; + public static String CODE_UTF8_BOM = "UTF-8_BOM"; + public static String CODE_GBK = "GBK"; + + /** + * 通过文件全名称获取编码集名称 + * + * @param fullFileName + * @param ignoreBom + * @return + * @throws Exception + */ + public static String getEncode(String fullFileName, boolean ignoreBom) throws Exception { + logger.debug("fullFileName ; {}", fullFileName); + BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fullFileName)); + return getEncode(bis, ignoreBom); + } + + /** + * 通过文件缓存流获取编码集名称,文件流必须为未曾 + * + * @param bis + * @param ignoreBom 是否忽略utf-8 bom + * @return + * @throws Exception + */ + public static String getEncode(BufferedInputStream bis, boolean ignoreBom) { + String encodeType = "未识别"; + try { + bis.mark(0); + byte[] head = new byte[3]; + bis.read(head); + if (head[0] == -1 && head[1] == -2) { + encodeType = "UTF-16"; + } else if (head[0] == -2 && head[1] == -1) { + encodeType = "Unicode"; + } else if (head[0] == -17 && head[1] == -69 && head[2] == -65) { //带BOM + if (ignoreBom) { + encodeType = CODE_UTF8; + } else { + encodeType = CODE_UTF8_BOM; + } + } else if ("Unicode".equals(encodeType)) { + encodeType = "UTF-16"; + } else if (isUTF8(bis)) { + encodeType = CODE_UTF8; + } else { + encodeType = CODE_GBK; + } + logger.info("result encode type : " + encodeType); + } catch (Exception e) { + // TODO: handle exception + } + + return encodeType; + } + + /** + * 是否是无BOM的UTF8格式,不判断常规场景,只区分无BOM UTF8和GBK + * + * @param bis + * @return + */ + private static boolean isUTF8( BufferedInputStream bis) throws Exception { + bis.reset(); + + //读取第一个字节 + int code = bis.read(); + do { + BitSet bitSet = convert2BitSet(code); + //判断是否为单字节 + if (bitSet.get(0)) {//多字节时,再读取N个字节 + if (!checkMultiByte(bis, bitSet)) {//未检测通过,直接返回 + return false; + } + } else { + //单字节时什么都不用做,再次读取字节 + } + code = bis.read(); + } while (code != -1); + return true; + } + + /** + * 检测多字节,判断是否为utf8,已经读取了一个字节 + * + * @param bis + * @param bitSet + * @return + */ + private static boolean checkMultiByte(BufferedInputStream bis, BitSet bitSet) throws Exception { + int count = getCountOfSequential(bitSet); + byte[] bytes = new byte[count - 1];//已经读取了一个字节,不能再读取 + bis.read(bytes); + for (byte b : bytes) { + if (!checkUtf8Byte(b)) { + return false; + } + } + return true; + } + + /** + * 检测单字节,判断是否为utf8 + * + * @param b + * @return + */ + private static boolean checkUtf8Byte(byte b) throws Exception { + BitSet bitSet = convert2BitSet(b); + return bitSet.get(0) && !bitSet.get(1); + } + + /** + * 检测bitSet中从开始有多少个连续的1 + * + * @param bitSet + * @return + */ + private static int getCountOfSequential( BitSet bitSet) { + int count = 0; + for (int i = 0; i < BYTE_SIZE; i++) { + if (bitSet.get(i)) { + count++; + } else { + break; + } + } + return count; + } + + + /** + * 将整形转为BitSet + * + * @param code + * @return + */ + private static BitSet convert2BitSet(int code) { + BitSet bitSet = new BitSet(BYTE_SIZE); + + for (int i = 0; i < BYTE_SIZE; i++) { + int tmp3 = code >> (BYTE_SIZE - i - 1); + int tmp2 = 0x1 & tmp3; + if (tmp2 == 1) { + bitSet.set(i); + } + } + return bitSet; + } + + /** + * 将一指定编码的文件转换为另一编码的文件 + * + * @param oldFullFileName + * @param oldCharsetName + * @param newFullFileName + * @param newCharsetName + */ + public static void convert(String oldFullFileName, String oldCharsetName, String newFullFileName, String newCharsetName) throws Exception { + logger.info("the old file name is : {}, The oldCharsetName is : {}", oldFullFileName, oldCharsetName); + logger.info("the new file name is : {}, The newCharsetName is : {}", newFullFileName, newCharsetName); + + StringBuffer content = new StringBuffer(); + + BufferedReader bin = new BufferedReader(new InputStreamReader(new FileInputStream(oldFullFileName), oldCharsetName)); + String line; + while ((line = bin.readLine()) != null) { + content.append(line); + content.append(System.getProperty("line.separator")); + } + newFullFileName = newFullFileName.replace("\\", "/"); + File dir = new File(newFullFileName.substring(0, newFullFileName.lastIndexOf("/"))); + if (!dir.exists()) { + dir.mkdirs(); + } + Writer out = new OutputStreamWriter(new FileOutputStream(newFullFileName), newCharsetName); + out.write(content.toString()); + } + +} diff --git a/ghy-admin/src/main/java/com/ghy/GhyApplication.java b/ghy-admin/src/main/java/com/ghy/GhyApplication.java new file mode 100644 index 00000000..17cce83d --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/GhyApplication.java @@ -0,0 +1,30 @@ +package com.ghy; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; + +/** + * 启动程序 + * + * @author clunt + */ +@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) +public class GhyApplication +{ + public static void main(String[] args) + { + // System.setProperty("spring.devtools.restart.enabled", "false"); + SpringApplication.run(GhyApplication.class, args); + System.out.println("(♥◠‿◠)ノ゙ 光惠影管理系统启动成功 ლ(´ڡ`ლ)゙ \n" + + " .-------. ____ __ \n" + + " | _ _ \\ \\ \\ / / \n" + + " | ( ' ) | \\ _. / ' \n" + + " |(_ o _) / _( )_ .' \n" + + " | (_,_).' __ ___(_ o _)' \n" + + " | |\\ \\ | || |(_,_)' \n" + + " | | \\ `' /| `-' / \n" + + " | | \\ / \\ / \n" + + " ''-' `'-' `-..-' "); + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/GhyServletInitializer.java b/ghy-admin/src/main/java/com/ghy/GhyServletInitializer.java new file mode 100644 index 00000000..e4f18ba2 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/GhyServletInitializer.java @@ -0,0 +1,18 @@ +package com.ghy; + +import org.springframework.boot.builder.SpringApplicationBuilder; +import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; + +/** + * web容器中进行部署 + * + * @author clunt + */ +public class GhyServletInitializer extends SpringBootServletInitializer +{ + @Override + protected SpringApplicationBuilder configure(SpringApplicationBuilder application) + { + return application.sources(GhyApplication.class); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/Test.java b/ghy-admin/src/main/java/com/ghy/Test.java new file mode 100644 index 00000000..37f98cb6 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/Test.java @@ -0,0 +1,65 @@ +package com.ghy; + +import java.io.*; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +public class Test { + + public static void main(String[] args) throws Exception{ +// URL rul = Test.class.getClassLoader().getResource("test1.zip"); +// String fileName = rul.getPath(); +// System.out.println(readZip("/Users/clunt/java/guanghy/ghy/ghy-admin/src/main/resources/test1.zip")); + String fileName = "/Users/clunt/java/guanghy/ghy/ghy-admin/src/main/resources/test1.zip"; + unzip(fileName , "/Users/clunt/java/guanghy/ghy/ghy-admin/src/main/resources/"); + } + + // 如果父目录不存在则创建 + private static void mkdir(File file) { + if (null == file || file.exists()) { + return; + } + mkdir(file.getParentFile()); + file.mkdir(); + } + + public static void unzip(String zipFilePath, String desDirectory) throws Exception { + + File desDir = new File(desDirectory); + if (!desDir.exists()) { + boolean mkdirSuccess = desDir.mkdir(); + if (!mkdirSuccess) { + throw new Exception("创建解压目标文件夹失败"); + } + } + // 读入流 + ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFilePath)); + // 遍历每一个文件 + ZipEntry zipEntry = zipInputStream.getNextEntry(); + while (zipEntry != null) { + if (zipEntry.isDirectory()) { // 文件夹 + String unzipFilePath = desDirectory + File.separator + zipEntry.getName(); + // 直接创建 + mkdir(new File(unzipFilePath)); + } else { // 文件 + String unzipFilePath = desDirectory + File.separator + zipEntry.getName(); + File file = new File(unzipFilePath); + // 创建父目录 + mkdir(file.getParentFile()); + // 写出文件流 + BufferedOutputStream bufferedOutputStream = + new BufferedOutputStream(new FileOutputStream(unzipFilePath)); + byte[] bytes = new byte[1024]; + int readLen; + while ((readLen = zipInputStream.read(bytes)) != -1) { + bufferedOutputStream.write(bytes, 0, readLen); + } + bufferedOutputStream.close(); + } + zipInputStream.closeEntry(); + zipEntry = zipInputStream.getNextEntry(); + } + zipInputStream.close(); + } + +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/common/CommonController.java b/ghy-admin/src/main/java/com/ghy/web/controller/common/CommonController.java new file mode 100644 index 00000000..2f919748 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/common/CommonController.java @@ -0,0 +1,156 @@ +package com.ghy.web.controller.common; + +import java.util.ArrayList; +import java.util.List; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ghy.common.config.GhyConfig; +import com.ghy.common.config.ServerConfig; +import com.ghy.common.constant.Constants; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.utils.StringUtils; +import com.ghy.common.utils.file.FileUploadUtils; +import com.ghy.common.utils.file.FileUtils; + +/** + * 通用请求处理 + * + * @author clunt + */ +@Controller +public class CommonController +{ + private static final Logger log = LoggerFactory.getLogger(CommonController.class); + + @Autowired + private ServerConfig serverConfig; + + private static final String FILE_DELIMETER = ","; + + /** + * 通用下载请求 + * + * @param fileName 文件名称 + * @param delete 是否删除 + */ + @GetMapping("common/download") + public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) + { + try + { + if (!FileUtils.checkAllowDownload(fileName)) + { + throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); + } + String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); + String filePath = GhyConfig.getDownloadPath() + fileName; + + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, realFileName); + FileUtils.writeBytes(filePath, response.getOutputStream()); + if (delete) + { + FileUtils.deleteFile(filePath); + } + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } + + /** + * 通用上传请求(单个) + */ + @PostMapping("/common/upload") + @ResponseBody + public AjaxResult uploadFile(MultipartFile file) throws Exception + { + try + { + // 上传文件路径 + String filePath = GhyConfig.getUploadPath(); + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + AjaxResult ajax = AjaxResult.success(); + ajax.put("fileName", fileName); + ajax.put("url", url); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 通用上传请求(多个) + */ + @PostMapping("/common/uploads") + @ResponseBody + public AjaxResult uploadFiles(List files) throws Exception + { + try + { + // 上传文件路径 + String filePath = GhyConfig.getUploadPath(); + List fileNames = new ArrayList(); + List urls = new ArrayList(); + for (MultipartFile file : files) + { + // 上传并返回新文件名称 + String fileName = FileUploadUtils.upload(filePath, file); + String url = serverConfig.getUrl() + fileName; + fileNames.add(fileName); + urls.add(url); + } + AjaxResult ajax = AjaxResult.success(); + ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); + ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); + return ajax; + } + catch (Exception e) + { + return AjaxResult.error(e.getMessage()); + } + } + + /** + * 本地资源通用下载 + */ + @GetMapping("/common/download/resource") + public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) + throws Exception + { + try + { + if (!FileUtils.checkAllowDownload(resource)) + { + throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); + } + // 本地资源路径 + String localPath = GhyConfig.getProfile(); + // 数据库资源地址 + String downloadPath = localPath + StringUtils.substringAfter(resource, Constants.RESOURCE_PREFIX); + // 下载名称 + String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); + response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); + FileUtils.setAttachmentResponseHeader(response, downloadName); + FileUtils.writeBytes(downloadPath, response.getOutputStream()); + } + catch (Exception e) + { + log.error("下载文件失败", e); + } + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoDialogController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoDialogController.java new file mode 100644 index 00000000..39271dd8 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoDialogController.java @@ -0,0 +1,98 @@ +package com.ghy.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 模态窗口 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/modal") +public class DemoDialogController +{ + private String prefix = "demo/modal"; + + /** + * 模态窗口 + */ + @GetMapping("/dialog") + public String dialog() + { + return prefix + "/dialog"; + } + + /** + * 弹层组件 + */ + @GetMapping("/layer") + public String layer() + { + return prefix + "/layer"; + } + + /** + * 表单 + */ + @GetMapping("/form") + public String form() + { + return prefix + "/form"; + } + + /** + * 表格 + */ + @GetMapping("/table") + public String table() + { + return prefix + "/table"; + } + + /** + * 表格check + */ + @GetMapping("/check") + public String check() + { + return prefix + "/table/check"; + } + + /** + * 表格radio + */ + @GetMapping("/radio") + public String radio() + { + return prefix + "/table/radio"; + } + + /** + * 表格回传父窗体 + */ + @GetMapping("/parent") + public String parent() + { + return prefix + "/table/parent"; + } + + /** + * 多层窗口frame1 + */ + @GetMapping("/frame1") + public String frame1() + { + return prefix + "/table/frame1"; + } + + /** + * 多层窗口frame2 + */ + @GetMapping("/frame2") + public String frame2() + { + return prefix + "/table/frame2"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoFormController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoFormController.java new file mode 100644 index 00000000..0bd89908 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoFormController.java @@ -0,0 +1,390 @@ +package com.ghy.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.alibaba.fastjson.JSON; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.CxSelect; +import com.ghy.common.json.JSONObject; +import com.ghy.common.json.JSONObject.JSONArray; +import com.ghy.common.utils.StringUtils; + +/** + * 表单相关 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/form") +public class DemoFormController +{ + private String prefix = "demo/form"; + + private final static List users = new ArrayList(); + { + users.add(new UserFormModel(1, "1000001", "测试1", "15888888888")); + users.add(new UserFormModel(2, "1000002", "测试2", "15666666666")); + users.add(new UserFormModel(3, "1000003", "测试3", "15666666666")); + users.add(new UserFormModel(4, "1000004", "测试4", "15666666666")); + users.add(new UserFormModel(5, "1000005", "测试5", "15666666666")); + } + + /** + * 按钮页 + */ + @GetMapping("/button") + public String button() + { + return prefix + "/button"; + } + + /** + * 下拉框 + */ + @GetMapping("/select") + public String select() + { + return prefix + "/select"; + } + + /** + * 时间轴 + */ + @GetMapping("/timeline") + public String timeline() + { + return prefix + "/timeline"; + } + + /** + * 表单校验 + */ + @GetMapping("/validate") + public String validate() + { + return prefix + "/validate"; + } + + /** + * 功能扩展(包含文件上传) + */ + @GetMapping("/jasny") + public String jasny() + { + return prefix + "/jasny"; + } + + /** + * 拖动排序 + */ + @GetMapping("/sortable") + public String sortable() + { + return prefix + "/sortable"; + } + + /** + * 单据打印 + */ + @GetMapping("/invoice") + public String invoice() + { + return prefix + "/invoice"; + } + + /** + * 标签 & 提示 + */ + @GetMapping("/labels_tips") + public String labels_tips() + { + return prefix + "/labels_tips"; + } + + /** + * 选项卡 & 面板 + */ + @GetMapping("/tabs_panels") + public String tabs_panels() + { + return prefix + "/tabs_panels"; + } + + /** + * 栅格 + */ + @GetMapping("/grid") + public String grid() + { + return prefix + "/grid"; + } + + /** + * 表单向导 + */ + @GetMapping("/wizard") + public String wizard() + { + return prefix + "/wizard"; + } + + /** + * 文件上传 + */ + @GetMapping("/upload") + public String upload() + { + return prefix + "/upload"; + } + + /** + * 日期和时间页 + */ + @GetMapping("/datetime") + public String datetime() + { + return prefix + "/datetime"; + } + + /** + * 左右互选组件 + */ + @GetMapping("/duallistbox") + public String duallistbox() + { + return prefix + "/duallistbox"; + } + + /** + * 基本表单 + */ + @GetMapping("/basic") + public String basic() + { + return prefix + "/basic"; + } + + /** + * 卡片列表 + */ + @GetMapping("/cards") + public String cards() + { + return prefix + "/cards"; + } + + /** + * summernote 富文本编辑器 + */ + @GetMapping("/summernote") + public String summernote() + { + return prefix + "/summernote"; + } + + /** + * 搜索自动补全 + */ + @GetMapping("/autocomplete") + public String autocomplete() + { + return prefix + "/autocomplete"; + } + + /** + * 多级联动下拉 + */ + @GetMapping("/cxselect") + public String cxselect(ModelMap mmap) + { + CxSelect cxSelectTB = new CxSelect(); + cxSelectTB.setN("淘宝"); + cxSelectTB.setV("taobao"); + CxSelect cxSelectTm = new CxSelect(); + cxSelectTm.setN("天猫"); + cxSelectTm.setV("tm"); + CxSelect cxSelectJhs = new CxSelect(); + cxSelectJhs.setN("聚划算"); + cxSelectJhs.setV("jhs"); + List tmList = new ArrayList(); + tmList.add(cxSelectTm); + tmList.add(cxSelectJhs); + cxSelectTB.setS(tmList); + + CxSelect cxSelectJD = new CxSelect(); + cxSelectJD.setN("京东"); + cxSelectJD.setV("jd"); + CxSelect cxSelectCs = new CxSelect(); + cxSelectCs.setN("京东超市"); + cxSelectCs.setV("jdcs"); + CxSelect cxSelectSx = new CxSelect(); + cxSelectSx.setN("京东生鲜"); + cxSelectSx.setV("jdsx"); + List jdList = new ArrayList(); + jdList.add(cxSelectCs); + jdList.add(cxSelectSx); + cxSelectJD.setS(jdList); + + List cxList = new ArrayList(); + cxList.add(cxSelectTB); + cxList.add(cxSelectJD); + + mmap.put("data", JSON.toJSON(cxList)); + return prefix + "/cxselect"; + } + + /** + * 局部刷新 + */ + @GetMapping("/localrefresh") + public String localRefresh(ModelMap mmap) + { + JSONArray list = new JSONArray(); + JSONObject item = new JSONObject(); + item.put("name", "这条任务数据是由ModelMap传递到页面的,点击添加按钮后会将这条数据替换为新数据"); + item.put("type", "默认"); + item.put("date", "2020.06.10"); + list.add(item); + mmap.put("tasks", list); + mmap.put("min", 2); + mmap.put("max", 10); + return prefix + "/localrefresh"; + } + + /** + * 局部刷新-添加任务 + * + * @param fragment 页面中的模板名称 + * @param taskName 任务名称 + */ + @PostMapping("/localrefresh/task") + public String localRefreshTask(String fragment, String taskName, ModelMap mmap) + { + JSONArray list = new JSONArray(); + JSONObject item = new JSONObject(); + item.put("name", StringUtils.defaultIfBlank(taskName, "通过电话销售过程中了解各盛市的设备仪器使用、采购情况及相关重要追踪人")); + item.put("type", "新增"); + item.put("date", "2018.06.10"); + list.add(item); + item = new JSONObject(); + item.put("name", "提高自己电话营销技巧,灵活专业地与客户进行电话交流"); + item.put("type", "新增"); + item.put("date", "2018.06.12"); + list.add(item); + mmap.put("tasks", list); + return prefix + "/localrefresh::" + fragment; + } + + /** + * 模拟数据 + */ + @GetMapping("/cityData") + @ResponseBody + public String cityData() + { + String data = "[{\"n\":\"湖南省\",\"s\":[{\"n\":\"长沙市\",\"s\":[{\"n\":\"芙蓉区\"},{\"n\":\"天心区\"},{\"n\":\"岳麓区\"},{\"n\":\"开福区\"},{\"n\":\"雨花区\"},{\"n\":\"望城区\"},{\"n\":\"长沙县\"},{\"n\":\"宁乡县\"},{\"n\":\"浏阳市\"}]},{\"n\":\"株洲市\",\"s\":[{\"n\":\"荷塘区\"},{\"n\":\"芦淞区\"},{\"n\":\"石峰区\"},{\"n\":\"天元区\"},{\"n\":\"株洲县\"},{\"n\":\"攸县\"},{\"n\":\"茶陵县\"},{\"n\":\"炎陵县\"},{\"n\":\"醴陵市\"}]},{\"n\":\"湘潭市\",\"s\":[{\"n\":\"雨湖区\"},{\"n\":\"岳塘区\"},{\"n\":\"湘潭县\"},{\"n\":\"湘乡市\"},{\"n\":\"韶山市\"}]},{\"n\":\"衡阳市\",\"s\":[{\"n\":\"珠晖区\"},{\"n\":\"雁峰区\"},{\"n\":\"石鼓区\"},{\"n\":\"蒸湘区\"},{\"n\":\"南岳区\"},{\"n\":\"衡阳县\"},{\"n\":\"衡南县\"},{\"n\":\"衡山县\"},{\"n\":\"衡东县\"},{\"n\":\"祁东县\"},{\"n\":\"耒阳市\"},{\"n\":\"常宁市\"}]},{\"n\":\"邵阳市\",\"s\":[{\"n\":\"双清区\"},{\"n\":\"大祥区\"},{\"n\":\"北塔区\"},{\"n\":\"邵东县\"},{\"n\":\"新邵县\"},{\"n\":\"邵阳县\"},{\"n\":\"隆回县\"},{\"n\":\"洞口县\"},{\"n\":\"绥宁县\"},{\"n\":\"新宁县\"},{\"n\":\"城步苗族自治县\"},{\"n\":\"武冈市\"}]},{\"n\":\"岳阳市\",\"s\":[{\"n\":\"岳阳楼区\"},{\"n\":\"云溪区\"},{\"n\":\"君山区\"},{\"n\":\"岳阳县\"},{\"n\":\"华容县\"},{\"n\":\"湘阴县\"},{\"n\":\"平江县\"},{\"n\":\"汨罗市\"},{\"n\":\"临湘市\"}]},{\"n\":\"常德市\",\"s\":[{\"n\":\"武陵区\"},{\"n\":\"鼎城区\"},{\"n\":\"安乡县\"},{\"n\":\"汉寿县\"},{\"n\":\"澧县\"},{\"n\":\"临澧县\"},{\"n\":\"桃源县\"},{\"n\":\"石门县\"},{\"n\":\"津市市\"}]},{\"n\":\"张家界市\",\"s\":[{\"n\":\"永定区\"},{\"n\":\"武陵源区\"},{\"n\":\"慈利县\"},{\"n\":\"桑植县\"}]},{\"n\":\"益阳市\",\"s\":[{\"n\":\"资阳区\"},{\"n\":\"赫山区\"},{\"n\":\"南县\"},{\"n\":\"桃江县\"},{\"n\":\"安化县\"},{\"n\":\"沅江市\"}]},{\"n\":\"郴州市\",\"s\":[{\"n\":\"北湖区\"},{\"n\":\"苏仙区\"},{\"n\":\"桂阳县\"},{\"n\":\"宜章县\"},{\"n\":\"永兴县\"},{\"n\":\"嘉禾县\"},{\"n\":\"临武县\"},{\"n\":\"汝城县\"},{\"n\":\"桂东县\"},{\"n\":\"安仁县\"},{\"n\":\"资兴市\"}]},{\"n\":\"永州市\",\"s\":[{\"n\":\"零陵区\"},{\"n\":\"冷水滩区\"},{\"n\":\"祁阳县\"},{\"n\":\"东安县\"},{\"n\":\"双牌县\"},{\"n\":\"道县\"},{\"n\":\"江永县\"},{\"n\":\"宁远县\"},{\"n\":\"蓝山县\"},{\"n\":\"新田县\"},{\"n\":\"江华瑶族自治县\"}]},{\"n\":\"怀化市\",\"s\":[{\"n\":\"鹤城区\"},{\"n\":\"中方县\"},{\"n\":\"沅陵县\"},{\"n\":\"辰溪县\"},{\"n\":\"溆浦县\"},{\"n\":\"会同县\"},{\"n\":\"麻阳苗族自治县\"},{\"n\":\"新晃侗族自治县\"},{\"n\":\"芷江侗族自治县\"},{\"n\":\"靖州苗族侗族自治县\"},{\"n\":\"通道侗族自治县\"},{\"n\":\"洪江市\"}]},{\"n\":\"娄底市\",\"s\":[{\"n\":\"娄星区\"},{\"n\":\"双峰县\"},{\"n\":\"新化县\"},{\"n\":\"冷水江市\"},{\"n\":\"涟源市\"}]},{\"n\":\"湘西土家族苗族自治州\",\"s\":[{\"n\":\"吉首市\"},{\"n\":\"泸溪县\"},{\"n\":\"凤凰县\"},{\"n\":\"花垣县\"},{\"n\":\"保靖县\"},{\"n\":\"古丈县\"},{\"n\":\"永顺县\"},{\"n\":\"龙山县\"}]}]},{\"n\":\"广东省\",\"s\":[{\"n\":\"广州市\",\"s\":[{\"n\":\"荔湾区\"},{\"n\":\"越秀区\"},{\"n\":\"海珠区\"},{\"n\":\"天河区\"},{\"n\":\"白云区\"},{\"n\":\"黄埔区\"},{\"n\":\"番禺区\"},{\"n\":\"花都区\"},{\"n\":\"南沙区\"},{\"n\":\"萝岗区\"},{\"n\":\"增城市\"},{\"n\":\"从化市\"}]},{\"n\":\"韶关市\",\"s\":[{\"n\":\"武江区\"},{\"n\":\"浈江区\"},{\"n\":\"曲江区\"},{\"n\":\"始兴县\"},{\"n\":\"仁化县\"},{\"n\":\"翁源县\"},{\"n\":\"乳源瑶族自治县\"},{\"n\":\"新丰县\"},{\"n\":\"乐昌市\"},{\"n\":\"南雄市\"}]},{\"n\":\"深圳市\",\"s\":[{\"n\":\"罗湖区\"},{\"n\":\"福田区\"},{\"n\":\"南山区\"},{\"n\":\"宝安区\"},{\"n\":\"龙岗区\"},{\"n\":\"盐田区\"}]},{\"n\":\"珠海市\",\"s\":[{\"n\":\"香洲区\"},{\"n\":\"斗门区\"},{\"n\":\"金湾区\"}]},{\"n\":\"汕头市\",\"s\":[{\"n\":\"龙湖区\"},{\"n\":\"金平区\"},{\"n\":\"濠江区\"},{\"n\":\"潮阳区\"},{\"n\":\"潮南区\"},{\"n\":\"澄海区\"},{\"n\":\"南澳县\"}]},{\"n\":\"佛山市\",\"s\":[{\"n\":\"禅城区\"},{\"n\":\"南海区\"},{\"n\":\"顺德区\"},{\"n\":\"三水区\"},{\"n\":\"高明区\"}]},{\"n\":\"江门市\",\"s\":[{\"n\":\"蓬江区\"},{\"n\":\"江海区\"},{\"n\":\"新会区\"},{\"n\":\"台山市\"},{\"n\":\"开平市\"},{\"n\":\"鹤山市\"},{\"n\":\"恩平市\"}]},{\"n\":\"湛江市\",\"s\":[{\"n\":\"赤坎区\"},{\"n\":\"霞山区\"},{\"n\":\"坡头区\"},{\"n\":\"麻章区\"},{\"n\":\"遂溪县\"},{\"n\":\"徐闻县\"},{\"n\":\"廉江市\"},{\"n\":\"雷州市\"},{\"n\":\"吴川市\"}]},{\"n\":\"茂名市\",\"s\":[{\"n\":\"茂南区\"},{\"n\":\"茂港区\"},{\"n\":\"电白县\"},{\"n\":\"高州市\"},{\"n\":\"化州市\"},{\"n\":\"信宜市\"}]},{\"n\":\"肇庆市\",\"s\":[{\"n\":\"端州区\"},{\"n\":\"鼎湖区\"},{\"n\":\"广宁县\"},{\"n\":\"怀集县\"},{\"n\":\"封开县\"},{\"n\":\"德庆县\"},{\"n\":\"高要市\"},{\"n\":\"四会市\"}]},{\"n\":\"惠州市\",\"s\":[{\"n\":\"惠城区\"},{\"n\":\"惠阳区\"},{\"n\":\"博罗县\"},{\"n\":\"惠东县\"},{\"n\":\"龙门县\"}]},{\"n\":\"梅州市\",\"s\":[{\"n\":\"梅江区\"},{\"n\":\"梅县\"},{\"n\":\"大埔县\"},{\"n\":\"丰顺县\"},{\"n\":\"五华县\"},{\"n\":\"平远县\"},{\"n\":\"蕉岭县\"},{\"n\":\"兴宁市\"}]},{\"n\":\"汕尾市\",\"s\":[{\"n\":\"城区\"},{\"n\":\"海丰县\"},{\"n\":\"陆河县\"},{\"n\":\"陆丰市\"}]},{\"n\":\"河源市\",\"s\":[{\"n\":\"源城区\"},{\"n\":\"紫金县\"},{\"n\":\"龙川县\"},{\"n\":\"连平县\"},{\"n\":\"和平县\"},{\"n\":\"东源县\"}]},{\"n\":\"阳江市\",\"s\":[{\"n\":\"江城区\"},{\"n\":\"阳西县\"},{\"n\":\"阳东县\"},{\"n\":\"阳春市\"}]},{\"n\":\"清远市\",\"s\":[{\"n\":\"清城区\"},{\"n\":\"清新区\"},{\"n\":\"佛冈县\"},{\"n\":\"阳山县\"},{\"n\":\"连山壮族瑶族自治县\"},{\"n\":\"连南瑶族自治县\"},{\"n\":\"英德市\"},{\"n\":\"连州市\"}]},{\"n\":\"东莞市\"},{\"n\":\"中山市\"},{\"n\":\"潮州市\",\"s\":[{\"n\":\"湘桥区\"},{\"n\":\"潮安区\"},{\"n\":\"饶平县\"}]},{\"n\":\"揭阳市\",\"s\":[{\"n\":\"榕城区\"},{\"n\":\"揭东区\"},{\"n\":\"揭西县\"},{\"n\":\"惠来县\"},{\"n\":\"普宁市\"}]},{\"n\":\"云浮市\",\"s\":[{\"n\":\"云城区\"},{\"n\":\"新兴县\"},{\"n\":\"郁南县\"},{\"n\":\"云安县\"},{\"n\":\"罗定市\"}]}]}]"; + return data; + } + + /** + * 获取用户数据 + */ + @GetMapping("/userModel") + @ResponseBody + public AjaxResult userModel() + { + AjaxResult ajax = new AjaxResult(); + + ajax.put("code", 200); + ajax.put("value", users); + return ajax; + } + + /** + * 获取数据集合 + */ + @GetMapping("/collection") + @ResponseBody + public AjaxResult collection() + { + String[] array = { "ruoyi 1", "ruoyi 2", "ruoyi 3", "ruoyi 4", "ruoyi 5" }; + AjaxResult ajax = new AjaxResult(); + ajax.put("value", array); + return ajax; + } +} + +class UserFormModel +{ + /** 用户ID */ + private int userId; + + /** 用户编号 */ + private String userCode; + + /** 用户姓名 */ + private String userName; + + /** 用户手机 */ + private String userPhone; + + public UserFormModel() + { + + } + + public UserFormModel(int userId, String userCode, String userName, String userPhone) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userPhone = userPhone; + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoIconController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoIconController.java new file mode 100644 index 00000000..b015c475 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoIconController.java @@ -0,0 +1,35 @@ +package com.ghy.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 图标相关 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/icon") +public class DemoIconController +{ + private String prefix = "demo/icon"; + + /** + * FontAwesome图标 + */ + @GetMapping("/fontawesome") + public String fontAwesome() + { + return prefix + "/fontawesome"; + } + + /** + * Glyphicons图标 + */ + @GetMapping("/glyphicons") + public String glyphicons() + { + return prefix + "/glyphicons"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoOperateController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoOperateController.java new file mode 100644 index 00000000..a2fa9086 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoOperateController.java @@ -0,0 +1,326 @@ +package com.ghy.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.PageDomain; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.core.page.TableSupport; +import com.ghy.common.core.text.Convert; +import com.ghy.common.exception.ServiceException; +import com.ghy.common.utils.StringUtils; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.web.controller.demo.domain.CustomerModel; +import com.ghy.web.controller.demo.domain.UserOperateModel; + +/** + * 操作控制 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/operate") +public class DemoOperateController extends BaseController +{ + private String prefix = "demo/operate"; + + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserOperateModel(1, "1000001", "测试1", "0", "15888888888", "ry@qq.com", 150.0, "0")); + users.put(2, new UserOperateModel(2, "1000002", "测试2", "1", "15666666666", "ry@qq.com", 180.0, "1")); + users.put(3, new UserOperateModel(3, "1000003", "测试3", "0", "15666666666", "ry@qq.com", 110.0, "1")); + users.put(4, new UserOperateModel(4, "1000004", "测试4", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.put(5, new UserOperateModel(5, "1000005", "测试5", "0", "15666666666", "ry@qq.com", 140.0, "1")); + users.put(6, new UserOperateModel(6, "1000006", "测试6", "1", "15666666666", "ry@qq.com", 330.0, "1")); + users.put(7, new UserOperateModel(7, "1000007", "测试7", "0", "15666666666", "ry@qq.com", 160.0, "1")); + users.put(8, new UserOperateModel(8, "1000008", "测试8", "1", "15666666666", "ry@qq.com", 170.0, "1")); + users.put(9, new UserOperateModel(9, "1000009", "测试9", "0", "15666666666", "ry@qq.com", 180.0, "1")); + users.put(10, new UserOperateModel(10, "1000010", "测试10", "0", "15666666666", "ry@qq.com", 210.0, "1")); + users.put(11, new UserOperateModel(11, "1000011", "测试11", "1", "15666666666", "ry@qq.com", 110.0, "1")); + users.put(12, new UserOperateModel(12, "1000012", "测试12", "0", "15666666666", "ry@qq.com", 120.0, "1")); + users.put(13, new UserOperateModel(13, "1000013", "测试13", "1", "15666666666", "ry@qq.com", 380.0, "1")); + users.put(14, new UserOperateModel(14, "1000014", "测试14", "0", "15666666666", "ry@qq.com", 280.0, "1")); + users.put(15, new UserOperateModel(15, "1000015", "测试15", "0", "15666666666", "ry@qq.com", 570.0, "1")); + users.put(16, new UserOperateModel(16, "1000016", "测试16", "1", "15666666666", "ry@qq.com", 260.0, "1")); + users.put(17, new UserOperateModel(17, "1000017", "测试17", "1", "15666666666", "ry@qq.com", 210.0, "1")); + users.put(18, new UserOperateModel(18, "1000018", "测试18", "1", "15666666666", "ry@qq.com", 340.0, "1")); + users.put(19, new UserOperateModel(19, "1000019", "测试19", "1", "15666666666", "ry@qq.com", 160.0, "1")); + users.put(20, new UserOperateModel(20, "1000020", "测试20", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.put(21, new UserOperateModel(21, "1000021", "测试21", "1", "15666666666", "ry@qq.com", 120.0, "1")); + users.put(22, new UserOperateModel(22, "1000022", "测试22", "1", "15666666666", "ry@qq.com", 130.0, "1")); + users.put(23, new UserOperateModel(23, "1000023", "测试23", "1", "15666666666", "ry@qq.com", 490.0, "1")); + users.put(24, new UserOperateModel(24, "1000024", "测试24", "1", "15666666666", "ry@qq.com", 570.0, "1")); + users.put(25, new UserOperateModel(25, "1000025", "测试25", "1", "15666666666", "ry@qq.com", 250.0, "1")); + users.put(26, new UserOperateModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1")); + } + + /** + * 表格 + */ + @GetMapping("/table") + public String table() + { + return prefix + "/table"; + } + + /** + * 其他 + */ + @GetMapping("/other") + public String other() + { + return prefix + "/other"; + } + + /** + * 查询数据 + */ + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(UserOperateModel userModel) + { + TableDataInfo rspData = new TableDataInfo(); + List userList = new ArrayList(users.values()); + // 查询条件过滤 + if (StringUtils.isNotEmpty(userModel.getSearchValue())) + { + userList.clear(); + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(userModel.getSearchValue())) + { + userList.add(entry.getValue()); + } + } + } + else if (StringUtils.isNotEmpty(userModel.getUserName())) + { + userList.clear(); + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(userModel.getUserName())) + { + userList.add(entry.getValue()); + } + } + } + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize()) + { + rspData.setRows(userList); + rspData.setTotal(userList.size()); + return rspData; + } + Integer pageNum = (pageDomain.getPageNum() - 1) * 10; + Integer pageSize = pageDomain.getPageNum() * 10; + if (pageSize > userList.size()) + { + pageSize = userList.size(); + } + rspData.setRows(userList.subList(pageNum, pageSize)); + rspData.setTotal(userList.size()); + return rspData; + } + + /** + * 新增用户 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + return prefix + "/add"; + } + + /** + * 新增保存用户 + */ + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(UserOperateModel user) + { + Integer userId = users.size() + 1; + user.setUserId(userId); + return AjaxResult.success(users.put(userId, user)); + } + + /** + * 新增保存主子表信息 + */ + @PostMapping("/customer/add") + @ResponseBody + public AjaxResult addSave(CustomerModel customerModel) + { + System.out.println(customerModel.toString()); + return AjaxResult.success(); + } + + /** + * 修改用户 + */ + @GetMapping("/edit/{userId}") + public String edit(@PathVariable("userId") Integer userId, ModelMap mmap) + { + mmap.put("user", users.get(userId)); + return prefix + "/edit"; + } + + /** + * 修改保存用户 + */ + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(UserOperateModel user) + { + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + /** + * 导出 + */ + @PostMapping("/export") + @ResponseBody + public AjaxResult export(UserOperateModel user) + { + List list = new ArrayList(users.values()); + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + return util.exportExcel(list, "用户数据"); + } + + /** + * 下载模板 + */ + @GetMapping("/importTemplate") + @ResponseBody + public AjaxResult importTemplate() + { + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + return util.importTemplateExcel("用户数据"); + } + + /** + * 导入数据 + */ + @PostMapping("/importData") + @ResponseBody + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(UserOperateModel.class); + List userList = util.importExcel(file.getInputStream()); + String message = importUser(userList, updateSupport); + return AjaxResult.success(message); + } + + /** + * 删除用户 + */ + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + Integer[] userIds = Convert.toIntArray(ids); + for (Integer userId : userIds) + { + users.remove(userId); + } + return AjaxResult.success(); + } + + /** + * 查看详细 + */ + @GetMapping("/detail/{userId}") + public String detail(@PathVariable("userId") Integer userId, ModelMap mmap) + { + mmap.put("user", users.get(userId)); + return prefix + "/detail"; + } + + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + users.clear(); + return success(); + } + + /** + * 导入用户数据 + * + * @param userList 用户数据列表 + * @param isUpdateSupport 是否更新支持,如果已存在,则进行更新数据 + * @return 结果 + */ + public String importUser(List userList, Boolean isUpdateSupport) + { + if (StringUtils.isNull(userList) || userList.size() == 0) + { + throw new ServiceException("导入用户数据不能为空!"); + } + int successNum = 0; + int failureNum = 0; + StringBuilder successMsg = new StringBuilder(); + StringBuilder failureMsg = new StringBuilder(); + for (UserOperateModel user : userList) + { + try + { + // 验证是否存在这个用户 + boolean userFlag = false; + for (Map.Entry entry : users.entrySet()) + { + if (entry.getValue().getUserName().equals(user.getUserName())) + { + userFlag = true; + break; + } + } + if (!userFlag) + { + Integer userId = users.size() + 1; + user.setUserId(userId); + users.put(userId, user); + successNum++; + successMsg.append("
" + successNum + "、用户 " + user.getUserName() + " 导入成功"); + } + else if (isUpdateSupport) + { + users.put(user.getUserId(), user); + successNum++; + successMsg.append("
" + successNum + "、用户 " + user.getUserName() + " 更新成功"); + } + else + { + failureNum++; + failureMsg.append("
" + failureNum + "、用户 " + user.getUserName() + " 已存在"); + } + } + catch (Exception e) + { + failureNum++; + String msg = "
" + failureNum + "、账号 " + user.getUserName() + " 导入失败:"; + failureMsg.append(msg + e.getMessage()); + } + } + if (failureNum > 0) + { + failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:"); + throw new ServiceException(failureMsg.toString()); + } + else + { + successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:"); + } + return successMsg.toString(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoReportController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoReportController.java new file mode 100644 index 00000000..0e22ca26 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoReportController.java @@ -0,0 +1,53 @@ +package com.ghy.web.controller.demo.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +/** + * 报表 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/report") +public class DemoReportController +{ + private String prefix = "demo/report"; + + /** + * 百度ECharts + */ + @GetMapping("/echarts") + public String echarts() + { + return prefix + "/echarts"; + } + + /** + * 图表插件 + */ + @GetMapping("/peity") + public String peity() + { + return prefix + "/peity"; + } + + /** + * 线状图插件 + */ + @GetMapping("/sparkline") + public String sparkline() + { + return prefix + "/sparkline"; + } + + /** + * 图表组合 + */ + @GetMapping("/metrics") + public String metrics() + { + return prefix + "/metrics"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoTableController.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoTableController.java new file mode 100644 index 00000000..d34b0ebc --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/controller/DemoTableController.java @@ -0,0 +1,599 @@ +package com.ghy.web.controller.demo.controller; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.ghy.common.annotation.Excel; +import com.ghy.common.annotation.Excel.ColumnType; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.PageDomain; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.core.page.TableSupport; +import com.ghy.common.core.text.Convert; +import com.ghy.common.utils.DateUtils; +import com.ghy.common.utils.StringUtils; +import com.ghy.common.utils.poi.ExcelUtil; + +/** + * 表格相关 + * + * @author clunt + */ +@Controller +@RequestMapping("/demo/table") +public class DemoTableController extends BaseController +{ + private String prefix = "demo/table"; + + private final static List users = new ArrayList(); + { + users.add(new UserTableModel(1, "1000001", "测试1", "0", "15888888888", "ry@qq.com", 150.0, "0")); + users.add(new UserTableModel(2, "1000002", "测试2", "1", "15666666666", "ry@qq.com", 180.0, "1")); + users.add(new UserTableModel(3, "1000003", "测试3", "0", "15666666666", "ry@qq.com", 110.0, "1")); + users.add(new UserTableModel(4, "1000004", "测试4", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.add(new UserTableModel(5, "1000005", "测试5", "0", "15666666666", "ry@qq.com", 140.0, "1")); + users.add(new UserTableModel(6, "1000006", "测试6", "1", "15666666666", "ry@qq.com", 330.0, "1")); + users.add(new UserTableModel(7, "1000007", "测试7", "0", "15666666666", "ry@qq.com", 160.0, "1")); + users.add(new UserTableModel(8, "1000008", "测试8", "1", "15666666666", "ry@qq.com", 170.0, "1")); + users.add(new UserTableModel(9, "1000009", "测试9", "0", "15666666666", "ry@qq.com", 180.0, "1")); + users.add(new UserTableModel(10, "1000010", "测试10", "0", "15666666666", "ry@qq.com", 210.0, "1")); + users.add(new UserTableModel(11, "1000011", "测试11", "1", "15666666666", "ry@qq.com", 110.0, "1")); + users.add(new UserTableModel(12, "1000012", "测试12", "0", "15666666666", "ry@qq.com", 120.0, "1")); + users.add(new UserTableModel(13, "1000013", "测试13", "1", "15666666666", "ry@qq.com", 380.0, "1")); + users.add(new UserTableModel(14, "1000014", "测试14", "0", "15666666666", "ry@qq.com", 280.0, "1")); + users.add(new UserTableModel(15, "1000015", "测试15", "0", "15666666666", "ry@qq.com", 570.0, "1")); + users.add(new UserTableModel(16, "1000016", "测试16", "1", "15666666666", "ry@qq.com", 260.0, "1")); + users.add(new UserTableModel(17, "1000017", "测试17", "1", "15666666666", "ry@qq.com", 210.0, "1")); + users.add(new UserTableModel(18, "1000018", "测试18", "1", "15666666666", "ry@qq.com", 340.0, "1")); + users.add(new UserTableModel(19, "1000019", "测试19", "1", "15666666666", "ry@qq.com", 160.0, "1")); + users.add(new UserTableModel(20, "1000020", "测试20", "1", "15666666666", "ry@qq.com", 220.0, "1")); + users.add(new UserTableModel(21, "1000021", "测试21", "1", "15666666666", "ry@qq.com", 120.0, "1")); + users.add(new UserTableModel(22, "1000022", "测试22", "1", "15666666666", "ry@qq.com", 130.0, "1")); + users.add(new UserTableModel(23, "1000023", "测试23", "1", "15666666666", "ry@qq.com", 490.0, "1")); + users.add(new UserTableModel(24, "1000024", "测试24", "1", "15666666666", "ry@qq.com", 570.0, "1")); + users.add(new UserTableModel(25, "1000025", "测试25", "1", "15666666666", "ry@qq.com", 250.0, "1")); + users.add(new UserTableModel(26, "1000026", "测试26", "1", "15666666666", "ry@qq.com", 250.0, "1")); + } + + private final static List columns = new ArrayList(); + { + columns.add(new UserTableColumn("用户ID", "userId")); + columns.add(new UserTableColumn("用户编号", "userCode")); + columns.add(new UserTableColumn("用户姓名", "userName")); + columns.add(new UserTableColumn("用户手机", "userPhone")); + columns.add(new UserTableColumn("用户邮箱", "userEmail")); + columns.add(new UserTableColumn("用户状态", "status")); + } + + /** + * 搜索相关 + */ + @GetMapping("/search") + public String search() + { + return prefix + "/search"; + } + + /** + * 数据汇总 + */ + @GetMapping("/footer") + public String footer() + { + return prefix + "/footer"; + } + + /** + * 组合表头 + */ + @GetMapping("/groupHeader") + public String groupHeader() + { + return prefix + "/groupHeader"; + } + + /** + * 表格导出 + */ + @GetMapping("/export") + public String export() + { + return prefix + "/export"; + } + + /** + * 表格导出选择列 + */ + @GetMapping("/exportSelected") + public String exportSelected() + { + return prefix + "/exportSelected"; + } + + /** + * 导出数据 + */ + @PostMapping("/exportData") + @ResponseBody + public AjaxResult exportSelected(UserTableModel userModel, String userIds) + { + List userList = new ArrayList(Arrays.asList(new UserTableModel[users.size()])); + Collections.copy(userList, users); + + // 条件过滤 + if (StringUtils.isNotEmpty(userIds)) + { + userList.clear(); + for (Long userId : Convert.toLongArray(userIds)) + { + for (UserTableModel user : users) + { + if (user.getUserId() == userId) + { + userList.add(user); + } + } + } + } + ExcelUtil util = new ExcelUtil(UserTableModel.class); + return util.exportExcel(userList, "用户数据"); + } + + /** + * 翻页记住选择 + */ + @GetMapping("/remember") + public String remember() + { + return prefix + "/remember"; + } + + /** + * 跳转至指定页 + */ + @GetMapping("/pageGo") + public String pageGo() + { + return prefix + "/pageGo"; + } + + /** + * 自定义查询参数 + */ + @GetMapping("/params") + public String params() + { + return prefix + "/params"; + } + + /** + * 多表格 + */ + @GetMapping("/multi") + public String multi() + { + return prefix + "/multi"; + } + + /** + * 点击按钮加载表格 + */ + @GetMapping("/button") + public String button() + { + return prefix + "/button"; + } + + /** + * 直接加载表格数据 + */ + @GetMapping("/data") + public String data(ModelMap mmap) + { + mmap.put("users", users); + return prefix + "/data"; + } + + /** + * 表格冻结列 + */ + @GetMapping("/fixedColumns") + public String fixedColumns() + { + return prefix + "/fixedColumns"; + } + + /** + * 自定义触发事件 + */ + @GetMapping("/event") + public String event() + { + return prefix + "/event"; + } + + /** + * 表格细节视图 + */ + @GetMapping("/detail") + public String detail() + { + return prefix + "/detail"; + } + + /** + * 表格父子视图 + */ + @GetMapping("/child") + public String child() + { + return prefix + "/child"; + } + + /** + * 表格图片预览 + */ + @GetMapping("/image") + public String image() + { + return prefix + "/image"; + } + + /** + * 动态增删改查 + */ + @GetMapping("/curd") + public String curd() + { + return prefix + "/curd"; + } + + /** + * 表格行拖拽操作 + */ + @GetMapping("/reorderRows") + public String reorderRows() + { + return prefix + "/reorderRows"; + } + + /** + * 表格列拖拽操作 + */ + @GetMapping("/reorderColumns") + public String reorderColumns() + { + return prefix + "/reorderColumns"; + } + + /** + * 表格列宽拖动 + */ + @GetMapping("/resizable") + public String resizable() + { + return prefix + "/resizable"; + } + + /** + * 表格行内编辑操作 + */ + @GetMapping("/editable") + public String editable() + { + return prefix + "/editable"; + } + + /** + * 主子表提交 + */ + @GetMapping("/subdata") + public String subdata() + { + return prefix + "/subdata"; + } + + /** + * 表格自动刷新 + */ + @GetMapping("/refresh") + public String refresh() + { + return prefix + "/refresh"; + } + + /** + * 表格打印配置 + */ + @GetMapping("/print") + public String print() + { + return prefix + "/print"; + } + + /** + * 表格标题格式化 + */ + @GetMapping("/headerStyle") + public String headerStyle() + { + return prefix + "/headerStyle"; + } + + /** + * 表格动态列 + */ + @GetMapping("/dynamicColumns") + public String dynamicColumns() + { + return prefix + "/dynamicColumns"; + } + + /** + * 自定义视图分页 + */ + @GetMapping("/customView") + public String customView() + { + return prefix + "/customView"; + } + + /** + * 表格其他操作 + */ + @GetMapping("/other") + public String other() + { + return prefix + "/other"; + } + + /** + * 动态获取列 + */ + @PostMapping("/ajaxColumns") + @ResponseBody + public AjaxResult ajaxColumns(UserTableColumn userColumn) + { + List columnList = new ArrayList(Arrays.asList(new UserTableColumn[columns.size()])); + Collections.copy(columnList, columns); + if (userColumn != null && "userBalance".equals(userColumn.getField())) + { + columnList.add(new UserTableColumn("用户余额", "userBalance")); + } + return AjaxResult.success(columnList); + } + + /** + * 查询数据 + */ + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(UserTableModel userModel) + { + TableDataInfo rspData = new TableDataInfo(); + List userList = new ArrayList(Arrays.asList(new UserTableModel[users.size()])); + Collections.copy(userList, users); + // 查询条件过滤 + if (StringUtils.isNotEmpty(userModel.getUserName())) + { + userList.clear(); + for (UserTableModel user : users) + { + if (user.getUserName().equals(userModel.getUserName())) + { + userList.add(user); + } + } + } + PageDomain pageDomain = TableSupport.buildPageRequest(); + if (null == pageDomain.getPageNum() || null == pageDomain.getPageSize()) + { + rspData.setRows(userList); + rspData.setTotal(userList.size()); + return rspData; + } + Integer pageNum = (pageDomain.getPageNum() - 1) * 10; + Integer pageSize = pageDomain.getPageNum() * 10; + if (pageSize > userList.size()) + { + pageSize = userList.size(); + } + rspData.setRows(userList.subList(pageNum, pageSize)); + rspData.setTotal(userList.size()); + return rspData; + } +} + +class UserTableColumn +{ + /** 表头 */ + private String title; + /** 字段 */ + private String field; + + public UserTableColumn() + { + + } + + public UserTableColumn(String title, String field) + { + this.title = title; + this.field = field; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getField() + { + return field; + } + + public void setField(String field) + { + this.field = field; + } +} + +class UserTableModel +{ + /** 用户ID */ + private int userId; + + /** 用户编号 */ + @Excel(name = "用户编号", cellType = ColumnType.NUMERIC) + private String userCode; + + /** 用户姓名 */ + @Excel(name = "用户姓名") + private String userName; + + /** 用户性别 */ + private String userSex; + + /** 用户手机 */ + @Excel(name = "用户手机") + private String userPhone; + + /** 用户邮箱 */ + @Excel(name = "用户邮箱") + private String userEmail; + + /** 用户余额 */ + @Excel(name = "用户余额", cellType = ColumnType.NUMERIC) + private double userBalance; + + /** 用户状态(0正常 1停用) */ + private String status; + + /** 创建时间 */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") + private Date createTime; + + public UserTableModel() + { + + } + + public UserTableModel(int userId, String userCode, String userName, String userSex, String userPhone, + String userEmail, double userBalance, String status) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userSex = userSex; + this.userPhone = userPhone; + this.userEmail = userEmail; + this.userBalance = userBalance; + this.status = status; + this.createTime = DateUtils.getNowDate(); + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserSex() + { + return userSex; + } + + public void setUserSex(String userSex) + { + this.userSex = userSex; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + + public String getUserEmail() + { + return userEmail; + } + + public void setUserEmail(String userEmail) + { + this.userEmail = userEmail; + } + + public double getUserBalance() + { + return userBalance; + } + + public void setUserBalance(double userBalance) + { + this.userBalance = userBalance; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + public Date getCreateTime() + { + return createTime; + } + + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/CustomerModel.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/CustomerModel.java new file mode 100644 index 00000000..d9705e64 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/CustomerModel.java @@ -0,0 +1,116 @@ +package com.ghy.web.controller.demo.domain; + +import java.util.List; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 客户测试信息 + * + * @author clunt + */ +public class CustomerModel +{ + /** + * 客户姓名 + */ + private String name; + + /** + * 客户手机 + */ + private String phonenumber; + + /** + * 客户性别 + */ + private String sex; + + /** + * 客户生日 + */ + private String birthday; + + /** + * 客户描述 + */ + private String remark; + + /** + * 商品信息 + */ + private List goods; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public String getPhonenumber() + { + return phonenumber; + } + + public void setPhonenumber(String phonenumber) + { + this.phonenumber = phonenumber; + } + + + public String getSex() + { + return sex; + } + + public void setSex(String sex) + { + this.sex = sex; + } + + public String getBirthday() + { + return birthday; + } + + public void setBirthday(String birthday) + { + this.birthday = birthday; + } + + public String getRemark() + { + return remark; + } + + public void setRemark(String remark) + { + this.remark = remark; + } + + public List getGoods() + { + return goods; + } + + public void setGoods(List goods) + { + this.goods = goods; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("phonenumber", getPhonenumber()) + .append("sex", getSex()) + .append("birthday", getBirthday()) + .append("goods", getGoods()) + .append("remark", getRemark()) + .toString(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/GoodsModel.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/GoodsModel.java new file mode 100644 index 00000000..bf2251c7 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/GoodsModel.java @@ -0,0 +1,99 @@ +package com.ghy.web.controller.demo.domain; + +import java.util.Date; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.builder.ToStringStyle; + +/** + * 商品测试信息 + * + * @author clunt + */ +public class GoodsModel +{ + /** + * 商品名称 + */ + private String name; + + /** + * 商品重量 + */ + private Integer weight; + + /** + * 商品价格 + */ + private Double price; + + /** + * 商品日期 + */ + private Date date; + + /** + * 商品种类 + */ + private String type; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + public Integer getWeight() + { + return weight; + } + + public void setWeight(Integer weight) + { + this.weight = weight; + } + + public Double getPrice() + { + return price; + } + + public void setPrice(Double price) + { + this.price = price; + } + + public Date getDate() + { + return date; + } + + public void setDate(Date date) + { + this.date = date; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + @Override + public String toString() { + return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) + .append("name", getName()) + .append("weight", getWeight()) + .append("price", getPrice()) + .append("date", getDate()) + .append("type", getType()) + .toString(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/UserOperateModel.java b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/UserOperateModel.java new file mode 100644 index 00000000..d81f07c3 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/demo/domain/UserOperateModel.java @@ -0,0 +1,152 @@ +package com.ghy.web.controller.demo.domain; + +import java.util.Date; +import com.ghy.common.annotation.Excel; +import com.ghy.common.annotation.Excel.Type; +import com.ghy.common.core.domain.BaseEntity; +import com.ghy.common.utils.DateUtils; + +/** + * @author clunt + */ +public class UserOperateModel extends BaseEntity +{ + private static final long serialVersionUID = 1L; + + private int userId; + + @Excel(name = "用户编号") + private String userCode; + + @Excel(name = "用户姓名") + private String userName; + + @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") + private String userSex; + + @Excel(name = "用户手机") + private String userPhone; + + @Excel(name = "用户邮箱") + private String userEmail; + + @Excel(name = "用户余额") + private double userBalance; + + @Excel(name = "用户状态", readConverterExp = "0=正常,1=停用") + private String status; + + @Excel(name = "创建时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) + private Date createTime; + + public UserOperateModel() + { + + } + + public UserOperateModel(int userId, String userCode, String userName, String userSex, String userPhone, + String userEmail, double userBalance, String status) + { + this.userId = userId; + this.userCode = userCode; + this.userName = userName; + this.userSex = userSex; + this.userPhone = userPhone; + this.userEmail = userEmail; + this.userBalance = userBalance; + this.status = status; + this.createTime = DateUtils.getNowDate(); + } + + public int getUserId() + { + return userId; + } + + public void setUserId(int userId) + { + this.userId = userId; + } + + public String getUserCode() + { + return userCode; + } + + public void setUserCode(String userCode) + { + this.userCode = userCode; + } + + public String getUserName() + { + return userName; + } + + public void setUserName(String userName) + { + this.userName = userName; + } + + public String getUserSex() + { + return userSex; + } + + public void setUserSex(String userSex) + { + this.userSex = userSex; + } + + public String getUserPhone() + { + return userPhone; + } + + public void setUserPhone(String userPhone) + { + this.userPhone = userPhone; + } + + public String getUserEmail() + { + return userEmail; + } + + public void setUserEmail(String userEmail) + { + this.userEmail = userEmail; + } + + public double getUserBalance() + { + return userBalance; + } + + public void setUserBalance(double userBalance) + { + this.userBalance = userBalance; + } + + public String getStatus() + { + return status; + } + + public void setStatus(String status) + { + this.status = status; + } + + @Override + public Date getCreateTime() + { + return createTime; + } + + @Override + public void setCreateTime(Date createTime) + { + this.createTime = createTime; + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/CacheController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/CacheController.java new file mode 100644 index 00000000..feb7400b --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/CacheController.java @@ -0,0 +1,90 @@ +package com.ghy.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.framework.web.service.CacheService; + +/** + * 缓存监控 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/cache") +public class CacheController extends BaseController +{ + private String prefix = "monitor/cache"; + + @Autowired + private CacheService cacheService; + + @RequiresPermissions("monitor:cache:view") + @GetMapping() + public String cache(ModelMap mmap) + { + mmap.put("cacheNames", cacheService.getCacheNames()); + return prefix + "/cache"; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getNames") + public String getCacheNames(String fragment, ModelMap mmap) + { + mmap.put("cacheNames", cacheService.getCacheNames()); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getKeys") + public String getCacheKeys(String fragment, String cacheName, ModelMap mmap) + { + mmap.put("cacheName", cacheName); + mmap.put("cacheKyes", cacheService.getCacheKeys(cacheName)); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/getValue") + public String getCacheValue(String fragment, String cacheName, String cacheKey, ModelMap mmap) + { + mmap.put("cacheName", cacheName); + mmap.put("cacheKey", cacheKey); + mmap.put("cacheValue", cacheService.getCacheValue(cacheName, cacheKey)); + return prefix + "/cache::" + fragment; + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/clearCacheName") + @ResponseBody + public AjaxResult clearCacheName(String cacheName, ModelMap mmap) + { + cacheService.clearCacheName(cacheName); + return AjaxResult.success(); + } + + @RequiresPermissions("monitor:cache:view") + @PostMapping("/clearCacheKey") + @ResponseBody + public AjaxResult clearCacheKey(String cacheName, String cacheKey, ModelMap mmap) + { + cacheService.clearCacheKey(cacheName, cacheKey); + return AjaxResult.success(); + } + + @RequiresPermissions("monitor:cache:view") + @GetMapping("/clearAll") + @ResponseBody + public AjaxResult clearAll(ModelMap mmap) + { + cacheService.clearAll(); + return AjaxResult.success(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/DruidController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/DruidController.java new file mode 100644 index 00000000..73038748 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/DruidController.java @@ -0,0 +1,26 @@ +package com.ghy.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ghy.common.core.controller.BaseController; + +/** + * druid 监控 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/data") +public class DruidController extends BaseController +{ + private String prefix = "/druid"; + + @RequiresPermissions("monitor:data:view") + @GetMapping() + public String index() + { + return redirect(prefix + "/index.html"); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/ServerController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/ServerController.java new file mode 100644 index 00000000..ef6642a3 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/ServerController.java @@ -0,0 +1,31 @@ +package com.ghy.web.controller.monitor; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ghy.common.core.controller.BaseController; +import com.ghy.framework.web.domain.Server; + +/** + * 服务器监控 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/server") +public class ServerController extends BaseController +{ + private String prefix = "monitor/server"; + + @RequiresPermissions("monitor:server:view") + @GetMapping() + public String server(ModelMap mmap) throws Exception + { + Server server = new Server(); + server.copyTo(); + mmap.put("server", server); + return prefix + "/server"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysLogininforController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysLogininforController.java new file mode 100644 index 00000000..b955318e --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysLogininforController.java @@ -0,0 +1,94 @@ +package com.ghy.web.controller.monitor; + +import java.util.List; +import com.ghy.framework.shiro.service.SysPasswordService; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.domain.SysLogininfor; +import com.ghy.system.service.ISysLogininforService; + +/** + * 系统访问记录 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/logininfor") +public class SysLogininforController extends BaseController +{ + private String prefix = "monitor/logininfor"; + + @Autowired + private ISysLogininforService logininforService; + + @Autowired + private SysPasswordService passwordService; + + @RequiresPermissions("monitor:logininfor:view") + @GetMapping() + public String logininfor() + { + return prefix + "/logininfor"; + } + + @RequiresPermissions("monitor:logininfor:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysLogininfor logininfor) + { + startPage(); + List list = logininforService.selectLogininforList(logininfor); + return getDataTable(list); + } + + @Log(title = "登录日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("monitor:logininfor:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysLogininfor logininfor) + { + List list = logininforService.selectLogininforList(logininfor); + ExcelUtil util = new ExcelUtil(SysLogininfor.class); + return util.exportExcel(list, "登录日志"); + } + + @RequiresPermissions("monitor:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(logininforService.deleteLogininforByIds(ids)); + } + + @RequiresPermissions("monitor:logininfor:remove") + @Log(title = "登录日志", businessType = BusinessType.CLEAN) + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + logininforService.cleanLogininfor(); + return success(); + } + + @RequiresPermissions("monitor:logininfor:unlock") + @Log(title = "账户解锁", businessType = BusinessType.OTHER) + @PostMapping("/unlock") + @ResponseBody + public AjaxResult unlock(String loginName) + { + passwordService.clearLoginRecordCache(loginName); + return success(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysOperlogController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysOperlogController.java new file mode 100644 index 00000000..594f1735 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysOperlogController.java @@ -0,0 +1,90 @@ +package com.ghy.web.controller.monitor; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.domain.SysOperLog; +import com.ghy.system.service.ISysOperLogService; + +/** + * 操作日志记录 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/operlog") +public class SysOperlogController extends BaseController +{ + private String prefix = "monitor/operlog"; + + @Autowired + private ISysOperLogService operLogService; + + @RequiresPermissions("monitor:operlog:view") + @GetMapping() + public String operlog() + { + return prefix + "/operlog"; + } + + @RequiresPermissions("monitor:operlog:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysOperLog operLog) + { + startPage(); + List list = operLogService.selectOperLogList(operLog); + return getDataTable(list); + } + + @Log(title = "操作日志", businessType = BusinessType.EXPORT) + @RequiresPermissions("monitor:operlog:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysOperLog operLog) + { + List list = operLogService.selectOperLogList(operLog); + ExcelUtil util = new ExcelUtil(SysOperLog.class); + return util.exportExcel(list, "操作日志"); + } + + @Log(title = "操作日志", businessType = BusinessType.DELETE) + @RequiresPermissions("monitor:operlog:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(operLogService.deleteOperLogByIds(ids)); + } + + @RequiresPermissions("monitor:operlog:detail") + @GetMapping("/detail/{operId}") + public String detail(@PathVariable("operId") Long operId, ModelMap mmap) + { + mmap.put("operLog", operLogService.selectOperLogById(operId)); + return prefix + "/detail"; + } + + @Log(title = "操作日志", businessType = BusinessType.CLEAN) + @RequiresPermissions("monitor:operlog:remove") + @PostMapping("/clean") + @ResponseBody + public AjaxResult clean() + { + operLogService.cleanOperLog(); + return success(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysUserOnlineController.java b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysUserOnlineController.java new file mode 100644 index 00000000..5deb6f0c --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/monitor/SysUserOnlineController.java @@ -0,0 +1,88 @@ +package com.ghy.web.controller.monitor; + +import java.util.List; +import org.apache.shiro.authz.annotation.Logical; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.core.text.Convert; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.enums.OnlineStatus; +import com.ghy.common.utils.ShiroUtils; +import com.ghy.framework.shiro.session.OnlineSession; +import com.ghy.framework.shiro.session.OnlineSessionDAO; +import com.ghy.system.domain.SysUserOnline; +import com.ghy.system.service.ISysUserOnlineService; + +/** + * 在线用户监控 + * + * @author clunt + */ +@Controller +@RequestMapping("/monitor/online") +public class SysUserOnlineController extends BaseController +{ + private String prefix = "monitor/online"; + + @Autowired + private ISysUserOnlineService userOnlineService; + + @Autowired + private OnlineSessionDAO onlineSessionDAO; + + @RequiresPermissions("monitor:online:view") + @GetMapping() + public String online() + { + return prefix + "/online"; + } + + @RequiresPermissions("monitor:online:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysUserOnline userOnline) + { + startPage(); + List list = userOnlineService.selectUserOnlineList(userOnline); + return getDataTable(list); + } + + @RequiresPermissions(value = { "monitor:online:batchForceLogout", "monitor:online:forceLogout" }, logical = Logical.OR) + @Log(title = "在线用户", businessType = BusinessType.FORCE) + @PostMapping("/batchForceLogout") + @ResponseBody + public AjaxResult batchForceLogout(String ids) + { + for (String sessionId : Convert.toStrArray(ids)) + { + SysUserOnline online = userOnlineService.selectOnlineById(sessionId); + if (online == null) + { + return error("用户已下线"); + } + OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId()); + if (onlineSession == null) + { + return error("用户已下线"); + } + if (sessionId.equals(ShiroUtils.getSessionId())) + { + return error("当前登录用户无法强退"); + } + onlineSessionDAO.delete(onlineSession); + online.setStatus(OnlineStatus.off_line); + userOnlineService.saveOnline(online); + userOnlineService.removeUserCache(online.getLoginName(), sessionId); + } + return success(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysCaptchaController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysCaptchaController.java new file mode 100644 index 00000000..8b5157e7 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysCaptchaController.java @@ -0,0 +1,92 @@ +package com.ghy.web.controller.system; + +import java.awt.image.BufferedImage; +import java.io.IOException; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; +import com.google.code.kaptcha.Constants; +import com.google.code.kaptcha.Producer; +import com.ghy.common.core.controller.BaseController; + +/** + * 图片验证码(支持算术形式) + * + * @author clunt + */ +@Controller +@RequestMapping("/captcha") +public class SysCaptchaController extends BaseController +{ + @Resource(name = "captchaProducer") + private Producer captchaProducer; + + @Resource(name = "captchaProducerMath") + private Producer captchaProducerMath; + + /** + * 验证码生成 + */ + @GetMapping(value = "/captchaImage") + public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) + { + ServletOutputStream out = null; + try + { + HttpSession session = request.getSession(); + response.setDateHeader("Expires", 0); + response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate"); + response.addHeader("Cache-Control", "post-check=0, pre-check=0"); + response.setHeader("Pragma", "no-cache"); + response.setContentType("image/jpeg"); + + String type = request.getParameter("type"); + String capStr = null; + String code = null; + BufferedImage bi = null; + if ("math".equals(type)) + { + String capText = captchaProducerMath.createText(); + capStr = capText.substring(0, capText.lastIndexOf("@")); + code = capText.substring(capText.lastIndexOf("@") + 1); + bi = captchaProducerMath.createImage(capStr); + } + else if ("char".equals(type)) + { + capStr = code = captchaProducer.createText(); + bi = captchaProducer.createImage(capStr); + } + session.setAttribute(Constants.KAPTCHA_SESSION_KEY, code); + out = response.getOutputStream(); + ImageIO.write(bi, "jpg", out); + out.flush(); + + } + catch (Exception e) + { + e.printStackTrace(); + } + finally + { + try + { + if (out != null) + { + out.close(); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + } + return null; + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysConfigController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysConfigController.java new file mode 100644 index 00000000..1d9ae5f0 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysConfigController.java @@ -0,0 +1,158 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.domain.SysConfig; +import com.ghy.system.service.ISysConfigService; + +/** + * 参数配置 信息操作处理 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/config") +public class SysConfigController extends BaseController +{ + private String prefix = "system/config"; + + @Autowired + private ISysConfigService configService; + + @RequiresPermissions("system:config:view") + @GetMapping() + public String config() + { + return prefix + "/config"; + } + + /** + * 查询参数配置列表 + */ + @RequiresPermissions("system:config:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysConfig config) + { + startPage(); + List list = configService.selectConfigList(config); + return getDataTable(list); + } + + @Log(title = "参数管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:config:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysConfig config) + { + List list = configService.selectConfigList(config); + ExcelUtil util = new ExcelUtil(SysConfig.class); + return util.exportExcel(list, "参数数据"); + } + + /** + * 新增参数配置 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存参数配置 + */ + @RequiresPermissions("system:config:add") + @Log(title = "参数管理", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysConfig config) + { + if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setCreateBy(getLoginName()); + return toAjax(configService.insertConfig(config)); + } + + /** + * 修改参数配置 + */ + @RequiresPermissions("system:config:edit") + @GetMapping("/edit/{configId}") + public String edit(@PathVariable("configId") Long configId, ModelMap mmap) + { + mmap.put("config", configService.selectConfigById(configId)); + return prefix + "/edit"; + } + + /** + * 修改保存参数配置 + */ + @RequiresPermissions("system:config:edit") + @Log(title = "参数管理", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysConfig config) + { + if (UserConstants.CONFIG_KEY_NOT_UNIQUE.equals(configService.checkConfigKeyUnique(config))) + { + return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); + } + config.setUpdateBy(getLoginName()); + return toAjax(configService.updateConfig(config)); + } + + /** + * 删除参数配置 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + configService.deleteConfigByIds(ids); + return success(); + } + + /** + * 刷新参数缓存 + */ + @RequiresPermissions("system:config:remove") + @Log(title = "参数管理", businessType = BusinessType.CLEAN) + @GetMapping("/refreshCache") + @ResponseBody + public AjaxResult refreshCache() + { + configService.resetConfigCache(); + return success(); + } + + /** + * 校验参数键名 + */ + @PostMapping("/checkConfigKeyUnique") + @ResponseBody + public String checkConfigKeyUnique(SysConfig config) + { + return configService.checkConfigKeyUnique(config); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDeptController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDeptController.java new file mode 100644 index 00000000..99e866c0 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDeptController.java @@ -0,0 +1,208 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.Ztree; +import com.ghy.common.core.domain.entity.SysDept; +import com.ghy.common.core.domain.entity.SysRole; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.StringUtils; +import com.ghy.system.service.ISysDeptService; + +/** + * 部门信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/dept") +public class SysDeptController extends BaseController +{ + private String prefix = "system/dept"; + + @Autowired + private ISysDeptService deptService; + + @RequiresPermissions("system:dept:view") + @GetMapping() + public String dept() + { + return prefix + "/dept"; + } + + @RequiresPermissions("system:dept:list") + @PostMapping("/list") + @ResponseBody + public List list(SysDept dept) + { + List deptList = deptService.selectDeptList(dept); + return deptList; + } + + /** + * 新增部门 + */ + @GetMapping("/add/{parentId}") + public String add(@PathVariable("parentId") Long parentId, ModelMap mmap) + { + if (!getSysUser().isAdmin()) + { + parentId = getSysUser().getDeptId(); + } + mmap.put("dept", deptService.selectDeptById(parentId)); + return prefix + "/add"; + } + + /** + * 新增保存部门 + */ + @Log(title = "部门管理", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dept:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDept dept) + { + if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + dept.setCreateBy(getLoginName()); + return toAjax(deptService.insertDept(dept)); + } + + /** + * 修改部门 + */ + @RequiresPermissions("system:dept:edit") + @GetMapping("/edit/{deptId}") + public String edit(@PathVariable("deptId") Long deptId, ModelMap mmap) + { + deptService.checkDeptDataScope(deptId); + SysDept dept = deptService.selectDeptById(deptId); + if (StringUtils.isNotNull(dept) && 100L == deptId) + { + dept.setParentName("无"); + } + mmap.put("dept", dept); + return prefix + "/edit"; + } + + /** + * 修改保存部门 + */ + @Log(title = "部门管理", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dept:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDept dept) + { + if (UserConstants.DEPT_NAME_NOT_UNIQUE.equals(deptService.checkDeptNameUnique(dept))) + { + return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); + } + else if (dept.getParentId().equals(dept.getDeptId())) + { + return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); + } + else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) + && deptService.selectNormalChildrenDeptById(dept.getDeptId()) > 0) + { + return AjaxResult.error("该部门包含未停用的子部门!"); + } + dept.setUpdateBy(getLoginName()); + return toAjax(deptService.updateDept(dept)); + } + + /** + * 删除 + */ + @Log(title = "部门管理", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dept:remove") + @GetMapping("/remove/{deptId}") + @ResponseBody + public AjaxResult remove(@PathVariable("deptId") Long deptId) + { + if (deptService.selectDeptCount(deptId) > 0) + { + return AjaxResult.warn("存在下级部门,不允许删除"); + } + if (deptService.checkDeptExistUser(deptId)) + { + return AjaxResult.warn("部门存在用户,不允许删除"); + } + return toAjax(deptService.deleteDeptById(deptId)); + } + + /** + * 校验部门名称 + */ + @PostMapping("/checkDeptNameUnique") + @ResponseBody + public String checkDeptNameUnique(SysDept dept) + { + return deptService.checkDeptNameUnique(dept); + } + + /** + * 选择部门树 + * + * @param deptId 部门ID + * @param excludeId 排除ID + */ + @GetMapping(value = { "/selectDeptTree/{deptId}", "/selectDeptTree/{deptId}/{excludeId}" }) + public String selectDeptTree(@PathVariable("deptId") Long deptId, + @PathVariable(value = "excludeId", required = false) String excludeId, ModelMap mmap) + { + mmap.put("dept", deptService.selectDeptById(deptId)); + mmap.put("excludeId", excludeId); + return prefix + "/tree"; + } + + /** + * 加载部门列表树 + */ + @GetMapping("/treeData") + @ResponseBody + public List treeData() + { + List ztrees = deptService.selectDeptTree(new SysDept()); + return ztrees; + } + + /** + * 加载部门列表树(排除下级) + */ + @GetMapping("/treeData/{excludeId}") + @ResponseBody + public List treeDataExcludeChild(@PathVariable(value = "excludeId", required = false) Long excludeId) + { + SysDept dept = new SysDept(); + dept.setExcludeId(excludeId); + List ztrees = deptService.selectDeptTreeExcludeChild(dept); + return ztrees; + } + + /** + * 加载角色部门(数据权限)列表树 + */ + @GetMapping("/roleDeptTreeData") + @ResponseBody + public List deptTreeData(SysRole role) + { + List ztrees = deptService.roleDeptTreeData(role); + return ztrees; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictDataController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictDataController.java new file mode 100644 index 00000000..df0f9ba3 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictDataController.java @@ -0,0 +1,121 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysDictData; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.service.ISysDictDataService; + +/** + * 数据字典信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/dict/data") +public class SysDictDataController extends BaseController +{ + private String prefix = "system/dict/data"; + + @Autowired + private ISysDictDataService dictDataService; + + @RequiresPermissions("system:dict:view") + @GetMapping() + public String dictData() + { + return prefix + "/data"; + } + + @PostMapping("/list") + @RequiresPermissions("system:dict:list") + @ResponseBody + public TableDataInfo list(SysDictData dictData) + { + startPage(); + List list = dictDataService.selectDictDataList(dictData); + return getDataTable(list); + } + + @Log(title = "字典数据", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysDictData dictData) + { + List list = dictDataService.selectDictDataList(dictData); + ExcelUtil util = new ExcelUtil(SysDictData.class); + return util.exportExcel(list, "字典数据"); + } + + /** + * 新增字典类型 + */ + @GetMapping("/add/{dictType}") + public String add(@PathVariable("dictType") String dictType, ModelMap mmap) + { + mmap.put("dictType", dictType); + return prefix + "/add"; + } + + /** + * 新增保存字典类型 + */ + @Log(title = "字典数据", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dict:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDictData dict) + { + dict.setCreateBy(getLoginName()); + return toAjax(dictDataService.insertDictData(dict)); + } + + /** + * 修改字典类型 + */ + @RequiresPermissions("system:dict:edit") + @GetMapping("/edit/{dictCode}") + public String edit(@PathVariable("dictCode") Long dictCode, ModelMap mmap) + { + mmap.put("dict", dictDataService.selectDictDataById(dictCode)); + return prefix + "/edit"; + } + + /** + * 修改保存字典类型 + */ + @Log(title = "字典数据", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dict:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDictData dict) + { + dict.setUpdateBy(getLoginName()); + return toAjax(dictDataService.updateDictData(dict)); + } + + @Log(title = "字典数据", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dict:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + dictDataService.deleteDictDataByIds(ids); + return success(); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictTypeController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictTypeController.java new file mode 100644 index 00000000..8054eda5 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysDictTypeController.java @@ -0,0 +1,189 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.Ztree; +import com.ghy.common.core.domain.entity.SysDictType; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.service.ISysDictTypeService; + +/** + * 数据字典信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/dict") +public class SysDictTypeController extends BaseController +{ + private String prefix = "system/dict/type"; + + @Autowired + private ISysDictTypeService dictTypeService; + + @RequiresPermissions("system:dict:view") + @GetMapping() + public String dictType() + { + return prefix + "/type"; + } + + @PostMapping("/list") + @RequiresPermissions("system:dict:list") + @ResponseBody + public TableDataInfo list(SysDictType dictType) + { + startPage(); + List list = dictTypeService.selectDictTypeList(dictType); + return getDataTable(list); + } + + @Log(title = "字典类型", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:dict:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysDictType dictType) + { + + List list = dictTypeService.selectDictTypeList(dictType); + ExcelUtil util = new ExcelUtil(SysDictType.class); + return util.exportExcel(list, "字典类型"); + } + + /** + * 新增字典类型 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存字典类型 + */ + @Log(title = "字典类型", businessType = BusinessType.INSERT) + @RequiresPermissions("system:dict:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysDictType dict) + { + if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setCreateBy(getLoginName()); + return toAjax(dictTypeService.insertDictType(dict)); + } + + /** + * 修改字典类型 + */ + @RequiresPermissions("system:dict:edit") + @GetMapping("/edit/{dictId}") + public String edit(@PathVariable("dictId") Long dictId, ModelMap mmap) + { + mmap.put("dict", dictTypeService.selectDictTypeById(dictId)); + return prefix + "/edit"; + } + + /** + * 修改保存字典类型 + */ + @Log(title = "字典类型", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:dict:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysDictType dict) + { + if (UserConstants.DICT_TYPE_NOT_UNIQUE.equals(dictTypeService.checkDictTypeUnique(dict))) + { + return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); + } + dict.setUpdateBy(getLoginName()); + return toAjax(dictTypeService.updateDictType(dict)); + } + + @Log(title = "字典类型", businessType = BusinessType.DELETE) + @RequiresPermissions("system:dict:remove") + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + dictTypeService.deleteDictTypeByIds(ids); + return success(); + } + + /** + * 刷新字典缓存 + */ + @RequiresPermissions("system:dict:remove") + @Log(title = "字典类型", businessType = BusinessType.CLEAN) + @GetMapping("/refreshCache") + @ResponseBody + public AjaxResult refreshCache() + { + dictTypeService.resetDictCache(); + return success(); + } + + /** + * 查询字典详细 + */ + @RequiresPermissions("system:dict:list") + @GetMapping("/detail/{dictId}") + public String detail(@PathVariable("dictId") Long dictId, ModelMap mmap) + { + mmap.put("dict", dictTypeService.selectDictTypeById(dictId)); + mmap.put("dictList", dictTypeService.selectDictTypeAll()); + return "system/dict/data/data"; + } + + /** + * 校验字典类型 + */ + @PostMapping("/checkDictTypeUnique") + @ResponseBody + public String checkDictTypeUnique(SysDictType dictType) + { + return dictTypeService.checkDictTypeUnique(dictType); + } + + /** + * 选择字典树 + */ + @GetMapping("/selectDictTree/{columnId}/{dictType}") + public String selectDeptTree(@PathVariable("columnId") Long columnId, @PathVariable("dictType") String dictType, + ModelMap mmap) + { + mmap.put("columnId", columnId); + mmap.put("dict", dictTypeService.selectDictTypeByType(dictType)); + return prefix + "/tree"; + } + + /** + * 加载字典列表树 + */ + @GetMapping("/treeData") + @ResponseBody + public List treeData() + { + List ztrees = dictTypeService.selectDictTree(new SysDictType()); + return ztrees; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysIndexController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysIndexController.java new file mode 100644 index 00000000..da3d3e39 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysIndexController.java @@ -0,0 +1,178 @@ +package com.ghy.web.controller.system; + +import java.util.Date; +import java.util.List; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.config.GhyConfig; +import com.ghy.common.constant.ShiroConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysMenu; +import com.ghy.common.core.domain.entity.SysUser; +import com.ghy.common.core.text.Convert; +import com.ghy.common.utils.CookieUtils; +import com.ghy.common.utils.DateUtils; +import com.ghy.common.utils.ServletUtils; +import com.ghy.common.utils.StringUtils; +import com.ghy.framework.shiro.service.SysPasswordService; +import com.ghy.system.service.ISysConfigService; +import com.ghy.system.service.ISysMenuService; + +/** + * 首页 业务处理 + * + * @author clunt + */ +@Controller +public class SysIndexController extends BaseController +{ + @Autowired + private ISysMenuService menuService; + + @Autowired + private ISysConfigService configService; + + @Autowired + private SysPasswordService passwordService; + + // 系统首页 + @GetMapping("/index") + public String index(ModelMap mmap) + { + // 取身份信息 + SysUser user = getSysUser(); + // 根据用户id取出菜单 + List menus = menuService.selectMenusByUser(user); + mmap.put("menus", menus); + mmap.put("user", user); + mmap.put("sideTheme", configService.selectConfigByKey("sys.index.sideTheme")); + mmap.put("skinName", configService.selectConfigByKey("sys.index.skinName")); + Boolean footer = Convert.toBool(configService.selectConfigByKey("sys.index.footer"), true); + Boolean tagsView = Convert.toBool(configService.selectConfigByKey("sys.index.tagsView"), true); + mmap.put("footer", footer); + mmap.put("tagsView", tagsView); + mmap.put("mainClass", contentMainClass(footer, tagsView)); + mmap.put("copyrightYear", GhyConfig.getCopyrightYear()); + mmap.put("demoEnabled", GhyConfig.isDemoEnabled()); + mmap.put("isDefaultModifyPwd", initPasswordIsModify(user.getPwdUpdateDate())); + mmap.put("isPasswordExpired", passwordIsExpiration(user.getPwdUpdateDate())); + mmap.put("isMobile", ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent"))); + + // 菜单导航显示风格 + String menuStyle = configService.selectConfigByKey("sys.index.menuStyle"); + // 移动端,默认使左侧导航菜单,否则取默认配置 + String indexStyle = ServletUtils.checkAgentIsMobile(ServletUtils.getRequest().getHeader("User-Agent")) ? "index" : menuStyle; + + // 优先Cookie配置导航菜单 + Cookie[] cookies = ServletUtils.getRequest().getCookies(); + for (Cookie cookie : cookies) + { + if (StringUtils.isNotEmpty(cookie.getName()) && "nav-style".equalsIgnoreCase(cookie.getName())) + { + indexStyle = cookie.getValue(); + break; + } + } + String webIndex = "topnav".equalsIgnoreCase(indexStyle) ? "index-topnav" : "index"; + return webIndex; + } + + // 锁定屏幕 + @GetMapping("/lockscreen") + public String lockscreen(ModelMap mmap) + { + mmap.put("user", getSysUser()); + ServletUtils.getSession().setAttribute(ShiroConstants.LOCK_SCREEN, true); + return "lock"; + } + + // 解锁屏幕 + @PostMapping("/unlockscreen") + @ResponseBody + public AjaxResult unlockscreen(String password) + { + SysUser user = getSysUser(); + if (StringUtils.isNull(user)) + { + return AjaxResult.error("服务器超时,请重新登录"); + } + if (passwordService.matches(user, password)) + { + ServletUtils.getSession().removeAttribute(ShiroConstants.LOCK_SCREEN); + return AjaxResult.success(); + } + return AjaxResult.error("密码不正确,请重新输入。"); + } + + // 切换主题 + @GetMapping("/system/switchSkin") + public String switchSkin() + { + return "skin"; + } + + // 切换菜单 + @GetMapping("/system/menuStyle/{style}") + public void menuStyle(@PathVariable String style, HttpServletResponse response) + { + CookieUtils.setCookie(response, "nav-style", style); + } + + // 系统介绍 + @GetMapping("/system/main") + public String main(ModelMap mmap) + { + mmap.put("version", GhyConfig.getVersion()); + return "main"; + } + + // content-main class + public String contentMainClass(Boolean footer, Boolean tagsView) + { + if (!footer && !tagsView) + { + return "tagsview-footer-hide"; + } + else if (!footer) + { + return "footer-hide"; + } + else if (!tagsView) + { + return "tagsview-hide"; + } + return StringUtils.EMPTY; + } + + // 检查初始密码是否提醒修改 + public boolean initPasswordIsModify(Date pwdUpdateDate) + { + Integer initPasswordModify = Convert.toInt(configService.selectConfigByKey("sys.account.initPasswordModify")); + return initPasswordModify != null && initPasswordModify == 1 && pwdUpdateDate == null; + } + + // 检查密码是否过期 + public boolean passwordIsExpiration(Date pwdUpdateDate) + { + Integer passwordValidateDays = Convert.toInt(configService.selectConfigByKey("sys.account.passwordValidateDays")); + if (passwordValidateDays != null && passwordValidateDays > 0) + { + if (StringUtils.isNull(pwdUpdateDate)) + { + // 如果从未修改过初始密码,直接提醒过期 + return true; + } + Date nowDate = DateUtils.getNowDate(); + return DateUtils.differentDaysByMillisecond(nowDate, pwdUpdateDate) > passwordValidateDays; + } + return false; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysLoginController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysLoginController.java new file mode 100644 index 00000000..26318498 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysLoginController.java @@ -0,0 +1,82 @@ +package com.ghy.web.controller.system; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.authc.AuthenticationException; +import org.apache.shiro.authc.UsernamePasswordToken; +import org.apache.shiro.subject.Subject; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.text.Convert; +import com.ghy.common.utils.ServletUtils; +import com.ghy.common.utils.StringUtils; +import com.ghy.framework.web.service.ConfigService; + +/** + * 登录验证 + * + * @author clunt + */ +@Controller +public class SysLoginController extends BaseController +{ + /** + * 是否开启记住我功能 + */ + @Value("${shiro.rememberMe.enabled: false}") + private boolean rememberMe; + + @Autowired + private ConfigService configService; + + @GetMapping("/login") + public String login(HttpServletRequest request, HttpServletResponse response, ModelMap mmap) + { + // 如果是Ajax请求,返回Json字符串。 + if (ServletUtils.isAjaxRequest(request)) + { + return ServletUtils.renderString(response, "{\"code\":\"1\",\"msg\":\"未登录或登录超时。请重新登录\"}"); + } + // 是否开启记住我 + mmap.put("isRemembered", rememberMe); + // 是否开启用户注册 + mmap.put("isAllowRegister", Convert.toBool(configService.getKey("sys.account.registerUser"), false)); + return "login"; + } + + @PostMapping("/login") + @ResponseBody + public AjaxResult ajaxLogin(String username, String password, Boolean rememberMe) + { + UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe); + Subject subject = SecurityUtils.getSubject(); + try + { + subject.login(token); + return success(); + } + catch (AuthenticationException e) + { + String msg = "用户或密码错误"; + if (StringUtils.isNotEmpty(e.getMessage())) + { + msg = e.getMessage(); + } + return error(msg); + } + } + + @GetMapping("/unauth") + public String unauth() + { + return "error/unauth"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysMenuController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysMenuController.java new file mode 100644 index 00000000..f2c38998 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysMenuController.java @@ -0,0 +1,198 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.Ztree; +import com.ghy.common.core.domain.entity.SysMenu; +import com.ghy.common.core.domain.entity.SysRole; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.ShiroUtils; +import com.ghy.framework.shiro.util.AuthorizationUtils; +import com.ghy.system.service.ISysMenuService; + +/** + * 菜单信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/menu") +public class SysMenuController extends BaseController +{ + private String prefix = "system/menu"; + + @Autowired + private ISysMenuService menuService; + + @RequiresPermissions("system:menu:view") + @GetMapping() + public String menu() + { + return prefix + "/menu"; + } + + @RequiresPermissions("system:menu:list") + @PostMapping("/list") + @ResponseBody + public List list(SysMenu menu) + { + Long userId = ShiroUtils.getUserId(); + List menuList = menuService.selectMenuList(menu, userId); + return menuList; + } + + /** + * 删除菜单 + */ + @Log(title = "菜单管理", businessType = BusinessType.DELETE) + @RequiresPermissions("system:menu:remove") + @GetMapping("/remove/{menuId}") + @ResponseBody + public AjaxResult remove(@PathVariable("menuId") Long menuId) + { + if (menuService.selectCountMenuByParentId(menuId) > 0) + { + return AjaxResult.warn("存在子菜单,不允许删除"); + } + if (menuService.selectCountRoleMenuByMenuId(menuId) > 0) + { + return AjaxResult.warn("菜单已分配,不允许删除"); + } + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.deleteMenuById(menuId)); + } + + /** + * 新增 + */ + @GetMapping("/add/{parentId}") + public String add(@PathVariable("parentId") Long parentId, ModelMap mmap) + { + SysMenu menu = null; + if (0L != parentId) + { + menu = menuService.selectMenuById(parentId); + } + else + { + menu = new SysMenu(); + menu.setMenuId(0L); + menu.setMenuName("主目录"); + } + mmap.put("menu", menu); + return prefix + "/add"; + } + + /** + * 新增保存菜单 + */ + @Log(title = "菜单管理", businessType = BusinessType.INSERT) + @RequiresPermissions("system:menu:add") + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysMenu menu) + { + if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + menu.setCreateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.insertMenu(menu)); + } + + /** + * 修改菜单 + */ + @RequiresPermissions("system:menu:edit") + @GetMapping("/edit/{menuId}") + public String edit(@PathVariable("menuId") Long menuId, ModelMap mmap) + { + mmap.put("menu", menuService.selectMenuById(menuId)); + return prefix + "/edit"; + } + + /** + * 修改保存菜单 + */ + @Log(title = "菜单管理", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:menu:edit") + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysMenu menu) + { + if (UserConstants.MENU_NAME_NOT_UNIQUE.equals(menuService.checkMenuNameUnique(menu))) + { + return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); + } + menu.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(menuService.updateMenu(menu)); + } + + /** + * 选择菜单图标 + */ + @GetMapping("/icon") + public String icon() + { + return prefix + "/icon"; + } + + /** + * 校验菜单名称 + */ + @PostMapping("/checkMenuNameUnique") + @ResponseBody + public String checkMenuNameUnique(SysMenu menu) + { + return menuService.checkMenuNameUnique(menu); + } + + /** + * 加载角色菜单列表树 + */ + @GetMapping("/roleMenuTreeData") + @ResponseBody + public List roleMenuTreeData(SysRole role) + { + Long userId = ShiroUtils.getUserId(); + List ztrees = menuService.roleMenuTreeData(role, userId); + return ztrees; + } + + /** + * 加载所有菜单列表树 + */ + @GetMapping("/menuTreeData") + @ResponseBody + public List menuTreeData() + { + Long userId = ShiroUtils.getUserId(); + List ztrees = menuService.menuTreeData(userId); + return ztrees; + } + + /** + * 选择菜单树 + */ + @GetMapping("/selectMenuTree/{menuId}") + public String selectMenuTree(@PathVariable("menuId") Long menuId, ModelMap mmap) + { + mmap.put("menu", menuService.selectMenuById(menuId)); + return prefix + "/tree"; + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysNoticeController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysNoticeController.java new file mode 100644 index 00000000..18d5769d --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysNoticeController.java @@ -0,0 +1,113 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.system.domain.SysNotice; +import com.ghy.system.service.ISysNoticeService; + +/** + * 公告 信息操作处理 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/notice") +public class SysNoticeController extends BaseController +{ + private String prefix = "system/notice"; + + @Autowired + private ISysNoticeService noticeService; + + @RequiresPermissions("system:notice:view") + @GetMapping() + public String notice() + { + return prefix + "/notice"; + } + + /** + * 查询公告列表 + */ + @RequiresPermissions("system:notice:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysNotice notice) + { + startPage(); + List list = noticeService.selectNoticeList(notice); + return getDataTable(list); + } + + /** + * 新增公告 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存公告 + */ + @RequiresPermissions("system:notice:add") + @Log(title = "通知公告", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysNotice notice) + { + notice.setCreateBy(getLoginName()); + return toAjax(noticeService.insertNotice(notice)); + } + + /** + * 修改公告 + */ + @RequiresPermissions("system:notice:edit") + @GetMapping("/edit/{noticeId}") + public String edit(@PathVariable("noticeId") Long noticeId, ModelMap mmap) + { + mmap.put("notice", noticeService.selectNoticeById(noticeId)); + return prefix + "/edit"; + } + + /** + * 修改保存公告 + */ + @RequiresPermissions("system:notice:edit") + @Log(title = "通知公告", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysNotice notice) + { + notice.setUpdateBy(getLoginName()); + return toAjax(noticeService.updateNotice(notice)); + } + + /** + * 删除公告 + */ + @RequiresPermissions("system:notice:remove") + @Log(title = "通知公告", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(noticeService.deleteNoticeByIds(ids)); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysPostController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysPostController.java new file mode 100644 index 00000000..4b3db316 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysPostController.java @@ -0,0 +1,163 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.system.domain.SysPost; +import com.ghy.system.service.ISysPostService; + +/** + * 岗位信息操作处理 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/post") +public class SysPostController extends BaseController +{ + private String prefix = "system/post"; + + @Autowired + private ISysPostService postService; + + @RequiresPermissions("system:post:view") + @GetMapping() + public String operlog() + { + return prefix + "/post"; + } + + @RequiresPermissions("system:post:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysPost post) + { + startPage(); + List list = postService.selectPostList(post); + return getDataTable(list); + } + + @Log(title = "岗位管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:post:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysPost post) + { + List list = postService.selectPostList(post); + ExcelUtil util = new ExcelUtil(SysPost.class); + return util.exportExcel(list, "岗位数据"); + } + + @RequiresPermissions("system:post:remove") + @Log(title = "岗位管理", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + try + { + return toAjax(postService.deletePostByIds(ids)); + } + catch (Exception e) + { + return error(e.getMessage()); + } + } + + /** + * 新增岗位 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存岗位 + */ + @RequiresPermissions("system:post:add") + @Log(title = "岗位管理", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysPost post) + { + if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setCreateBy(getLoginName()); + return toAjax(postService.insertPost(post)); + } + + /** + * 修改岗位 + */ + @RequiresPermissions("system:post:edit") + @GetMapping("/edit/{postId}") + public String edit(@PathVariable("postId") Long postId, ModelMap mmap) + { + mmap.put("post", postService.selectPostById(postId)); + return prefix + "/edit"; + } + + /** + * 修改保存岗位 + */ + @RequiresPermissions("system:post:edit") + @Log(title = "岗位管理", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysPost post) + { + if (UserConstants.POST_NAME_NOT_UNIQUE.equals(postService.checkPostNameUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); + } + else if (UserConstants.POST_CODE_NOT_UNIQUE.equals(postService.checkPostCodeUnique(post))) + { + return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); + } + post.setUpdateBy(getLoginName()); + return toAjax(postService.updatePost(post)); + } + + /** + * 校验岗位名称 + */ + @PostMapping("/checkPostNameUnique") + @ResponseBody + public String checkPostNameUnique(SysPost post) + { + return postService.checkPostNameUnique(post); + } + + /** + * 校验岗位编码 + */ + @PostMapping("/checkPostCodeUnique") + @ResponseBody + public String checkPostCodeUnique(SysPost post) + { + return postService.checkPostCodeUnique(post); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysProfileController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysProfileController.java new file mode 100644 index 00000000..8db3a0a0 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysProfileController.java @@ -0,0 +1,187 @@ +package com.ghy.web.controller.system; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ghy.common.annotation.Log; +import com.ghy.common.config.GhyConfig; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysUser; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.DateUtils; +import com.ghy.common.utils.ShiroUtils; +import com.ghy.common.utils.StringUtils; +import com.ghy.common.utils.file.FileUploadUtils; +import com.ghy.framework.shiro.service.SysPasswordService; +import com.ghy.system.service.ISysUserService; + +/** + * 个人信息 业务处理 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/user/profile") +public class SysProfileController extends BaseController +{ + private static final Logger log = LoggerFactory.getLogger(SysProfileController.class); + + private String prefix = "system/user/profile"; + + @Autowired + private ISysUserService userService; + + @Autowired + private SysPasswordService passwordService; + + /** + * 个人信息 + */ + @GetMapping() + public String profile(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", user); + mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId())); + mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId())); + return prefix + "/profile"; + } + + @GetMapping("/checkPassword") + @ResponseBody + public boolean checkPassword(String password) + { + SysUser user = getSysUser(); + if (passwordService.matches(user, password)) + { + return true; + } + return false; + } + + @GetMapping("/resetPwd") + public String resetPwd(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/resetPwd"; + } + + @Log(title = "重置密码", businessType = BusinessType.UPDATE) + @PostMapping("/resetPwd") + @ResponseBody + public AjaxResult resetPwd(String oldPassword, String newPassword) + { + SysUser user = getSysUser(); + if (!passwordService.matches(user, oldPassword)) + { + return error("修改密码失败,旧密码错误"); + } + if (passwordService.matches(user, newPassword)) + { + return error("新密码不能与旧密码相同"); + } + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt())); + user.setPwdUpdateDate(DateUtils.getNowDate()); + if (userService.resetUserPwd(user) > 0) + { + setSysUser(userService.selectUserById(user.getUserId())); + return success(); + } + return error("修改密码异常,请联系管理员"); + } + + /** + * 修改用户 + */ + @GetMapping("/edit") + public String edit(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/edit"; + } + + /** + * 修改头像 + */ + @GetMapping("/avatar") + public String avatar(ModelMap mmap) + { + SysUser user = getSysUser(); + mmap.put("user", userService.selectUserById(user.getUserId())); + return prefix + "/avatar"; + } + + /** + * 修改用户 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PostMapping("/update") + @ResponseBody + public AjaxResult update(SysUser user) + { + SysUser currentUser = getSysUser(); + currentUser.setUserName(user.getUserName()); + currentUser.setEmail(user.getEmail()); + currentUser.setPhonenumber(user.getPhonenumber()); + currentUser.setSex(user.getSex()); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser))) + { + return error("修改用户'" + currentUser.getLoginName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser))) + { + return error("修改用户'" + currentUser.getLoginName() + "'失败,邮箱账号已存在"); + } + if (userService.updateUserInfo(currentUser) > 0) + { + setSysUser(userService.selectUserById(currentUser.getUserId())); + return success(); + } + return error(); + } + + /** + * 保存头像 + */ + @Log(title = "个人信息", businessType = BusinessType.UPDATE) + @PostMapping("/updateAvatar") + @ResponseBody + public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file) + { + SysUser currentUser = getSysUser(); + try + { + if (!file.isEmpty()) + { + String avatar = FileUploadUtils.upload(GhyConfig.getAvatarPath(), file); + currentUser.setAvatar(avatar); + if (userService.updateUserInfo(currentUser) > 0) + { + setSysUser(userService.selectUserById(currentUser.getUserId())); + return success(); + } + } + return error(); + } + catch (Exception e) + { + log.error("修改头像失败!", e); + return error(e.getMessage()); + } + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRegisterController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRegisterController.java new file mode 100644 index 00000000..eb5b8d14 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRegisterController.java @@ -0,0 +1,46 @@ +package com.ghy.web.controller.system; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysUser; +import com.ghy.common.utils.StringUtils; +import com.ghy.framework.shiro.service.SysRegisterService; +import com.ghy.system.service.ISysConfigService; + +/** + * 注册验证 + * + * @author clunt + */ +@Controller +public class SysRegisterController extends BaseController +{ + @Autowired + private SysRegisterService registerService; + + @Autowired + private ISysConfigService configService; + + @GetMapping("/register") + public String register() + { + return "register"; + } + + @PostMapping("/register") + @ResponseBody + public AjaxResult ajaxRegister(SysUser user) + { + if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) + { + return error("当前系统没有开启注册功能!"); + } + String msg = registerService.register(user); + return StringUtils.isEmpty(msg) ? success() : error(msg); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRoleController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRoleController.java new file mode 100644 index 00000000..b6b4468e --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysRoleController.java @@ -0,0 +1,302 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysRole; +import com.ghy.common.core.domain.entity.SysUser; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.framework.shiro.util.AuthorizationUtils; +import com.ghy.system.domain.SysUserRole; +import com.ghy.system.service.ISysRoleService; +import com.ghy.system.service.ISysUserService; + +/** + * 角色信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/role") +public class SysRoleController extends BaseController +{ + private String prefix = "system/role"; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysUserService userService; + + @RequiresPermissions("system:role:view") + @GetMapping() + public String role() + { + return prefix + "/role"; + } + + @RequiresPermissions("system:role:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysRole role) + { + startPage(); + List list = roleService.selectRoleList(role); + return getDataTable(list); + } + + @Log(title = "角色管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:role:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysRole role) + { + List list = roleService.selectRoleList(role); + ExcelUtil util = new ExcelUtil(SysRole.class); + return util.exportExcel(list, "角色数据"); + } + + /** + * 新增角色 + */ + @GetMapping("/add") + public String add() + { + return prefix + "/add"; + } + + /** + * 新增保存角色 + */ + @RequiresPermissions("system:role:add") + @Log(title = "角色管理", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysRole role) + { + if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setCreateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(roleService.insertRole(role)); + + } + + /** + * 修改角色 + */ + @RequiresPermissions("system:role:edit") + @GetMapping("/edit/{roleId}") + public String edit(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + roleService.checkRoleDataScope(roleId); + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/edit"; + } + + /** + * 修改保存角色 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysRole role) + { + roleService.checkRoleAllowed(role); + if (UserConstants.ROLE_NAME_NOT_UNIQUE.equals(roleService.checkRoleNameUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); + } + else if (UserConstants.ROLE_KEY_NOT_UNIQUE.equals(roleService.checkRoleKeyUnique(role))) + { + return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); + } + role.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(roleService.updateRole(role)); + } + + /** + * 角色分配数据权限 + */ + @GetMapping("/authDataScope/{roleId}") + public String authDataScope(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/dataScope"; + } + + /** + * 保存角色分配数据权限 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @PostMapping("/authDataScope") + @ResponseBody + public AjaxResult authDataScopeSave(SysRole role) + { + roleService.checkRoleAllowed(role); + role.setUpdateBy(getLoginName()); + if (roleService.authDataScope(role) > 0) + { + setSysUser(userService.selectUserById(getUserId())); + return success(); + } + return error(); + } + + @RequiresPermissions("system:role:remove") + @Log(title = "角色管理", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + return toAjax(roleService.deleteRoleByIds(ids)); + } + + /** + * 校验角色名称 + */ + @PostMapping("/checkRoleNameUnique") + @ResponseBody + public String checkRoleNameUnique(SysRole role) + { + return roleService.checkRoleNameUnique(role); + } + + /** + * 校验角色权限 + */ + @PostMapping("/checkRoleKeyUnique") + @ResponseBody + public String checkRoleKeyUnique(SysRole role) + { + return roleService.checkRoleKeyUnique(role); + } + + /** + * 选择菜单树 + */ + @GetMapping("/selectMenuTree") + public String selectMenuTree() + { + return prefix + "/tree"; + } + + /** + * 角色状态修改 + */ + @Log(title = "角色管理", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:role:edit") + @PostMapping("/changeStatus") + @ResponseBody + public AjaxResult changeStatus(SysRole role) + { + roleService.checkRoleAllowed(role); + return toAjax(roleService.changeStatus(role)); + } + + /** + * 分配用户 + */ + @RequiresPermissions("system:role:edit") + @GetMapping("/authUser/{roleId}") + public String authUser(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/authUser"; + } + + /** + * 查询已分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @PostMapping("/authUser/allocatedList") + @ResponseBody + public TableDataInfo allocatedList(SysUser user) + { + startPage(); + List list = userService.selectAllocatedList(user); + return getDataTable(list); + } + + /** + * 取消授权 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PostMapping("/authUser/cancel") + @ResponseBody + public AjaxResult cancelAuthUser(SysUserRole userRole) + { + return toAjax(roleService.deleteAuthUser(userRole)); + } + + /** + * 批量取消授权 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PostMapping("/authUser/cancelAll") + @ResponseBody + public AjaxResult cancelAuthUserAll(Long roleId, String userIds) + { + return toAjax(roleService.deleteAuthUsers(roleId, userIds)); + } + + /** + * 选择用户 + */ + @GetMapping("/authUser/selectUser/{roleId}") + public String selectUser(@PathVariable("roleId") Long roleId, ModelMap mmap) + { + mmap.put("role", roleService.selectRoleById(roleId)); + return prefix + "/selectUser"; + } + + /** + * 查询未分配用户角色列表 + */ + @RequiresPermissions("system:role:list") + @PostMapping("/authUser/unallocatedList") + @ResponseBody + public TableDataInfo unallocatedList(SysUser user) + { + startPage(); + List list = userService.selectUnallocatedList(user); + return getDataTable(list); + } + + /** + * 批量选择用户授权 + */ + @RequiresPermissions("system:role:edit") + @Log(title = "角色管理", businessType = BusinessType.GRANT) + @PostMapping("/authUser/selectAll") + @ResponseBody + public AjaxResult selectAuthUserAll(Long roleId, String userIds) + { + return toAjax(roleService.insertAuthUsers(roleId, userIds)); + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/system/SysUserController.java b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysUserController.java new file mode 100644 index 00000000..e82f3249 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/system/SysUserController.java @@ -0,0 +1,298 @@ +package com.ghy.web.controller.system; + +import java.util.List; +import java.util.stream.Collectors; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.multipart.MultipartFile; +import com.ghy.common.annotation.Log; +import com.ghy.common.constant.UserConstants; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.core.domain.entity.SysRole; +import com.ghy.common.core.domain.entity.SysUser; +import com.ghy.common.core.page.TableDataInfo; +import com.ghy.common.core.text.Convert; +import com.ghy.common.enums.BusinessType; +import com.ghy.common.utils.ShiroUtils; +import com.ghy.common.utils.StringUtils; +import com.ghy.common.utils.poi.ExcelUtil; +import com.ghy.framework.shiro.service.SysPasswordService; +import com.ghy.framework.shiro.util.AuthorizationUtils; +import com.ghy.system.service.ISysPostService; +import com.ghy.system.service.ISysRoleService; +import com.ghy.system.service.ISysUserService; + +/** + * 用户信息 + * + * @author clunt + */ +@Controller +@RequestMapping("/system/user") +public class SysUserController extends BaseController +{ + private String prefix = "system/user"; + + @Autowired + private ISysUserService userService; + + @Autowired + private ISysRoleService roleService; + + @Autowired + private ISysPostService postService; + + @Autowired + private SysPasswordService passwordService; + + @RequiresPermissions("system:user:view") + @GetMapping() + public String user() + { + return prefix + "/user"; + } + + @RequiresPermissions("system:user:list") + @PostMapping("/list") + @ResponseBody + public TableDataInfo list(SysUser user) + { + startPage(); + List list = userService.selectUserList(user); + return getDataTable(list); + } + + @Log(title = "用户管理", businessType = BusinessType.EXPORT) + @RequiresPermissions("system:user:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(SysUser user) + { + List list = userService.selectUserList(user); + ExcelUtil util = new ExcelUtil(SysUser.class); + return util.exportExcel(list, "用户数据"); + } + + @Log(title = "用户管理", businessType = BusinessType.IMPORT) + @RequiresPermissions("system:user:import") + @PostMapping("/importData") + @ResponseBody + public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception + { + ExcelUtil util = new ExcelUtil(SysUser.class); + List userList = util.importExcel(file.getInputStream()); + String message = userService.importUser(userList, updateSupport, getLoginName()); + return AjaxResult.success(message); + } + + @RequiresPermissions("system:user:view") + @GetMapping("/importTemplate") + @ResponseBody + public AjaxResult importTemplate() + { + ExcelUtil util = new ExcelUtil(SysUser.class); + return util.importTemplateExcel("用户数据"); + } + + /** + * 新增用户 + */ + @GetMapping("/add") + public String add(ModelMap mmap) + { + mmap.put("roles", roleService.selectRoleAll().stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + mmap.put("posts", postService.selectPostAll()); + return prefix + "/add"; + } + + /** + * 新增保存用户 + */ + @RequiresPermissions("system:user:add") + @Log(title = "用户管理", businessType = BusinessType.INSERT) + @PostMapping("/add") + @ResponseBody + public AjaxResult addSave(@Validated SysUser user) + { + if (UserConstants.USER_NAME_NOT_UNIQUE.equals(userService.checkLoginNameUnique(user.getLoginName()))) + { + return error("新增用户'" + user.getLoginName() + "'失败,登录账号已存在"); + } + else if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("新增用户'" + user.getLoginName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("新增用户'" + user.getLoginName() + "'失败,邮箱账号已存在"); + } + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); + user.setCreateBy(getLoginName()); + return toAjax(userService.insertUser(user)); + } + + /** + * 修改用户 + */ + @RequiresPermissions("system:user:edit") + @GetMapping("/edit/{userId}") + public String edit(@PathVariable("userId") Long userId, ModelMap mmap) + { + userService.checkUserDataScope(userId); + List roles = roleService.selectRolesByUserId(userId); + mmap.put("user", userService.selectUserById(userId)); + mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + mmap.put("posts", postService.selectPostsByUserId(userId)); + return prefix + "/edit"; + } + + /** + * 修改保存用户 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @PostMapping("/edit") + @ResponseBody + public AjaxResult editSave(@Validated SysUser user) + { + userService.checkUserAllowed(user); + if (StringUtils.isNotEmpty(user.getPhonenumber()) + && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(user))) + { + return error("修改用户'" + user.getLoginName() + "'失败,手机号码已存在"); + } + else if (StringUtils.isNotEmpty(user.getEmail()) + && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(user))) + { + return error("修改用户'" + user.getLoginName() + "'失败,邮箱账号已存在"); + } + user.setUpdateBy(getLoginName()); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return toAjax(userService.updateUser(user)); + } + + @RequiresPermissions("system:user:resetPwd") + @GetMapping("/resetPwd/{userId}") + public String resetPwd(@PathVariable("userId") Long userId, ModelMap mmap) + { + mmap.put("user", userService.selectUserById(userId)); + return prefix + "/resetPwd"; + } + + @RequiresPermissions("system:user:resetPwd") + @Log(title = "重置密码", businessType = BusinessType.UPDATE) + @PostMapping("/resetPwd") + @ResponseBody + public AjaxResult resetPwdSave(SysUser user) + { + userService.checkUserAllowed(user); + user.setSalt(ShiroUtils.randomSalt()); + user.setPassword(passwordService.encryptPassword(user.getLoginName(), user.getPassword(), user.getSalt())); + if (userService.resetUserPwd(user) > 0) + { + if (ShiroUtils.getUserId().longValue() == user.getUserId().longValue()) + { + setSysUser(userService.selectUserById(user.getUserId())); + } + return success(); + } + return error(); + } + + /** + * 进入授权角色页 + */ + @GetMapping("/authRole/{userId}") + public String authRole(@PathVariable("userId") Long userId, ModelMap mmap) + { + SysUser user = userService.selectUserById(userId); + // 获取用户所属的角色列表 + List roles = roleService.selectRolesByUserId(userId); + mmap.put("user", user); + mmap.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); + return prefix + "/authRole"; + } + + /** + * 用户授权角色 + */ + @RequiresPermissions("system:user:edit") + @Log(title = "用户管理", businessType = BusinessType.GRANT) + @PostMapping("/authRole/insertAuthRole") + @ResponseBody + public AjaxResult insertAuthRole(Long userId, Long[] roleIds) + { + userService.insertUserAuth(userId, roleIds); + AuthorizationUtils.clearAllCachedAuthorizationInfo(); + return success(); + } + + @RequiresPermissions("system:user:remove") + @Log(title = "用户管理", businessType = BusinessType.DELETE) + @PostMapping("/remove") + @ResponseBody + public AjaxResult remove(String ids) + { + if (ArrayUtils.contains(Convert.toLongArray(ids), getUserId())) + { + return error("当前用户不能删除"); + } + return toAjax(userService.deleteUserByIds(ids)); + } + + /** + * 校验用户名 + */ + @PostMapping("/checkLoginNameUnique") + @ResponseBody + public String checkLoginNameUnique(SysUser user) + { + return userService.checkLoginNameUnique(user.getLoginName()); + } + + /** + * 校验手机号码 + */ + @PostMapping("/checkPhoneUnique") + @ResponseBody + public String checkPhoneUnique(SysUser user) + { + return userService.checkPhoneUnique(user); + } + + /** + * 校验email邮箱 + */ + @PostMapping("/checkEmailUnique") + @ResponseBody + public String checkEmailUnique(SysUser user) + { + return userService.checkEmailUnique(user); + } + + /** + * 用户状态修改 + */ + @Log(title = "用户管理", businessType = BusinessType.UPDATE) + @RequiresPermissions("system:user:edit") + @PostMapping("/changeStatus") + @ResponseBody + public AjaxResult changeStatus(SysUser user) + { + userService.checkUserAllowed(user); + return toAjax(userService.changeStatus(user)); + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/tool/BuildController.java b/ghy-admin/src/main/java/com/ghy/web/controller/tool/BuildController.java new file mode 100644 index 00000000..6423bbda --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/tool/BuildController.java @@ -0,0 +1,26 @@ +package com.ghy.web.controller.tool; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ghy.common.core.controller.BaseController; + +/** + * build 表单构建 + * + * @author clunt + */ +@Controller +@RequestMapping("/tool/build") +public class BuildController extends BaseController +{ + private String prefix = "tool/build"; + + @RequiresPermissions("tool:build:view") + @GetMapping() + public String build() + { + return prefix + "/build"; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/tool/SwaggerController.java b/ghy-admin/src/main/java/com/ghy/web/controller/tool/SwaggerController.java new file mode 100644 index 00000000..b88eb56d --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/tool/SwaggerController.java @@ -0,0 +1,24 @@ +package com.ghy.web.controller.tool; + +import org.apache.shiro.authz.annotation.RequiresPermissions; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import com.ghy.common.core.controller.BaseController; + +/** + * swagger 接口 + * + * @author clunt + */ +@Controller +@RequestMapping("/tool/swagger") +public class SwaggerController extends BaseController +{ + @RequiresPermissions("tool:swagger:view") + @GetMapping() + public String index() + { + return redirect("/swagger-ui/index.html"); + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/controller/tool/TestController.java b/ghy-admin/src/main/java/com/ghy/web/controller/tool/TestController.java new file mode 100644 index 00000000..0712aa14 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/controller/tool/TestController.java @@ -0,0 +1,181 @@ +package com.ghy.web.controller.tool; + +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import org.springframework.web.bind.annotation.DeleteMapping; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.PutMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; +import com.ghy.common.core.controller.BaseController; +import com.ghy.common.core.domain.AjaxResult; +import com.ghy.common.utils.StringUtils; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiImplicitParam; +import io.swagger.annotations.ApiImplicitParams; +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import io.swagger.annotations.ApiOperation; + +/** + * swagger 用户测试方法 + * + * @author clunt + */ +@Api("用户信息管理") +@RestController +@RequestMapping("/test/user") +public class TestController extends BaseController +{ + private final static Map users = new LinkedHashMap(); + { + users.put(1, new UserEntity(1, "admin", "admin123", "15888888888")); + users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); + } + + @ApiOperation("获取用户列表") + @GetMapping("/list") + public AjaxResult userList() + { + List userList = new ArrayList(users.values()); + return AjaxResult.success(userList); + } + + @ApiOperation("获取用户详细") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @GetMapping("/{userId}") + public AjaxResult getUser(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + return AjaxResult.success(users.get(userId)); + } + else + { + return error("用户不存在"); + } + } + + @ApiOperation("新增用户") + @ApiImplicitParams({ + @ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), + @ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), + @ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) + }) + @PostMapping("/save") + public AjaxResult save(UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return error("用户ID不能为空"); + } + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + @ApiOperation("更新用户") + @PutMapping("/update") + public AjaxResult update(@RequestBody UserEntity user) + { + if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) + { + return error("用户ID不能为空"); + } + if (users.isEmpty() || !users.containsKey(user.getUserId())) + { + return error("用户不存在"); + } + users.remove(user.getUserId()); + return AjaxResult.success(users.put(user.getUserId(), user)); + } + + @ApiOperation("删除用户信息") + @ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) + @DeleteMapping("/{userId}") + public AjaxResult delete(@PathVariable Integer userId) + { + if (!users.isEmpty() && users.containsKey(userId)) + { + users.remove(userId); + return success(); + } + else + { + return error("用户不存在"); + } + } +} + +@ApiModel(value = "UserEntity", description = "用户实体") +class UserEntity +{ + @ApiModelProperty("用户ID") + private Integer userId; + + @ApiModelProperty("用户名称") + private String username; + + @ApiModelProperty("用户密码") + private String password; + + @ApiModelProperty("用户手机") + private String mobile; + + public UserEntity() + { + + } + + public UserEntity(Integer userId, String username, String password, String mobile) + { + this.userId = userId; + this.username = username; + this.password = password; + this.mobile = mobile; + } + + public Integer getUserId() + { + return userId; + } + + public void setUserId(Integer userId) + { + this.userId = userId; + } + + public String getUsername() + { + return username; + } + + public void setUsername(String username) + { + this.username = username; + } + + public String getPassword() + { + return password; + } + + public void setPassword(String password) + { + this.password = password; + } + + public String getMobile() + { + return mobile; + } + + public void setMobile(String mobile) + { + this.mobile = mobile; + } +} diff --git a/ghy-admin/src/main/java/com/ghy/web/core/config/SwaggerConfig.java b/ghy-admin/src/main/java/com/ghy/web/core/config/SwaggerConfig.java new file mode 100644 index 00000000..e3d8f099 --- /dev/null +++ b/ghy-admin/src/main/java/com/ghy/web/core/config/SwaggerConfig.java @@ -0,0 +1,67 @@ +package com.ghy.web.core.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import com.ghy.common.config.GhyConfig; +import io.swagger.annotations.ApiOperation; +import springfox.documentation.builders.ApiInfoBuilder; +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.builders.RequestHandlerSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; + +/** + * Swagger2的接口配置 + * + * @author clunt + */ +@Configuration +public class SwaggerConfig +{ + /** 是否开启swagger */ + @Value("${swagger.enabled}") + private boolean enabled; + + /** + * 创建API + */ + @Bean + public Docket createRestApi() + { + return new Docket(DocumentationType.OAS_30) + // 是否启用Swagger + .enable(enabled) + // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) + .apiInfo(apiInfo()) + // 设置哪些接口暴露给Swagger展示 + .select() + // 扫描所有有注解的api,用这种方式更灵活 + .apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) + // 扫描指定包中的swagger注解 + //.apis(RequestHandlerSelectors.basePackage("com.ghy.project.tool.swagger")) + // 扫描所有 .apis(RequestHandlerSelectors.any()) + .paths(PathSelectors.any()) + .build(); + } + + /** + * 添加摘要信息 + */ + private ApiInfo apiInfo() + { + // 用ApiInfoBuilder进行定制 + return new ApiInfoBuilder() + // 设置标题 + .title("标题:若依管理系统_接口文档") + // 描述 + .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...") + // 作者信息 + .contact(new Contact(GhyConfig.getName(), null, null)) + // 版本 + .version("版本号:" + GhyConfig.getVersion()) + .build(); + } +} diff --git a/ghy-admin/src/main/resources/application-druid.yml b/ghy-admin/src/main/resources/application-druid.yml new file mode 100644 index 00000000..b4eaaf18 --- /dev/null +++ b/ghy-admin/src/main/resources/application-druid.yml @@ -0,0 +1,57 @@ +# 数据源配置 +spring: + datasource: + type: com.alibaba.druid.pool.DruidDataSource + driverClassName: com.mysql.cj.jdbc.Driver + druid: + # 主库数据源 + master: + url: jdbc:mysql://121.4.113.60:3306/ghy?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 + username: root + password: 123456 + # 从库数据源 + slave: + # 从数据源开关/默认关闭 + enabled: false + url: + username: + password: + # 初始连接数 + initialSize: 5 + # 最小连接池数量 + minIdle: 10 + # 最大连接池数量 + maxActive: 20 + # 配置获取连接等待超时的时间 + maxWait: 60000 + # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 + timeBetweenEvictionRunsMillis: 60000 + # 配置一个连接在池中最小生存的时间,单位是毫秒 + minEvictableIdleTimeMillis: 300000 + # 配置一个连接在池中最大生存的时间,单位是毫秒 + maxEvictableIdleTimeMillis: 900000 + # 配置检测连接是否有效 + validationQuery: SELECT 1 FROM DUAL + testWhileIdle: true + testOnBorrow: false + testOnReturn: false + webStatFilter: + enabled: true + statViewServlet: + enabled: true + # 设置白名单,不填则允许所有访问 + allow: + url-pattern: /druid/* + # 控制台管理用户名和密码 + login-username: ruoyi + login-password: 123456 + filter: + stat: + enabled: true + # 慢SQL记录 + log-slow-sql: true + slow-sql-millis: 1000 + merge-sql: true + wall: + config: + multi-statement-allow: true \ No newline at end of file diff --git a/ghy-admin/src/main/resources/application.yml b/ghy-admin/src/main/resources/application.yml new file mode 100644 index 00000000..6ec56581 --- /dev/null +++ b/ghy-admin/src/main/resources/application.yml @@ -0,0 +1,142 @@ +# 项目相关配置 +ruoyi: + # 名称 + name: RuoYi + # 版本 + version: 4.7.2 + # 版权年份 + copyrightYear: 2021 + # 实例演示开关 + demoEnabled: true + # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) + profile: D:/ruoyi/uploadPath + # 获取ip地址开关 + addressEnabled: false + +# 开发环境配置 +server: + # 服务器的HTTP端口,默认为80 + port: 80 + servlet: + # 应用的访问路径 + context-path: / + tomcat: + # tomcat的URI编码 + uri-encoding: UTF-8 + # 连接数满后的排队数,默认为100 + accept-count: 1000 + threads: + # tomcat最大线程数,默认为200 + max: 800 + # Tomcat启动初始化的线程数,默认值10 + min-spare: 100 + +# 日志配置 +logging: + level: + com.ghy: debug + org.springframework: warn + +# 用户配置 +user: + password: + # 密码错误{maxRetryCount}次锁定10分钟 + maxRetryCount: 5 + +# Spring配置 +spring: + # 模板引擎 + thymeleaf: + mode: HTML + encoding: utf-8 + # 禁用缓存 + cache: false + # 资源信息 + messages: + # 国际化资源文件路径 + basename: static/i18n/messages + jackson: + time-zone: GMT+8 + date-format: yyyy-MM-dd HH:mm:ss + profiles: + active: druid + # 文件上传 + servlet: + multipart: + # 单个文件大小 + max-file-size: 10MB + # 设置总上传的文件大小 + max-request-size: 20MB + # 服务模块 + devtools: + restart: + # 热部署开关 + enabled: true + +# MyBatis +mybatis: + # 搜索指定包别名 + typeAliasesPackage: com.ghy.**.domain + # 配置mapper的扫描,找到所有的mapper.xml映射文件 + mapperLocations: classpath*:mapper/**/*Mapper.xml + # 加载全局的配置文件 + configLocation: classpath:mybatis/mybatis-config.xml + +# PageHelper分页插件 +pagehelper: + helperDialect: mysql + supportMethodsArguments: true + params: count=countSql + +# Shiro +shiro: + user: + # 登录地址 + loginUrl: /login + # 权限认证失败地址 + unauthorizedUrl: /unauth + # 首页地址 + indexUrl: /index + # 验证码开关 + captchaEnabled: true + # 验证码类型 math 数组计算 char 字符 + captchaType: math + cookie: + # 设置Cookie的域名 默认空,即当前访问的域名 + domain: + # 设置cookie的有效访问路径 + path: / + # 设置HttpOnly属性 + httpOnly: true + # 设置Cookie的过期时间,天为单位 + maxAge: 30 + # 设置密钥,务必保持唯一性(生成方式,直接拷贝到main运行即可)Base64.encodeToString(CipherUtils.generateNewKey(128, "AES").getEncoded()) (默认启动生成随机秘钥,随机秘钥会导致之前客户端RememberMe Cookie无效,如设置固定秘钥RememberMe Cookie则有效) + cipherKey: + session: + # Session超时时间,-1代表永不过期(默认30分钟) + expireTime: 30 + # 同步session到数据库的周期(默认1分钟) + dbSyncPeriod: 1 + # 相隔多久检查一次session的有效性,默认就是10分钟 + validationInterval: 10 + # 同一个用户最大会话数,比如2的意思是同一个账号允许最多同时两个人登录(默认-1不限制) + maxSession: -1 + # 踢出之前登录的/之后登录的用户,默认踢出之前登录的用户 + kickoutAfter: false + rememberMe: + # 是否开启记住我 + enabled: true + +# 防止XSS攻击 +xss: + # 过滤开关 + enabled: true + # 排除链接(多个用逗号分隔) + excludes: /system/notice/* + # 匹配链接 + urlPatterns: /system/*,/monitor/*,/tool/* + +# Swagger配置 +swagger: + # 是否开启swagger + enabled: true diff --git a/ghy-admin/src/main/resources/banner.txt b/ghy-admin/src/main/resources/banner.txt new file mode 100644 index 00000000..0931cb84 --- /dev/null +++ b/ghy-admin/src/main/resources/banner.txt @@ -0,0 +1,24 @@ +Application Version: ${ruoyi.version} +Spring Boot Version: ${spring-boot.version} +//////////////////////////////////////////////////////////////////// +// _ooOoo_ // +// o8888888o // +// 88" . "88 // +// (| ^_^ |) // +// O\ = /O // +// ____/`---'\____ // +// .' \\| |// `. // +// / \\||| : |||// \ // +// / _||||| -:- |||||- \ // +// | | \\\ - /// | | // +// | \_| ''\---/'' | | // +// \ .-\__ `-` ___/-. / // +// ___`. .' /--.--\ `. . ___ // +// ."" '< `.___\_<|>_/___.' >'"". // +// | | : `- \`.;`\ _ /`;.`/ - ` : | | // +// \ \ `-. \_ __\ /__ _/ .-` / / // +// ========`-.____`-.___\_____/___.-`____.-'======== // +// `=---=' // +// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // +// 佛祖保佑 永不宕机 永无BUG // +//////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/ghy-admin/src/main/resources/ehcache/ehcache-shiro.xml b/ghy-admin/src/main/resources/ehcache/ehcache-shiro.xml new file mode 100644 index 00000000..5b595eb0 --- /dev/null +++ b/ghy-admin/src/main/resources/ehcache/ehcache-shiro.xml @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ghy-admin/src/main/resources/logback.xml b/ghy-admin/src/main/resources/logback.xml new file mode 100644 index 00000000..2e47b5e4 --- /dev/null +++ b/ghy-admin/src/main/resources/logback.xml @@ -0,0 +1,93 @@ + + + + + + + + + + + ${log.pattern} + + + + + + ${log.path}/sys-info.log + + + + ${log.path}/sys-info.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + INFO + + ACCEPT + + DENY + + + + + ${log.path}/sys-error.log + + + + ${log.path}/sys-error.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + ERROR + + ACCEPT + + DENY + + + + + + ${log.path}/sys-user.log + + + ${log.path}/sys-user.%d{yyyy-MM-dd}.log + + 60 + + + ${log.pattern} + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ghy-admin/src/main/resources/mybatis/mybatis-config.xml b/ghy-admin/src/main/resources/mybatis/mybatis-config.xml new file mode 100644 index 00000000..ac47c038 --- /dev/null +++ b/ghy-admin/src/main/resources/mybatis/mybatis-config.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + diff --git a/ghy-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js b/ghy-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js new file mode 100644 index 00000000..ea69dece --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/beautifyhtml/beautifyhtml.js @@ -0,0 +1,617 @@ +/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */ +/* + + The MIT License (MIT) + + Copyright (c) 2007-2013 Einar Lielmanis and contributors. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation files + (the "Software"), to deal in the Software without restriction, + including without limitation the rights to use, copy, modify, merge, + publish, distribute, sublicense, and/or sell copies of the Software, + and to permit persons to whom the Software is furnished to do so, + subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + + + Style HTML +--------------- + + Written by Nochum Sossonko, (nsossonko@hotmail.com) + + Based on code initially developed by: Einar Lielmanis, + http://jsbeautifier.org/ + + Usage: + style_html(html_source); + + style_html(html_source, options); + + The options are: + indent_size (default 4) — indentation size, + indent_char (default space) — character to indent with, + max_char (default 250) - maximum amount of characters per line (0 = disable) + brace_style (default "collapse") - "collapse" | "expand" | "end-expand" + put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line. + unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted + indent_scripts (default normal) - "keep"|"separate"|"normal" + + e.g. + + style_html(html_source, { + 'indent_size': 2, + 'indent_char': ' ', + 'max_char': 78, + 'brace_style': 'expand', + 'unformatted': ['a', 'sub', 'sup', 'b', 'i', 'u'] + }); +*/ + +(function() { + + function style_html(html_source, options, js_beautify, css_beautify) { + //Wrapper function to invoke all the necessary constructors and deal with the output. + + var multi_parser, + indent_size, + indent_character, + max_char, + brace_style, + unformatted; + + options = options || {}; + indent_size = options.indent_size || 4; + indent_character = options.indent_char || ' '; + brace_style = options.brace_style || 'collapse'; + max_char = options.max_char === 0 ? Infinity : options.max_char || 250; + unformatted = options.unformatted || ['a', 'span', 'bdo', 'em', 'strong', 'dfn', 'code', 'samp', 'kbd', 'var', 'cite', 'abbr', 'acronym', 'q', 'sub', 'sup', 'tt', 'i', 'b', 'big', 'small', 'u', 's', 'strike', 'font', 'ins', 'del', 'pre', 'address', 'dt', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + + function Parser() { + + this.pos = 0; //Parser position + this.token = ''; + this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT + this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values + parent: 'parent1', + parentcount: 1, + parent1: '' + }; + this.tag_type = ''; + this.token_text = this.last_token = this.last_text = this.token_type = ''; + + this.Utils = { //Uilities made available to the various functions + whitespace: "\n\r\t ".split(''), + single_token: 'br,input,link,meta,!doctype,basefont,base,area,hr,wbr,param,img,isindex,?xml,embed,?php,?,?='.split(','), //all the single tags for HTML + extra_liners: 'head,body,/html'.split(','), //for tags that need a line of whitespace before them + in_array: function (what, arr) { + for (var i=0; i= this.input.length) { + return content.length?content.join(''):['', 'TK_EOF']; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + this.line_char_count++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { + if (content.length) { + space = true; + } + this.line_char_count--; + continue; //don't want to insert unnecessary space + } + else if (space) { + if (this.line_char_count >= this.max_char) { //insert a line when the max_char is reached + content.push('\n'); + for (var i=0; i', 'igm'); + reg_match.lastIndex = this.pos; + var reg_array = reg_match.exec(this.input); + var end_script = reg_array?reg_array.index:this.input.length; //absolute end of script + if(this.pos < end_script) { //get everything in between the script tags + content = this.input.substring(this.pos, end_script); + this.pos = end_script; + } + return content; + }; + + this.record_tag = function (tag){ //function to record a tag and its parent in this.tags Object + if (this.tags[tag + 'count']) { //check for the existence of this tag type + this.tags[tag + 'count']++; + this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level + } + else { //otherwise initialize this tag type + this.tags[tag + 'count'] = 1; + this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level + } + this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent) + this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1') + }; + + this.retrieve_tag = function (tag) { //function to retrieve the opening tag to the corresponding closer + if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it + var temp_parent = this.tags.parent; //check to see if it's a closable tag. + while (temp_parent) { //till we reach '' (the initial value); + if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it + break; + } + temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree + } + if (temp_parent) { //if we caught something + this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly + this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent + } + delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference... + delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself + if (this.tags[tag + 'count'] === 1) { + delete this.tags[tag + 'count']; + } + else { + this.tags[tag + 'count']--; + } + } + }; + + this.get_tag = function (peek) { //function to get a full tag and parse its type + var input_char = '', + content = [], + comment = '', + space = false, + tag_start, tag_end, + orig_pos = this.pos, + orig_line_char_count = this.line_char_count; + + peek = peek !== undefined ? peek : false; + + do { + if (this.pos >= this.input.length) { + if (peek) { + this.pos = orig_pos; + this.line_char_count = orig_line_char_count; + } + return content.length?content.join(''):['', 'TK_EOF']; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + this.line_char_count++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space + space = true; + this.line_char_count--; + continue; + } + + if (input_char === "'" || input_char === '"') { + if (!content[1] || content[1] !== '!') { //if we're in a comment strings don't get treated specially + input_char += this.get_unformatted(input_char); + space = true; + } + } + + if (input_char === '=') { //no space before = + space = false; + } + + if (content.length && content[content.length-1] !== '=' && input_char !== '>' && space) { + //no space after = or before > + if (this.line_char_count >= this.max_char) { + this.print_newline(false, content); + this.line_char_count = 0; + } + else { + content.push(' '); + this.line_char_count++; + } + space = false; + } + if (input_char === '<') { + tag_start = this.pos - 1; + } + content.push(input_char); //inserts character at-a-time (or string) + } while (input_char !== '>'); + + var tag_complete = content.join(''); + var tag_index; + if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends + tag_index = tag_complete.indexOf(' '); + } + else { //otherwise go with the tag ending + tag_index = tag_complete.indexOf('>'); + } + var tag_check = tag_complete.substring(1, tag_index).toLowerCase(); + if (tag_complete.charAt(tag_complete.length-2) === '/' || + this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /) + if ( ! peek) { + this.tag_type = 'SINGLE'; + } + } + else if (tag_check === 'script') { //for later script handling + if ( ! peek) { + this.record_tag(tag_check); + this.tag_type = 'SCRIPT'; + } + } + else if (tag_check === 'style') { //for future style handling (for now it justs uses get_content) + if ( ! peek) { + this.record_tag(tag_check); + this.tag_type = 'STYLE'; + } + } + else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags + comment = this.get_unformatted('', tag_complete); //...delegate to get_unformatted function + content.push(comment); + // Preserve collapsed whitespace either before or after this tag. + if (tag_start > 0 && this.Utils.in_array(this.input.charAt(tag_start - 1), this.Utils.whitespace)){ + content.splice(0, 0, this.input.charAt(tag_start - 1)); + } + tag_end = this.pos - 1; + if (this.Utils.in_array(this.input.charAt(tag_end + 1), this.Utils.whitespace)){ + content.push(this.input.charAt(tag_end + 1)); + } + this.tag_type = 'SINGLE'; + } + else if (tag_check.charAt(0) === '!') { //peek for so... + comment = this.get_unformatted('-->', tag_complete); //...delegate to get_unformatted + content.push(comment); + } + if ( ! peek) { + this.tag_type = 'START'; + } + } + else if (tag_check.indexOf('[endif') !== -1) {//peek for ', tag_complete); + content.push(comment); + this.tag_type = 'SINGLE'; + } + } + else if ( ! peek) { + if (tag_check.charAt(0) === '/') { //this tag is a double tag so check for tag-ending + this.retrieve_tag(tag_check.substring(1)); //remove it and all ancestors + this.tag_type = 'END'; + } + else { //otherwise it's a start-tag + this.record_tag(tag_check); //push it on the tag stack + this.tag_type = 'START'; + } + if (this.Utils.in_array(tag_check, this.Utils.extra_liners)) { //check if this double needs an extra line + this.print_newline(true, this.output); + } + } + + if (peek) { + this.pos = orig_pos; + this.line_char_count = orig_line_char_count; + } + + return content.join(''); //returns fully formatted tag + }; + + this.get_unformatted = function (delimiter, orig_tag) { //function to return unformatted content in its entirety + + if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) { + return ''; + } + var input_char = ''; + var content = ''; + var space = true; + do { + + if (this.pos >= this.input.length) { + return content; + } + + input_char = this.input.charAt(this.pos); + this.pos++; + + if (this.Utils.in_array(input_char, this.Utils.whitespace)) { + if (!space) { + this.line_char_count--; + continue; + } + if (input_char === '\n' || input_char === '\r') { + content += '\n'; + /* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect

 tags if they are specified in the 'unformatted array'
+                for (var i=0; i]*>\s*$/);
+
+            // if next_tag comes back but is not an isolated tag, then
+            // let's treat the 'a' tag as having content
+            // and respect the unformatted option
+            if (!tag || this.Utils.in_array(tag, unformatted)){
+                return true;
+            } else {
+                return false;
+            }
+        };
+
+        this.printer = function (js_source, indent_character, indent_size, max_char, brace_style) { //handles input/output and some other printing functions
+
+          this.input = js_source || ''; //gets the input for the Parser
+          this.output = [];
+          this.indent_character = indent_character;
+          this.indent_string = '';
+          this.indent_size = indent_size;
+          this.brace_style = brace_style;
+          this.indent_level = 0;
+          this.max_char = max_char;
+          this.line_char_count = 0; //count to see if max_char was exceeded
+
+          for (var i=0; i 0) {
+              this.indent_level--;
+            }
+          };
+        };
+        return this;
+      }
+
+      /*_____________________--------------------_____________________*/
+
+      multi_parser = new Parser(); //wrapping functions Parser
+      multi_parser.printer(html_source, indent_character, indent_size, max_char, brace_style); //initialize starting values
+
+      while (true) {
+          var t = multi_parser.get_token();
+          multi_parser.token_text = t[0];
+          multi_parser.token_type = t[1];
+
+        if (multi_parser.token_type === 'TK_EOF') {
+          break;
+        }
+
+        switch (multi_parser.token_type) {
+          case 'TK_TAG_START':
+            multi_parser.print_newline(false, multi_parser.output);
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.indent();
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_STYLE':
+          case 'TK_TAG_SCRIPT':
+            multi_parser.print_newline(false, multi_parser.output);
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_END':
+            //Print new line only if the tag has no content and has child
+            if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
+                var tag_name = multi_parser.token_text.match(/\w+/)[0];
+                var tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length -1].match(/<\s*(\w+)/);
+                if (tag_extracted_from_last_output === null || tag_extracted_from_last_output[1] !== tag_name) {
+                    multi_parser.print_newline(true, multi_parser.output);
+                }
+            }
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_TAG_SINGLE':
+            // Don't add a newline before elements that should remain unformatted.
+            var tag_check = multi_parser.token_text.match(/^\s*<([a-z]+)/i);
+            if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)){
+                multi_parser.print_newline(false, multi_parser.output);
+            }
+            multi_parser.print_token(multi_parser.token_text);
+            multi_parser.current_mode = 'CONTENT';
+            break;
+          case 'TK_CONTENT':
+            if (multi_parser.token_text !== '') {
+              multi_parser.print_token(multi_parser.token_text);
+            }
+            multi_parser.current_mode = 'TAG';
+            break;
+          case 'TK_STYLE':
+          case 'TK_SCRIPT':
+            if (multi_parser.token_text !== '') {
+              multi_parser.output.push('\n');
+              var text = multi_parser.token_text,
+                  _beautifier,
+                  script_indent_level = 1;
+              if (multi_parser.token_type === 'TK_SCRIPT') {
+                _beautifier = typeof js_beautify === 'function' && js_beautify;
+              } else if (multi_parser.token_type === 'TK_STYLE') {
+                _beautifier = typeof css_beautify === 'function' && css_beautify;
+              }
+
+              if (options.indent_scripts === "keep") {
+                script_indent_level = 0;
+              } else if (options.indent_scripts === "separate") {
+                script_indent_level = -multi_parser.indent_level;
+              }
+
+              var indentation = multi_parser.get_full_indent(script_indent_level);
+              if (_beautifier) {
+                // call the Beautifier if avaliable
+                text = _beautifier(text.replace(/^\s*/, indentation), options);
+              } else {
+                // simply indent the string otherwise
+                var white = text.match(/^\s*/)[0];
+                var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
+                var reindent = multi_parser.get_full_indent(script_indent_level -_level);
+                text = text.replace(/^\s*/, indentation)
+                       .replace(/\r\n|\r|\n/g, '\n' + reindent)
+                       .replace(/\s*$/, '');
+              }
+              if (text) {
+                multi_parser.print_token(text);
+                multi_parser.print_newline(true, multi_parser.output);
+              }
+            }
+            multi_parser.current_mode = 'TAG';
+            break;
+        }
+        multi_parser.last_token = multi_parser.token_type;
+        multi_parser.last_text = multi_parser.token_text;
+      }
+      return multi_parser.output.join('');
+    }
+
+    // If we're running a web page and don't have either of the above, add our one global
+    window.html_beautify = function(html_source, options) {
+        return style_html(html_source, options, window.js_beautify, window.css_beautify);
+    };
+
+}());
diff --git a/ghy-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js b/ghy-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
new file mode 100644
index 00000000..552613d9
--- /dev/null
+++ b/ghy-admin/src/main/resources/static/ajax/libs/blockUI/jquery.blockUI.js
@@ -0,0 +1,620 @@
+/*!
+ * jQuery blockUI plugin
+ * Version 2.70.0-2014.11.23
+ * Requires jQuery v1.7 or later
+ *
+ * Examples at: http://malsup.com/jquery/block/
+ * Copyright (c) 2007-2013 M. Alsup
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ *
+ * Thanks to Amir-Hossein Sobhi for some excellent contributions!
+ */
+
+;(function() {
+/*jshint eqeqeq:false curly:false latedef:false */
+"use strict";
+
+	function setup($) {
+		$.fn._fadeIn = $.fn.fadeIn;
+
+		var noOp = $.noop || function() {};
+
+		// this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
+		// confusing userAgent strings on Vista)
+		var msie = /MSIE/.test(navigator.userAgent);
+		var ie6  = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
+		var mode = document.documentMode || 0;
+		var setExpr = $.isFunction( document.createElement('div').style.setExpression );
+
+		// global $ methods for blocking/unblocking the entire page
+		$.blockUI   = function(opts) { install(window, opts); };
+		$.unblockUI = function(opts) { remove(window, opts); };
+
+		// convenience method for quick growl-like notifications  (http://www.google.com/search?q=growl)
+		$.growlUI = function(title, message, timeout, onClose) {
+			var $m = $('
'); + if (title) $m.append('

'+title+'

'); + if (message) $m.append('

'+message+'

'); + if (timeout === undefined) timeout = 3000; + + // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications + var callBlock = function(opts) { + opts = opts || {}; + + $.blockUI({ + message: $m, + fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700, + fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000, + timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout, + centerY: false, + showOverlay: false, + onUnblock: onClose, + css: $.blockUI.defaults.growlCSS + }); + }; + + callBlock(); + var nonmousedOpacity = $m.css('opacity'); + $m.mouseover(function() { + callBlock({ + fadeIn: 0, + timeout: 30000 + }); + + var displayBlock = $('.blockMsg'); + displayBlock.stop(); // cancel fadeout if it has started + displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency + }).mouseout(function() { + $('.blockMsg').fadeOut(1000); + }); + // End konapun additions + }; + + // plugin method for blocking element content + $.fn.block = function(opts) { + if ( this[0] === window ) { + $.blockUI( opts ); + return this; + } + var fullOpts = $.extend({}, $.blockUI.defaults, opts || {}); + this.each(function() { + var $el = $(this); + if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked')) + return; + $el.unblock({ fadeOut: 0 }); + }); + + return this.each(function() { + if ($.css(this,'position') == 'static') { + this.style.position = 'relative'; + $(this).data('blockUI.static', true); + } + this.style.zoom = 1; // force 'hasLayout' in ie + install(this, opts); + }); + }; + + // plugin method for unblocking element content + $.fn.unblock = function(opts) { + if ( this[0] === window ) { + $.unblockUI( opts ); + return this; + } + return this.each(function() { + remove(this, opts); + }); + }; + + $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost! + + // override these in your code to change the default behavior and style + $.blockUI.defaults = { + // message displayed when blocking (use null for no message) + message: '
加载中......
', + + title: null, // title string; only used when theme == true + draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded) + + theme: false, // set to true to use with jQuery UI themes + + // styles for the message when blocking; if you wish to disable + // these and use an external stylesheet then do this in your code: + // $.blockUI.defaults.css = {}; + css: { + padding: 0, + margin: 0, + width: '30%', + top: '40%', + left: '35%', + textAlign: 'center', + color: '#000', + border: '0px', + backgroundColor:'transparent', + cursor: 'wait' + }, + + // minimal style set used when themes are used + themedCSS: { + width: '30%', + top: '40%', + left: '35%' + }, + + // styles for the overlay + overlayCSS: { + backgroundColor: '#000', + opacity: 0.6, + cursor: 'wait' + }, + + // style to replace wait cursor before unblocking to correct issue + // of lingering wait cursor + cursorReset: 'default', + + // styles applied when using $.growlUI + growlCSS: { + width: '350px', + top: '10px', + left: '', + right: '10px', + border: 'none', + padding: '5px', + opacity: 0.6, + cursor: 'default', + color: '#fff', + backgroundColor: '#000', + '-webkit-border-radius':'10px', + '-moz-border-radius': '10px', + 'border-radius': '10px' + }, + + // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w + // (hat tip to Jorge H. N. de Vasconcelos) + /*jshint scripturl:true */ + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank', + + // force usage of iframe in non-IE browsers (handy for blocking applets) + forceIframe: false, + + // z-index for the blocking overlay + baseZ: 1000, + + // set these to true to have the message automatically centered + centerX: true, // <-- only effects element blocking (page block controlled via css above) + centerY: true, + + // allow body element to be stetched in ie6; this makes blocking look better + // on "short" pages. disable if you wish to prevent changes to the body height + allowBodyStretch: true, + + // enable if you want key and mouse events to be disabled for content that is blocked + bindEvents: true, + + // be default blockUI will supress tab navigation from leaving blocking content + // (if bindEvents is true) + constrainTabKey: true, + + // fadeIn time in millis; set to 0 to disable fadeIn on block + fadeIn: 200, + + // fadeOut time in millis; set to 0 to disable fadeOut on unblock + fadeOut: 400, + + // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock + timeout: 0, + + // disable if you don't want to show the overlay + showOverlay: true, + + // if true, focus will be placed in the first available input field when + // page blocking + focusInput: true, + + // elements that can receive focus + focusableElements: ':input:enabled:visible', + + // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity) + // no longer needed in 2012 + // applyPlatformOpacityRules: true, + + // callback method invoked when fadeIn has completed and blocking message is visible + onBlock: null, + + // callback method invoked when unblocking has completed; the callback is + // passed the element that has been unblocked (which is the window object for page + // blocks) and the options that were passed to the unblock call: + // onUnblock(element, options) + onUnblock: null, + + // callback method invoked when the overlay area is clicked. + // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used. + onOverlayClick: null, + + // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493 + quirksmodeOffsetHack: 4, + + // class name of the message block + blockMsgClass: 'blockMsg', + + // if it is already blocked, then ignore it (don't unblock and reblock) + ignoreIfBlocked: false + }; + + // private data and functions follow... + + var pageBlock = null; + var pageBlockEls = []; + + function install(el, opts) { + var css, themedCSS; + var full = (el == window); + var msg = (opts && opts.message !== undefined ? opts.message : undefined); + opts = $.extend({}, $.blockUI.defaults, opts || {}); + + if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked')) + return; + + opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {}); + css = $.extend({}, $.blockUI.defaults.css, opts.css || {}); + if (opts.onOverlayClick) + opts.overlayCSS.cursor = 'pointer'; + + themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {}); + msg = msg === undefined ? opts.message : msg; + + // remove the current block (if there is one) + if (full && pageBlock) + remove(window, {fadeOut:0}); + + // if an existing element is being used as the blocking content then we capture + // its current place in the DOM (and current display style) so we can restore + // it when we unblock + if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) { + var node = msg.jquery ? msg[0] : msg; + var data = {}; + $(el).data('blockUI.history', data); + data.el = node; + data.parent = node.parentNode; + data.display = node.style.display; + data.position = node.style.position; + if (data.parent) + data.parent.removeChild(node); + } + + $(el).data('blockUI.onUnblock', opts.onUnblock); + var z = opts.baseZ; + + // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform; + // layer1 is the iframe layer which is used to supress bleed through of underlying content + // layer2 is the overlay layer which has opacity and a wait cursor (by default) + // layer3 is the message content that is displayed while blocking + var lyr1, lyr2, lyr3, s; + if (msie || opts.forceIframe) + lyr1 = $(''); + else + lyr1 = $(''); + + if (opts.theme) + lyr2 = $(''); + else + lyr2 = $(''); + + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if (msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.support.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.support.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each(layers, function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + if (full) + s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"'); + else + s.setExpression('height','this.parentNode.offsetHeight + "px"'); + if (full) + s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"'); + else + s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if ((msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock.bind(lyr3)(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(opts.focusableElements,pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + if (full) + $.unblockUI(opts); + else + $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } + } + + // remove the block + function remove(el, opts) { + var count; + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $el.find('>.blockUI'); + + // fix cursor issue + if ( opts.cursorReset ) { + if ( els.length > 1 ) + els[1].style.cursor = opts.cursorReset; + if ( els.length > 2 ) + els[2].style.cursor = opts.cursorReset; + } + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + count = els.length; + els.stop().fadeOut(opts.fadeOut, function() { + if ( --count === 0) + reset(els,data,opts,el); + }); + } + else + reset(els, data, opts, el); + } + + // move blocking element back into the DOM where it started + function reset(els,data,opts,el) { + var $el = $(el); + if ( $el.data('blockUI.isBlocked') ) + return; + + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + data.el.style.cursor = 'default'; // #59 + if (data.parent) + data.parent.appendChild(data.el); + $el.removeData('blockUI.history'); + } + + if ($el.data('blockUI.static')) { + $el.css('position', 'static'); // #22 + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); + + // fix issue in Safari 6 where block artifacts remain until reflow + var body = $(document.body), w = body.width(), cssW = body[0].style.width; + body.width(w-1).width(w); + body[0].style.width = cssW; + } + + // bind/unbind the handler + function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!full || !opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove'; + if (b) + $(document).bind(events, opts, handler); + else + $(document).unbind(events, handler); + + // former impl... + // var $e = $('a,:input'); + // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); + } + + // event handler to suppress keyboard/mouse events when blocking + function handler(e) { + // allow tab navigation (conditionally) + if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back);},10); + return false; + } + } + } + var opts = e.data; + var target = $(e.target); + if (target.hasClass('blockOverlay') && opts.onOverlayClick) + opts.onOverlayClick(e); + + // allow events within the message content + if (target.parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return target.parents().children().filter('div.blockUI').length === 0; + } + + function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); + } + + function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; + } + + function sz(el, p) { + return parseInt($.css(el,p),10)||0; + } + + } + + + /*global define:true */ + if (typeof define === 'function' && define.amd && define.amd.jQuery) { + define(['jquery'], setup); + } else { + setup(jQuery); + } + +})(); \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css new file mode 100644 index 00000000..0f27a5f5 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.css @@ -0,0 +1,671 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Krajee default styling for bootstrap-fileinput. + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ + +.file-loading input[type=file], +input[type=file].file-loading { + width: 0; + height: 0; +} + +.file-no-browse { + position: absolute; + left: 50%; + bottom: 20%; + width: 1px; + height: 1px; + font-size: 0; + opacity: 0; + border: none; + background: none; + outline: none; + box-shadow: none; +} + +.kv-hidden, +.file-caption-icon, +.file-zoom-dialog .modal-header:before, +.file-zoom-dialog .modal-header:after, +.file-input-new .file-preview, +.file-input-new .close, +.file-input-new .glyphicon-file, +.file-input-new .fileinput-remove-button, +.file-input-new .fileinput-upload-button, +.file-input-new .no-browse .input-group-btn, +.file-input-ajax-new .fileinput-remove-button, +.file-input-ajax-new .fileinput-upload-button, +.file-input-ajax-new .no-browse .input-group-btn, +.hide-content .kv-file-content, +.is-locked .fileinput-upload-button, +.is-locked .fileinput-remove-button { + display: none; +} + +.btn-file input[type=file], +.file-caption-icon, +.file-preview .fileinput-remove, +.krajee-default .file-thumb-progress, +.file-zoom-dialog .btn-navigate, +.file-zoom-dialog .floating-buttons { + position: absolute; +} + +.file-caption-icon .kv-caption-icon { + line-height: inherit; +} + +.file-input, +.file-loading:before, +.btn-file, +.file-caption, +.file-preview, +.krajee-default.file-preview-frame, +.krajee-default .file-thumbnail-footer, +.file-zoom-dialog .modal-dialog { + position: relative; +} + +.file-error-message pre, +.file-error-message ul, +.krajee-default .file-actions, +.krajee-default .file-other-error { + text-align: left; +} + +.file-error-message pre, +.file-error-message ul { + margin: 0; +} + +.krajee-default .file-drag-handle, +.krajee-default .file-upload-indicator { + float: left; + margin-top: 10px; + width: 16px; + height: 16px; +} + +.file-thumb-progress .progress, +.file-thumb-progress .progress-bar { + font-family: Verdana, Helvetica, sans-serif; + font-size: 0.7rem; +} + +.krajee-default .file-thumb-progress .progress, +.kv-upload-progress .progress { + background-color: #ccc; +} + +.krajee-default .file-caption-info, +.krajee-default .file-size-info { + display: block; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + width: 160px; + height: 15px; + margin: auto; +} + +.file-zoom-content > .file-object.type-video, +.file-zoom-content > .file-object.type-flash, +.file-zoom-content > .file-object.type-image { + max-width: 100%; + max-height: 100%; + width: auto; +} + +.file-zoom-content > .file-object.type-video, +.file-zoom-content > .file-object.type-flash { + height: 100%; +} + +.file-zoom-content > .file-object.type-pdf, +.file-zoom-content > .file-object.type-html, +.file-zoom-content > .file-object.type-text, +.file-zoom-content > .file-object.type-default { + width: 100%; +} + +.file-loading:before { + content: " Loading..."; + display: inline-block; + padding-left: 20px; + line-height: 16px; + font-size: 13px; + font-variant: small-caps; + color: #999; + background: transparent url(loading.gif) top left no-repeat; +} + +.file-object { + margin: 0 0 -5px 0; + padding: 0; +} + +.btn-file { + overflow: hidden; +} + +.btn-file input[type=file] { + top: 0; + left: 0; + min-width: 100%; + min-height: 100%; + text-align: right; + opacity: 0; + background: none repeat scroll 0 0 transparent; + cursor: inherit; + display: block; +} + +.btn-file ::-ms-browse { + font-size: 10000px; + width: 100%; + height: 100%; +} + +.file-caption.icon-visible .file-caption-icon { + display: inline-block; +} + +.file-caption.icon-visible .file-caption-name { + padding-left: 25px; +} + +.file-caption.icon-visible > .input-group-lg .file-caption-name { + padding-left: 30px; +} + +.file-caption.icon-visible > .input-group-sm .file-caption-name { + padding-left: 22px; +} + +.file-caption-name:not(.file-caption-disabled) { + background-color: transparent; +} + +.file-caption-name.file-processing { + font-style: italic; + border-color: #bbb; + opacity: 0.5; +} + +.file-caption-icon { + padding: 7px 5px; + left: 4px; +} + +.input-group-lg .file-caption-icon { + font-size: 1.25rem; +} + +.input-group-sm .file-caption-icon { + font-size: 0.875rem; + padding: 0.25rem; +} + +.file-error-message { + color: #a94442; + background-color: #f2dede; + margin: 5px; + border: 1px solid #ebccd1; + border-radius: 4px; + padding: 15px; +} + +.file-error-message pre { + margin: 5px 0; +} + +.file-caption-disabled { + background-color: #eee; + cursor: not-allowed; + opacity: 1; +} + +.file-preview { + border-radius: 5px; + border: 1px solid #ddd; + padding: 8px; + width: 100%; + margin-bottom: 5px; +} + +.file-preview .btn-xs { + padding: 1px 5px; + font-size: 12px; + line-height: 1.5; + border-radius: 3px; +} + +.file-preview .fileinput-remove { + top: 1px; + right: 1px; + line-height: 10px; +} + +.file-preview .clickable { + cursor: pointer; +} + +.file-preview-image { + font: 40px Impact, Charcoal, sans-serif; + color: #008000; + width: auto; + height: auto; + max-width: 100%; + max-height: 100%; +} + +.krajee-default.file-preview-frame { + margin: 8px; + border: 1px solid rgba(0, 0, 0, 0.2); + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2); + padding: 6px; + float: left; + text-align: center; +} + +.krajee-default.file-preview-frame .kv-file-content { + width: 213px; + height: 160px; +} + +.krajee-default .file-preview-other-frame { + display: flex; + align-items: center; + justify-content: center; +} + +.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered { + width: 400px; +} + +.krajee-default.file-preview-frame[data-template="audio"] .kv-file-content { + width: 240px; + height: 55px; +} + +.krajee-default.file-preview-frame .file-thumbnail-footer { + height: 70px; +} + +.krajee-default.file-preview-frame:not(.file-preview-error):hover { + border: 1px solid rgba(0, 0, 0, 0.3); + box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.4); +} + +.krajee-default .file-preview-text { + color: #428bca; + border: 1px solid #ddd; + outline: none; + resize: none; +} + +.krajee-default .file-preview-html { + border: 1px solid #ddd; +} + +.krajee-default .file-other-icon { + font-size: 6em; + line-height: 1; +} + +.krajee-default .file-footer-buttons { + float: right; +} + +.krajee-default .file-footer-caption { + display: block; + text-align: center; + padding-top: 4px; + font-size: 11px; + color: #777; + margin-bottom: 30px; +} + +.file-upload-stats { + font-size: 10px; + text-align: center; + width: 100%; +} + +.kv-upload-progress .file-upload-stats { + font-size: 12px; + margin: -10px 0 5px; +} + +.krajee-default .file-preview-error { + opacity: 0.65; + box-shadow: none; +} + +.krajee-default .file-thumb-progress { + top: 37px; + left: 0; + right: 0; +} + +.krajee-default.kvsortable-ghost { + background: #e1edf7; + border: 2px solid #a1abff; +} + +.krajee-default .file-preview-other:hover { + opacity: 0.8; +} + +.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover { + color: #000; +} + +.kv-upload-progress .progress { + height: 20px; + margin: 10px 0; + overflow: hidden; +} + +.kv-upload-progress .progress-bar { + height: 20px; + font-family: Verdana, Helvetica, sans-serif; +} + + +/*noinspection CssOverwrittenProperties*/ + +.file-zoom-dialog .file-other-icon { + font-size: 22em; + font-size: 50vmin; +} + +.file-zoom-dialog .modal-dialog { + width: auto; +} + +.file-zoom-dialog .modal-header { + display: flex; + align-items: center; + justify-content: space-between; +} + +.file-zoom-dialog .btn-navigate { + margin: 0 0.1rem; + padding: 0; + font-size: 1.2rem; + width: 2.4rem; + height: 2.4rem; + top: 50%; + border-radius: 50%; + text-align:center; +} + +.btn-navigate * { + width: auto; +} + +.file-zoom-dialog .floating-buttons { + top: 5px; + right: 10px; +} + +.file-zoom-dialog .btn-kv-prev { + left: 0; +} + +.file-zoom-dialog .btn-kv-next { + right: 0; +} + +.file-zoom-dialog .kv-zoom-caption { + max-width: 50%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; +} + +.file-zoom-dialog .kv-zoom-header { + padding: 0.5rem; +} + +.file-zoom-dialog .kv-zoom-body { + padding: 0.25rem 0.5rem 0.25rem 0; +} + +.file-zoom-dialog .kv-zoom-description { + position: absolute; + opacity: 0.8; + font-size: 0.8rem; + background-color: #1a1a1a; + padding: 1rem; + text-align: center; + border-radius: 0.5rem; + color: #fff; + left: 15%; + right: 15%; + bottom: 15%; +} + +.file-zoom-dialog .kv-desc-hide { + float: right; + color: #fff; + padding: 0 0.1rem; + background: none; + border: none; +} + +.file-zoom-dialog .kv-desc-hide:hover { + opacity: 0.7; +} + +.file-zoom-dialog .kv-desc-hide:focus { + opacity: 0.9; +} + +.file-input-new .no-browse .form-control { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.file-input-ajax-new .no-browse .form-control { + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; +} + +.file-caption { + width: 100%; + position: relative; +} + +.file-thumb-loading { + background: transparent url(loading.gif) no-repeat scroll center center content-box !important; +} + +.file-drop-zone { + border: 1px dashed #aaa; + min-height: 260px; + border-radius: 4px; + text-align: center; + vertical-align: middle; + margin: 12px 15px 12px 12px; + padding: 5px; +} + +.file-drop-zone.clickable:hover { + border: 2px dashed #999; +} + +.file-drop-zone.clickable:focus { + border: 2px solid #5acde2; +} + +.file-drop-zone .file-preview-thumbnails { + cursor: default; +} + +.file-drop-zone-title { + color: #aaa; + font-size: 1.6em; + text-align: center; + padding: 85px 10px; + cursor: default; +} + +.file-highlighted { + border: 2px dashed #999 !important; + background-color: #eee; +} + +.file-uploading { + background: url(loading-sm.gif) no-repeat center bottom 10px; + opacity: 0.65; +} + +.file-zoom-fullscreen .modal-dialog { + min-width: 100%; + margin: 0; +} + +.file-zoom-fullscreen .modal-content { + border-radius: 0; + box-shadow: none; + min-height: 100vh; +} + +.file-zoom-fullscreen .kv-zoom-body { + overflow-y: auto; +} + +.floating-buttons { + z-index: 3000; +} + +.floating-buttons .btn-kv { + margin-left: 3px; + z-index: 3000; +} + +.kv-zoom-actions .btn-kv { + margin-left: 3px; +} + +.file-zoom-content { + text-align: center; + white-space: nowrap; + min-height: 300px; +} + +.file-zoom-content:hover { + background: transparent; +} + +.file-zoom-content > * { + display: inline-block; + vertical-align: middle; +} + +.file-zoom-content .kv-spacer { + height: 100%; +} + +.file-zoom-content .file-preview-image { + max-height: 100%; +} + +.file-zoom-content .file-preview-video { + max-height: 100%; +} + +.file-zoom-content > .file-object.type-image { + height: auto; + min-height: inherit; +} + +.file-zoom-content > .file-object.type-audio { + width: auto; + height: 30px; +} + +@media (min-width: 576px) { + .file-zoom-dialog .modal-dialog { + max-width: 500px; + } +} + +@media (min-width: 992px) { + .file-zoom-dialog .modal-lg { + max-width: 800px; + } +} + +@media (max-width: 767px) { + .file-preview-thumbnails { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + } + + .file-zoom-dialog .modal-header { + flex-direction: column; + } +} + +@media (max-width: 350px) { + .krajee-default.file-preview-frame:not([data-template="audio"]) .kv-file-content { + width: 160px; + } +} + +@media (max-width: 420px) { + .krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered { + width: 100%; + } +} + +.file-loading[dir=rtl]:before { + background: transparent url(loading.gif) top right no-repeat; + padding-left: 0; + padding-right: 20px; +} + +.clickable .file-drop-zone-title { + cursor: pointer; +} + +.file-sortable .file-drag-handle:hover { + opacity: 0.7; +} + +.file-sortable .file-drag-handle { + cursor: grab; + opacity: 1; +} + +.file-grabbing, +.file-grabbing * { + cursor: not-allowed !important; +} + +.file-grabbing .file-preview-thumbnails * { + cursor: grabbing !important; +} + +.file-preview-frame.sortable-chosen { + background-color: #d9edf7; + border-color: #17a2b8; + box-shadow: none !important; +} + +.file-preview .kv-zoom-cache { + display: none; +} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js new file mode 100644 index 00000000..f52cf3d7 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.js @@ -0,0 +1,6404 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ +(function (factory) { + 'use strict'; + if (typeof define === 'function' && define.amd) { + define(['jquery'], factory); + } else { + if (typeof module === 'object' && module.exports) { + //noinspection NpmUsedModulesInstalled + module.exports = factory(require('jquery')); + } else { + factory(window.jQuery); + } + } +}(function ($) { + 'use strict'; + $.fn.fileinputLocales = {}; + $.fn.fileinputThemes = {}; + if (!$.fn.fileinputBsVersion) { + $.fn.fileinputBsVersion = (window.Alert && window.Alert.VERSION) || + (window.bootstrap && window.bootstrap.Alert && bootstrap.Alert.VERSION) || '3.x.x'; + } + String.prototype.setTokens = function (replacePairs) { + var str = this.toString(), key, re; + for (key in replacePairs) { + if (replacePairs.hasOwnProperty(key)) { + re = new RegExp('\{' + key + '\}', 'g'); + str = str.replace(re, replacePairs[key]); + } + } + return str; + }; + + if (!Array.prototype.flatMap) { // polyfill flatMap + Array.prototype.flatMap = function (lambda) { + return [].concat(this.map(lambda)); + }; + } + + if (!document.currentScript) { + document.currentScript = function() { + var scripts = document.getElementsByTagName('script'); + return scripts[scripts.length - 1]; + }(); + } + + var $h, FileInput, getLoadingUrl = function () { + var src = document.currentScript.src, srcPath = src.substring(0, src.lastIndexOf("/")); + return srcPath + '/loading.gif' + }; + + // fileinput helper object for all global variables and internal helper methods + $h = { + FRAMES: '.kv-preview-thumb', + SORT_CSS: 'file-sortable', + INIT_FLAG: 'init-', + ZOOM_VAR: getLoadingUrl() + '?kvTemp__2873389129__=', // used to prevent 404 errors in URL parsing + OBJECT_PARAMS: '\n' + + '\n' + + '\n' + + '\n' + + '\n' + + '\n', + DEFAULT_PREVIEW: '
\n' + + '{previewFileIcon}\n' + + '
', + MODAL_ID: 'kvFileinputModal', + MODAL_EVENTS: ['show', 'shown', 'hide', 'hidden', 'loaded'], + logMessages: { + ajaxError: '{status}: {error}. Error Details: {text}.', + badDroppedFiles: 'Error scanning dropped files!', + badExifParser: 'Error loading the piexif.js library. {details}', + badInputType: 'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.', + exifWarning: 'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded ' + + 'the "piexif.js" library correctly on your page before the "fileinput.js" script.', + invalidChunkSize: 'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.', + invalidThumb: 'Invalid thumb frame with id: "{id}".', + noResumableSupport: 'The browser does not support resumable or chunk uploads.', + noUploadUrl: 'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.', + retryStatus: 'Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.', + chunkQueueError: 'Could not push task to ajax pool for chunk index # {index}.', + resumableMaxRetriesReached: 'Maximum resumable ajax retries ({n}) reached.', + resumableRetryError: 'Could not retry the resumable request (try # {n})... aborting.', + resumableAborting: 'Aborting / cancelling the resumable request.', + resumableRequestError: 'Error processing resumable request. {msg}' + + }, + objUrl: window.URL || window.webkitURL, + isBs: function (ver) { + var chk = $.trim(($.fn.fileinputBsVersion || '') + ''); + ver = parseInt(ver, 10); + if (!chk) { + return ver === 4; + } + return ver === parseInt(chk.charAt(0), 10); + + }, + defaultButtonCss: function (fill) { + return 'btn-default btn-' + (fill ? '' : 'outline-') + 'secondary'; + }, + now: function () { + return new Date().getTime(); + }, + round: function (num) { + num = parseFloat(num); + return isNaN(num) ? 0 : Math.floor(Math.round(num)); + }, + getArray: function (obj) { + var i, arr = [], len = obj && obj.length || 0; + for (i = 0; i < len; i++) { + arr.push(obj[i]); + } + return arr; + }, + getFileRelativePath: function (file) { + /** @namespace file.relativePath */ + /** @namespace file.webkitRelativePath */ + return String(file.newPath || file.relativePath || file.webkitRelativePath || $h.getFileName(file) || null); + + }, + getFileId: function (file, generateFileId) { + var relativePath = $h.getFileRelativePath(file); + if (typeof generateFileId === 'function') { + return generateFileId(file); + } + if (!file) { + return null; + } + if (!relativePath) { + return null; + } + return (file.size + '_' + encodeURIComponent(relativePath).replace(/%/g, '_')); + }, + getFrameSelector: function (id, selector) { + selector = selector || ''; + return '[id="' + id + '"]' + selector; + }, + getZoomSelector: function (id, selector) { + return $h.getFrameSelector('zoom-' + id, selector); + }, + getFrameElement: function ($element, id, selector) { + return $element.find($h.getFrameSelector(id, selector)); + }, + getZoomElement: function ($element, id, selector) { + return $element.find($h.getZoomSelector(id, selector)); + }, + getElapsed: function (seconds) { + var delta = seconds, out = '', result = {}, structure = { + year: 31536000, + month: 2592000, + week: 604800, // uncomment row to ignore + day: 86400, // feel free to add your own row + hour: 3600, + minute: 60, + second: 1 + }; + $h.getObjectKeys(structure).forEach(function (key) { + result[key] = Math.floor(delta / structure[key]); + delta -= result[key] * structure[key]; + }); + $.each(result, function (key, value) { + if (value > 0) { + out += (out ? ' ' : '') + value + key.substring(0, 1); + } + }); + return out; + }, + debounce: function (func, delay) { + var inDebounce; + return function () { + var args = arguments, context = this; + clearTimeout(inDebounce); + inDebounce = setTimeout(function () { + func.apply(context, args); + }, delay); + }; + }, + stopEvent: function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + getFileName: function (file) { + /** @namespace file.fileName */ + return file ? (file.fileName || file.name || '') : ''; // some confusion in different versions of Firefox + }, + createObjectURL: function (data) { + if ($h.objUrl && $h.objUrl.createObjectURL && data) { + return $h.objUrl.createObjectURL(data); + } + return ''; + }, + revokeObjectURL: function (data) { + if ($h.objUrl && $h.objUrl.revokeObjectURL && data) { + $h.objUrl.revokeObjectURL(data); + } + }, + compare: function (input, str, exact) { + return input !== undefined && (exact ? input === str : input.match(str)); + }, + isIE: function (ver) { + var div, status; + // check for IE versions < 11 + if (navigator.appName !== 'Microsoft Internet Explorer') { + return false; + } + if (ver === 10) { + return new RegExp('msie\\s' + ver, 'i').test(navigator.userAgent); + } + div = document.createElement('div'); + div.innerHTML = ''; + status = div.getElementsByTagName('i').length; + document.body.appendChild(div); + div.parentNode.removeChild(div); + return status; + }, + canOrientImage: function ($el) { + var $img = $(document.createElement('img')).css({width: '1px', height: '1px'}).insertAfter($el), + flag = $img.css('image-orientation'); + $img.remove(); + return !!flag; + }, + canAssignFilesToInput: function () { + var input = document.createElement('input'); + try { + input.type = 'file'; + input.files = null; + return true; + } catch (err) { + return false; + } + }, + getDragDropFolders: function (items) { + var i, item, len = items ? items.length : 0, folders = 0; + if (len > 0 && items[0].webkitGetAsEntry()) { + for (i = 0; i < len; i++) { + item = items[i].webkitGetAsEntry(); + if (item && item.isDirectory) { + folders++; + } + } + } + return folders; + }, + initModal: function ($modal) { + var $body = $('body'); + if ($body.length) { + $modal.appendTo($body); + } + }, + isFunction: function (v) { + return typeof v === 'function'; + }, + isEmpty: function (value, trim) { + if (value === undefined || value === null || value === '') { + return true; + } + if ($h.isString(value) && trim) { + return $.trim(value) === ''; + } + if ($h.isArray(value)) { + return value.length === 0; + } + if ($.isPlainObject(value) && $.isEmptyObject(value)) { + return true + } + return false; + }, + isArray: function (a) { + return Array.isArray(a) || Object.prototype.toString.call(a) === '[object Array]'; + }, + isString: function (a) { + return Object.prototype.toString.call(a) === '[object String]'; + }, + ifSet: function (needle, haystack, def) { + def = def || ''; + return (haystack && typeof haystack === 'object' && needle in haystack) ? haystack[needle] : def; + }, + cleanArray: function (arr) { + if (!(arr instanceof Array)) { + arr = []; + } + return arr.filter(function (e) { + return (e !== undefined && e !== null); + }); + }, + spliceArray: function (arr, index, reverseOrder) { + var i, j = 0, out = [], newArr; + if (!(arr instanceof Array)) { + return []; + } + newArr = $.extend(true, [], arr); + if (reverseOrder) { + newArr.reverse(); + } + for (i = 0; i < newArr.length; i++) { + if (i !== index) { + out[j] = newArr[i]; + j++; + } + } + if (reverseOrder) { + out.reverse(); + } + return out; + }, + getNum: function (num, def) { + def = def || 0; + if (typeof num === 'number') { + return num; + } + if (typeof num === 'string') { + num = parseFloat(num); + } + return isNaN(num) ? def : num; + }, + hasFileAPISupport: function () { + return !!(window.File && window.FileReader); + }, + hasDragDropSupport: function () { + var div = document.createElement('div'); + /** @namespace div.draggable */ + /** @namespace div.ondragstart */ + /** @namespace div.ondrop */ + return !$h.isIE(9) && + (div.draggable !== undefined || (div.ondragstart !== undefined && div.ondrop !== undefined)); + }, + hasFileUploadSupport: function () { + return $h.hasFileAPISupport() && window.FormData; + }, + hasBlobSupport: function () { + try { + return !!window.Blob && Boolean(new Blob()); + } catch (e) { + return false; + } + }, + hasArrayBufferViewSupport: function () { + try { + return new Blob([new Uint8Array(100)]).size === 100; + } catch (e) { + return false; + } + }, + hasResumableUploadSupport: function () { + /** @namespace Blob.prototype.webkitSlice */ + /** @namespace Blob.prototype.mozSlice */ + return $h.hasFileUploadSupport() && $h.hasBlobSupport() && $h.hasArrayBufferViewSupport() && + (!!Blob.prototype.webkitSlice || !!Blob.prototype.mozSlice || !!Blob.prototype.slice || false); + }, + dataURI2Blob: function (dataURI) { + var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder || window.MozBlobBuilder || + window.MSBlobBuilder, canBlob = $h.hasBlobSupport(), byteStr, arrayBuffer, intArray, i, mimeStr, bb, + canProceed = (canBlob || BlobBuilder) && window.atob && window.ArrayBuffer && window.Uint8Array; + if (!canProceed) { + return null; + } + if (dataURI.split(',')[0].indexOf('base64') >= 0) { + byteStr = atob(dataURI.split(',')[1]); + } else { + byteStr = decodeURIComponent(dataURI.split(',')[1]); + } + arrayBuffer = new ArrayBuffer(byteStr.length); + intArray = new Uint8Array(arrayBuffer); + for (i = 0; i < byteStr.length; i += 1) { + intArray[i] = byteStr.charCodeAt(i); + } + mimeStr = dataURI.split(',')[0].split(':')[1].split(';')[0]; + if (canBlob) { + return new Blob([$h.hasArrayBufferViewSupport() ? intArray : arrayBuffer], {type: mimeStr}); + } + bb = new BlobBuilder(); + bb.append(arrayBuffer); + return bb.getBlob(mimeStr); + }, + arrayBuffer2String: function (buffer) { + if (window.TextDecoder) { + return new TextDecoder('utf-8').decode(buffer); + } + var array = Array.prototype.slice.apply(new Uint8Array(buffer)), out = '', i = 0, len, c, char2, char3; + len = array.length; + while (i < len) { + c = array[i++]; + switch (c >> 4) { // jshint ignore:line + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + // 0xxxxxxx + out += String.fromCharCode(c); + break; + case 12: + case 13: + // 110x xxxx 10xx xxxx + char2 = array[i++]; + out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F)); // jshint ignore:line + break; + case 14: + // 1110 xxxx 10xx xxxx 10xx xxxx + char2 = array[i++]; + char3 = array[i++]; + out += String.fromCharCode(((c & 0x0F) << 12) | // jshint ignore:line + ((char2 & 0x3F) << 6) | // jshint ignore:line + ((char3 & 0x3F) << 0)); // jshint ignore:line + break; + } + } + return out; + }, + isHtml: function (str) { + var a = document.createElement('div'); + a.innerHTML = str; + for (var c = a.childNodes, i = c.length; i--;) { + if (c[i].nodeType === 1) { + return true; + } + } + return false; + }, + isSvg: function (str) { + return str.match(/^\s*<\?xml/i) && (str.match(/' + str + '')); + }, + uniqId: function () { + return (new Date().getTime() + Math.floor(Math.random() * Math.pow(10, 15))).toString(36); + }, + cspBuffer: { + CSP_ATTRIB: 'data-csp-01928735', // a randomly named temporary attribute to store the CSP elem id + domElementsStyles: {}, + stash: function (htmlString) { + var self = this, outerDom = $.parseHTML('
' + htmlString + '
'), $el = $(outerDom); + $el.find('[style]').each(function (key, elem) { + var $elem = $(elem), styleDeclaration = $elem[0].style, id = $h.uniqId(), styles = {}; + if (styleDeclaration && styleDeclaration.length) { + $(styleDeclaration).each(function () { + styles[this] = styleDeclaration[this]; + }); + self.domElementsStyles[id] = styles; + $elem.removeAttr('style').attr(self.CSP_ATTRIB, id); + } + }); + $el.filter('*').removeAttr('style'); // make sure all style attr are removed + var values = Object.values ? Object.values(outerDom) : Object.keys(outerDom).map(function (itm) { + return outerDom[itm]; + }); + return values.flatMap(function (elem) { + return elem.innerHTML; + }).join(''); + }, + apply: function (domElement) { + var self = this, $el = $(domElement); + $el.find('[' + self.CSP_ATTRIB + ']').each(function (key, elem) { + var $elem = $(elem), id = $elem.attr(self.CSP_ATTRIB), styles = self.domElementsStyles[id]; + if (styles) { + $elem.css(styles); + } + $elem.removeAttr(self.CSP_ATTRIB); + }); + self.domElementsStyles = {}; + } + }, + setHtml: function ($elem, htmlString) { + var buf = $h.cspBuffer; + $elem.html(buf.stash(htmlString)); + buf.apply($elem); + return $elem; + }, + htmlEncode: function (str, undefVal) { + if (str === undefined) { + return undefVal || null; + } + return str.replace(/&/g, '&') + .replace(//g, '>') + .replace(/"/g, '"') + .replace(/'/g, '''); + }, + replaceTags: function (str, tags) { + var out = str; + if (!tags) { + return out; + } + $.each(tags, function (key, value) { + if (typeof value === 'function') { + value = value(); + } + out = out.split(key).join(value); + }); + return out; + }, + cleanMemory: function ($thumb) { + var data = $thumb.is('img') ? $thumb.attr('src') : $thumb.find('source').attr('src'); + $h.revokeObjectURL(data); + }, + findFileName: function (filePath) { + var sepIndex = filePath.lastIndexOf('/'); + if (sepIndex === -1) { + sepIndex = filePath.lastIndexOf('\\'); + } + return filePath.split(filePath.substring(sepIndex, sepIndex + 1)).pop(); + }, + checkFullScreen: function () { + return document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || + document.msFullscreenElement; + }, + toggleFullScreen: function (maximize) { + var doc = document, de = doc.documentElement, isFullScreen = $h.checkFullScreen(); + if (de && maximize && !isFullScreen) { + if (de.requestFullscreen) { + de.requestFullscreen(); + } else { + if (de.msRequestFullscreen) { + de.msRequestFullscreen(); + } else { + if (de.mozRequestFullScreen) { + de.mozRequestFullScreen(); + } else { + if (de.webkitRequestFullscreen) { + de.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT); + } + } + } + } + } else { + if (isFullScreen) { + if (doc.exitFullscreen) { + doc.exitFullscreen(); + } else { + if (doc.msExitFullscreen) { + doc.msExitFullscreen(); + } else { + if (doc.mozCancelFullScreen) { + doc.mozCancelFullScreen(); + } else { + if (doc.webkitExitFullscreen) { + doc.webkitExitFullscreen(); + } + } + } + } + } + } + }, + moveArray: function (arr, oldIndex, newIndex, reverseOrder) { + var newArr = $.extend(true, [], arr); + if (reverseOrder) { + newArr.reverse(); + } + if (newIndex >= newArr.length) { + var k = newIndex - newArr.length; + while ((k--) + 1) { + newArr.push(undefined); + } + } + newArr.splice(newIndex, 0, newArr.splice(oldIndex, 1)[0]); + if (reverseOrder) { + newArr.reverse(); + } + return newArr; + }, + closeButton: function (css) { + css = ($h.isBs(5) ? 'btn-close' : 'close') + (css ? ' ' + css : ''); + return ''; + }, + getRotation: function (value) { + switch (value) { + case 2: + return 'rotateY(180deg)'; + case 3: + return 'rotate(180deg)'; + case 4: + return 'rotate(180deg) rotateY(180deg)'; + case 5: + return 'rotate(270deg) rotateY(180deg)'; + case 6: + return 'rotate(90deg)'; + case 7: + return 'rotate(90deg) rotateY(180deg)'; + case 8: + return 'rotate(270deg)'; + default: + return ''; + } + }, + setTransform: function (el, val) { + if (!el) { + return; + } + el.style.transform = val; + el.style.webkitTransform = val; + el.style['-moz-transform'] = val; + el.style['-ms-transform'] = val; + el.style['-o-transform'] = val; + }, + getObjectKeys: function (obj) { + var keys = []; + if (obj) { + $.each(obj, function (key) { + keys.push(key); + }); + } + return keys; + }, + getObjectSize: function (obj) { + return $h.getObjectKeys(obj).length; + }, + /** + * Small dependency injection for the task manager + * https://gist.github.com/fearphage/4341799 + */ + whenAll: function (array) { + var s = [].slice, resolveValues = arguments.length === 1 && $h.isArray(array) ? array : s.call(arguments), + deferred = $.Deferred(), i, failed = 0, value, length = resolveValues.length, + remaining = length, rejectContexts, rejectValues, resolveContexts, updateFunc; + rejectContexts = rejectValues = resolveContexts = Array(length); + updateFunc = function (index, contexts, values) { + return function () { + if (values !== resolveValues) { + failed++; + } + deferred.notifyWith(contexts[index] = this, values[index] = s.call(arguments)); + if (!(--remaining)) { + deferred[(!failed ? 'resolve' : 'reject') + 'With'](contexts, values); + } + }; + }; + for (i = 0; i < length; i++) { + if ((value = resolveValues[i]) && $.isFunction(value.promise)) { + value.promise() + .done(updateFunc(i, resolveContexts, resolveValues)) + .fail(updateFunc(i, rejectContexts, rejectValues)); + } else { + deferred.notifyWith(this, value); + --remaining; + } + } + if (!remaining) { + deferred.resolveWith(resolveContexts, resolveValues); + } + return deferred.promise(); + } + }; + FileInput = function (element, options) { + var self = this; + self.$element = $(element); + self.$parent = self.$element.parent(); + if (!self._validate()) { + return; + } + self.isPreviewable = $h.hasFileAPISupport(); + self.isIE9 = $h.isIE(9); + self.isIE10 = $h.isIE(10); + if (self.isPreviewable || self.isIE9) { + self._init(options); + self._listen(); + } + self.$element.removeClass('file-loading'); + }; + + FileInput.prototype = { + constructor: FileInput, + _cleanup: function () { + var self = this; + self.reader = null; + self.clearFileStack(); + self.fileBatchCompleted = true; + self.isError = false; + self.isDuplicateError = false; + self.isPersistentError = false; + self.cancelling = false; + self.paused = false; + self.lastProgress = 0; + self._initAjax(); + }, + _isAborted: function () { + var self = this; + return self.cancelling || self.paused; + }, + _initAjax: function () { + var self = this, tm = self.taskManager = { + pool: {}, + addPool: function (id) { + return (tm.pool[id] = new tm.TasksPool(id)); + }, + getPool: function (id) { + return tm.pool[id]; + }, + addTask: function (id, logic) { // add standalone task directly from task manager + return new tm.Task(id, logic); + }, + TasksPool: function (id) { + var tp = this; + tp.id = id; + tp.cancelled = false; + tp.cancelledDeferrer = $.Deferred(); + tp.tasks = {}; + tp.addTask = function (id, logic) { + return (tp.tasks[id] = new tm.Task(id, logic)); + }; + tp.size = function () { + return $h.getObjectSize(tp.tasks); + }; + tp.run = function (maxThreads) { + var i = 0, failed = false, task, tasksList = $h.getObjectKeys(tp.tasks).map(function (key) { + return tp.tasks[key]; + }), tasksDone = [], deferred = $.Deferred(), enqueue, callback; + + if (tp.cancelled) { + tp.cancelledDeferrer.resolve(); + return deferred.reject(); + } + // if run all at once + if (!maxThreads) { + var tasksDeferredList = $h.getObjectKeys(tp.tasks).map(function (key) { + return tp.tasks[key].deferred; + }); + // when all are done + $h.whenAll(tasksDeferredList).done(function () { + var argv = $h.getArray(arguments); + if (!tp.cancelled) { + deferred.resolve.apply(null, argv); + tp.cancelledDeferrer.reject(); + } else { + deferred.reject.apply(null, argv); + tp.cancelledDeferrer.resolve(); + } + }).fail(function () { + var argv = $h.getArray(arguments); + deferred.reject.apply(null, argv); + if (!tp.cancelled) { + tp.cancelledDeferrer.reject(); + } else { + tp.cancelledDeferrer.resolve(); + } + }); + // run all tasks + $.each(tp.tasks, function (id) { + task = tp.tasks[id]; + task.run(); + }); + return deferred; + } + enqueue = function (task) { + $.when(task.deferred) + .fail(function () { + failed = true; + callback.apply(null, arguments); + }) + .always(callback); + }; + callback = function () { + var argv = $h.getArray(arguments); + // notify a task just ended + deferred.notify(argv); + tasksDone.push(argv); + if (tp.cancelled) { + deferred.reject.apply(null, tasksDone); + tp.cancelledDeferrer.resolve(); + return; + } + if (tasksDone.length === tp.size()) { + if (failed) { + deferred.reject.apply(null, tasksDone); + } else { + deferred.resolve.apply(null, tasksDone); + } + } + // if there are any tasks remaining + if (tasksList.length) { + task = tasksList.shift(); + enqueue(task); + task.run(); + } + }; + // run the first "maxThreads" tasks + while (tasksList.length && i++ < maxThreads) { + task = tasksList.shift(); + enqueue(task); + task.run(); + } + return deferred; + }; + tp.cancel = function () { + tp.cancelled = true; + return tp.cancelledDeferrer; + }; + }, + Task: function (id, logic) { + var tk = this; + tk.id = id; + tk.deferred = $.Deferred(); + tk.logic = logic; + tk.context = null; + tk.run = function () { + var argv = $h.getArray(arguments); + argv.unshift(tk.deferred); // add deferrer as first argument + logic.apply(tk.context, argv); // run task + return tk.deferred; // return deferrer + }; + tk.runWithContext = function (context) { + tk.context = context; + return tk.run(); + }; + } + }; + self.ajaxQueue = []; + self.ajaxRequests = []; + self.ajaxAborted = false; + }, + _init: function (options, refreshMode) { + var self = this, f, $el = self.$element, $cont, t, tmp; + self.options = options; + self.canOrientImage = $h.canOrientImage($el); + $.each(options, function (key, value) { + switch (key) { + case 'minFileCount': + case 'maxFileCount': + case 'maxTotalFileCount': + case 'minFileSize': + case 'maxFileSize': + case 'maxFilePreviewSize': + case 'resizeQuality': + case 'resizeIfSizeMoreThan': + case 'progressUploadThreshold': + case 'initialPreviewCount': + case 'zoomModalHeight': + case 'minImageHeight': + case 'maxImageHeight': + case 'minImageWidth': + case 'maxImageWidth': + case 'bytesToKB': + self[key] = $h.getNum(value); + break; + default: + self[key] = value; + break; + } + }); + if (!self.bytesToKB || self.bytesToKB <= 0) { + self.bytesToKB = 1024; + } + if (self.errorCloseButton === undefined) { + self.errorCloseButton = $h.closeButton('kv-error-close' + ($h.isBs(5) ? ' float-end' : '')); + } + if (self.maxTotalFileCount > 0 && self.maxTotalFileCount < self.maxFileCount) { + self.maxTotalFileCount = self.maxFileCount; + } + if (self.rtl) { // swap buttons for rtl + tmp = self.previewZoomButtonIcons.prev; + self.previewZoomButtonIcons.prev = self.previewZoomButtonIcons.next; + self.previewZoomButtonIcons.next = tmp; + } + // validate chunk threads to not exceed maxAjaxThreads + if (!isNaN(self.maxAjaxThreads) && self.maxAjaxThreads < self.resumableUploadOptions.maxThreads) { + self.resumableUploadOptions.maxThreads = self.maxAjaxThreads; + } + self._initFileManager(); + if (typeof self.autoOrientImage === 'function') { + self.autoOrientImage = self.autoOrientImage(); + } + if (typeof self.autoOrientImageInitial === 'function') { + self.autoOrientImageInitial = self.autoOrientImageInitial(); + } + if (!refreshMode) { + self._cleanup(); + } + self.duplicateErrors = []; + self.$form = $el.closest('form'); + self._initTemplateDefaults(); + self.uploadFileAttr = !$h.isEmpty($el.attr('name')) ? $el.attr('name') : 'file_data'; + t = self._getLayoutTemplate('progress'); + self.progressTemplate = t.replace('{class}', self.progressClass); + self.progressInfoTemplate = t.replace('{class}', self.progressInfoClass); + self.progressPauseTemplate = t.replace('{class}', self.progressPauseClass); + self.progressCompleteTemplate = t.replace('{class}', self.progressCompleteClass); + self.progressErrorTemplate = t.replace('{class}', self.progressErrorClass); + self.isDisabled = $el.attr('disabled') || $el.attr('readonly'); + if (self.isDisabled) { + $el.attr('disabled', true); + } + self.isClickable = self.browseOnZoneClick && self.showPreview && + (self.dropZoneEnabled || !$h.isEmpty(self.defaultPreviewContent)); + self.isAjaxUpload = $h.hasFileUploadSupport() && !$h.isEmpty(self.uploadUrl); + self.dropZoneEnabled = $h.hasDragDropSupport() && self.dropZoneEnabled; + if (!self.isAjaxUpload) { + self.dropZoneEnabled = self.dropZoneEnabled && $h.canAssignFilesToInput(); + } + self.slug = typeof options.slugCallback === 'function' ? options.slugCallback : self._slugDefault; + self.mainTemplate = self.showCaption ? self._getLayoutTemplate('main1') : self._getLayoutTemplate('main2'); + self.captionTemplate = self._getLayoutTemplate('caption'); + self.previewGenericTemplate = self._getPreviewTemplate('generic'); + if (!self.imageCanvas && self.resizeImage && (self.maxImageWidth || self.maxImageHeight)) { + self.imageCanvas = document.createElement('canvas'); + self.imageCanvasContext = self.imageCanvas.getContext('2d'); + } + if ($h.isEmpty($el.attr('id'))) { + $el.attr('id', $h.uniqId()); + } + self.namespace = '.fileinput_' + $el.attr('id').replace(/-/g, '_'); + if (self.$container === undefined) { + self.$container = self._createContainer(); + } else { + self._refreshContainer(); + } + $cont = self.$container; + self.$dropZone = $cont.find('.file-drop-zone'); + self.$progress = $cont.find('.kv-upload-progress'); + self.$btnUpload = $cont.find('.fileinput-upload'); + self.$captionContainer = $h.getElement(options, 'elCaptionContainer', $cont.find('.file-caption')); + self.$caption = $h.getElement(options, 'elCaptionText', $cont.find('.file-caption-name')); + if (!$h.isEmpty(self.msgPlaceholder)) { + f = $el.attr('multiple') ? self.filePlural : self.fileSingle; + self.$caption.attr('placeholder', self.msgPlaceholder.replace('{files}', f)); + } + self.$captionIcon = self.$captionContainer.find('.file-caption-icon'); + self.$previewContainer = $h.getElement(options, 'elPreviewContainer', $cont.find('.file-preview')); + self.$preview = $h.getElement(options, 'elPreviewImage', $cont.find('.file-preview-thumbnails')); + self.$previewStatus = $h.getElement(options, 'elPreviewStatus', $cont.find('.file-preview-status')); + self.$errorContainer = $h.getElement(options, 'elErrorContainer', + self.$previewContainer.find('.kv-fileinput-error')); + self._validateDisabled(); + if (!$h.isEmpty(self.msgErrorClass)) { + $h.addCss(self.$errorContainer, self.msgErrorClass); + } + if (!refreshMode) { + self._resetErrors(); + self.$errorContainer.hide(); + self.previewInitId = 'thumb-' + $el.attr('id'); + self._initPreviewCache(); + self._initPreview(true); + self._initPreviewActions(); + if (self.$parent.hasClass('file-loading')) { + self.$container.insertBefore(self.$parent); + self.$parent.remove(); + } + } else { + if (!self._errorsExist()) { + self.$errorContainer.hide(); + } + } + self._setFileDropZoneTitle(); + if ($el.attr('disabled')) { + self.disable(); + } + self._initZoom(); + if (self.hideThumbnailContent) { + $h.addCss(self.$preview, 'hide-content'); + } + }, + _initFileManager: function () { + var self = this; + self.uploadStartTime = $h.now(); + self.fileManager = { + stack: {}, + filesProcessed: [], + errors: [], + loadedImages: {}, + totalImages: 0, + totalFiles: null, + totalSize: null, + uploadedSize: 0, + stats: {}, + bpsLog: [], + bps: 0, + initStats: function (id) { + var data = {started: $h.now()}; + if (id) { + self.fileManager.stats[id] = data; + } else { + self.fileManager.stats = data; + } + }, + getUploadStats: function (id, loaded, total) { + var fm = self.fileManager, + started = id ? fm.stats[id] && fm.stats[id].started || $h.now() : self.uploadStartTime, + elapsed = ($h.now() - started) / 1000, bps = Math.ceil(elapsed ? loaded / elapsed : 0), + pendingBytes = total - loaded, out, delay = fm.bpsLog.length ? self.bitrateUpdateDelay : 0; + setTimeout(function () { + var i, j = 0, n = 0, len, beg; + fm.bpsLog.push(bps); + fm.bpsLog.sort(function (a, b) { + return a - b; + }); + len = fm.bpsLog.length; + beg = len > 10 ? len - 10 : Math.ceil(len / 2); + for (i = len; i > beg; i--) { + n = parseFloat(fm.bpsLog[i]); + j++; + } + fm.bps = (j > 0 ? n / j : 0) * 64; + }, delay); + out = { + fileId: id, + started: started, + elapsed: elapsed, + loaded: loaded, + total: total, + bps: fm.bps, + bitrate: self._getSize(fm.bps, self.bitRateUnits), + pendingBytes: pendingBytes + }; + if (id) { + fm.stats[id] = out; + } else { + fm.stats = out; + } + return out; + }, + exists: function (id) { + return $.inArray(id, self.fileManager.getIdList()) !== -1; + }, + count: function () { + return self.fileManager.getIdList().length; + }, + total: function () { + var fm = self.fileManager; + if (!fm.totalFiles) { + fm.totalFiles = fm.count(); + } + return fm.totalFiles; + }, + getTotalSize: function () { + var fm = self.fileManager; + if (fm.totalSize) { + return fm.totalSize; + } + fm.totalSize = 0; + $.each(self.getFileStack(), function (id, f) { + var size = parseFloat(f.size); + fm.totalSize += isNaN(size) ? 0 : size; + }); + return fm.totalSize; + }, + add: function (file, id) { + if (!id) { + id = self.fileManager.getId(file); + } + if (!id) { + return; + } + self.fileManager.stack[id] = { + file: file, + name: $h.getFileName(file), + relativePath: $h.getFileRelativePath(file), + size: file.size, + nameFmt: self._getFileName(file, ''), + sizeFmt: self._getSize(file.size) + }; + }, + remove: function ($thumb) { + var id = self._getThumbFileId($thumb); + self.fileManager.removeFile(id); + }, + removeFile: function (id) { + var fm = self.fileManager; + if (!id) { + return; + } + delete fm.stack[id]; + delete fm.loadedImages[id]; + }, + move: function (idFrom, idTo) { + var result = {}, stack = self.fileManager.stack; + if (!idFrom && !idTo || idFrom === idTo) { + return; + } + $.each(stack, function (k, v) { + if (k !== idFrom) { + result[k] = v; + } + if (k === idTo) { + result[idFrom] = stack[idFrom]; + } + }); + self.fileManager.stack = result; + }, + list: function () { + var files = []; + $.each(self.getFileStack(), function (k, v) { + if (v && v.file) { + files.push(v.file); + } + }); + return files; + }, + isPending: function (id) { + return $.inArray(id, self.fileManager.filesProcessed) === -1 && self.fileManager.exists(id); + }, + isProcessed: function () { + var filesProcessed = true, fm = self.fileManager; + $.each(self.getFileStack(), function (id) { + if (fm.isPending(id)) { + filesProcessed = false; + } + }); + return filesProcessed; + }, + clear: function () { + var fm = self.fileManager; + self.isDuplicateError = false; + self.isPersistentError = false; + fm.totalFiles = null; + fm.totalSize = null; + fm.uploadedSize = 0; + fm.stack = {}; + fm.errors = []; + fm.filesProcessed = []; + fm.stats = {}; + fm.bpsLog = []; + fm.bps = 0; + fm.clearImages(); + }, + clearImages: function () { + self.fileManager.loadedImages = {}; + self.fileManager.totalImages = 0; + }, + addImage: function (id, config) { + self.fileManager.loadedImages[id] = config; + }, + removeImage: function (id) { + delete self.fileManager.loadedImages[id]; + }, + getImageIdList: function () { + return $h.getObjectKeys(self.fileManager.loadedImages); + }, + getImageCount: function () { + return self.fileManager.getImageIdList().length; + }, + getId: function (file) { + return self._getFileId(file); + }, + getIndex: function (id) { + return self.fileManager.getIdList().indexOf(id); + }, + getThumb: function (id) { + var $thumb = null; + self._getThumbs().each(function () { + var $t = $(this); + if (self._getThumbFileId($t) === id) { + $thumb = $t; + } + }); + return $thumb; + }, + getThumbIndex: function ($thumb) { + var id = self._getThumbFileId($thumb); + return self.fileManager.getIndex(id); + }, + getIdList: function () { + return $h.getObjectKeys(self.fileManager.stack); + }, + getFile: function (id) { + return self.fileManager.stack[id] || null; + }, + getFileName: function (id, fmt) { + var file = self.fileManager.getFile(id); + if (!file) { + return ''; + } + return fmt ? (file.nameFmt || '') : file.name || ''; + }, + getFirstFile: function () { + var ids = self.fileManager.getIdList(), id = ids && ids.length ? ids[0] : null; + return self.fileManager.getFile(id); + }, + setFile: function (id, file) { + if (self.fileManager.getFile(id)) { + self.fileManager.stack[id].file = file; + } else { + self.fileManager.add(file, id); + } + }, + setProcessed: function (id) { + self.fileManager.filesProcessed.push(id); + }, + getProgress: function () { + var total = self.fileManager.total(), filesProcessed = self.fileManager.filesProcessed.length; + if (!total) { + return 0; + } + return Math.ceil(filesProcessed / total * 100); + + }, + setProgress: function (id, pct) { + var f = self.fileManager.getFile(id); + if (!isNaN(pct) && f) { + f.progress = pct; + } + } + }; + }, + _setUploadData: function (fd, config) { + var self = this; + $.each(config, function (key, value) { + var param = self.uploadParamNames[key] || key; + if ($h.isArray(value)) { + fd.append(param, value[0], value[1]); + } else { + fd.append(param, value); + } + }); + }, + _initResumableUpload: function () { + var self = this, opts = self.resumableUploadOptions, logs = $h.logMessages, rm, fm = self.fileManager; + if (!self.enableResumableUpload) { + return; + } + if (opts.fallback !== false && typeof opts.fallback !== 'function') { + opts.fallback = function (s) { + s._log(logs.noResumableSupport); + s.enableResumableUpload = false; + }; + } + if (!$h.hasResumableUploadSupport() && opts.fallback !== false) { + opts.fallback(self); + return; + } + if (!self.uploadUrl && self.enableResumableUpload) { + self._log(logs.noUploadUrl); + self.enableResumableUpload = false; + return; + + } + opts.chunkSize = parseFloat(opts.chunkSize); + if (opts.chunkSize <= 0 || isNaN(opts.chunkSize)) { + self._log(logs.invalidChunkSize, {chunkSize: opts.chunkSize}); + self.enableResumableUpload = false; + return; + } + rm = self.resumableManager = { + init: function (id, f, index) { + rm.logs = []; + rm.stack = []; + rm.error = ''; + rm.id = id; + rm.file = f.file; + rm.fileName = f.name; + rm.fileIndex = index; + rm.completed = false; + rm.lastProgress = 0; + if (self.showPreview) { + rm.$thumb = fm.getThumb(id) || null; + rm.$progress = rm.$btnDelete = null; + if (rm.$thumb && rm.$thumb.length) { + rm.$progress = rm.$thumb.find('.file-thumb-progress'); + rm.$btnDelete = rm.$thumb.find('.kv-file-remove'); + } + } + rm.chunkSize = opts.chunkSize * self.bytesToKB; + rm.chunkCount = rm.getTotalChunks(); + }, + setAjaxError: function (jqXHR, textStatus, errorThrown, isTest) { + if (jqXHR.responseJSON && jqXHR.responseJSON.error) { + errorThrown = jqXHR.responseJSON.error.toString(); + } + if (!isTest) { + rm.error = errorThrown; + } + if (opts.showErrorLog) { + self._log(logs.ajaxError, { + status: jqXHR.status, + error: errorThrown, + text: jqXHR.responseText || '' + }); + } + }, + reset: function () { + rm.stack = []; + rm.chunksProcessed = {}; + }, + setProcessed: function (status) { + var id = rm.id, msg, $thumb = rm.$thumb, $prog = rm.$progress, hasThumb = $thumb && $thumb.length, + params = {id: hasThumb ? $thumb.attr('id') : '', index: fm.getIndex(id), fileId: id}, tokens, + skipErrorsAndProceed = self.resumableUploadOptions.skipErrorsAndProceed; + rm.completed = true; + rm.lastProgress = 0; + if (hasThumb) { + $thumb.removeClass('file-uploading'); + } + if (status === 'success') { + fm.uploadedSize += rm.file.size; + if (self.showPreview) { + self._setProgress(101, $prog); + self._setThumbStatus($thumb, 'Success'); + self._initUploadSuccess(rm.chunksProcessed[id].data, $thumb); + } + fm.removeFile(id); + delete rm.chunksProcessed[id]; + self._raise('fileuploaded', [params.id, params.index, params.fileId]); + if (fm.isProcessed()) { + self._setProgress(101); + } + } else { + if (status !== 'cancel') { + if (self.showPreview) { + self._setThumbStatus($thumb, 'Error'); + self._setPreviewError($thumb, true); + self._setProgress(101, $prog, self.msgProgressError); + self._setProgress(101, self.$progress, self.msgProgressError); + self.cancelling = !skipErrorsAndProceed; + } + if (!self.$errorContainer.find('li[data-file-id="' + params.fileId + '"]').length) { + tokens = {file: rm.fileName, max: opts.maxRetries, error: rm.error}; + msg = self.msgResumableUploadRetriesExceeded.setTokens(tokens); + $.extend(params, tokens); + self._showFileError(msg, params, 'filemaxretries'); + if (skipErrorsAndProceed) { + fm.removeFile(id); + delete rm.chunksProcessed[id]; + if (fm.isProcessed()) { + self._setProgress(101); + } + } + } + } + } + if (fm.isProcessed()) { + rm.reset(); + } + }, + check: function () { + var status = true; + $.each(rm.logs, function (index, value) { + if (!value) { + status = false; + return false; + } + }); + }, + processedResumables: function () { + var logs = rm.logs, i, count = 0; + if (!logs || !logs.length) { + return 0; + } + for (i = 0; i < logs.length; i++) { + if (logs[i] === true) { + count++; + } + } + return count; + }, + getUploadedSize: function () { + var size = rm.processedResumables() * rm.chunkSize; + return size > rm.file.size ? rm.file.size : size; + }, + getTotalChunks: function () { + var chunkSize = parseFloat(rm.chunkSize); + if (!isNaN(chunkSize) && chunkSize > 0) { + return Math.ceil(rm.file.size / chunkSize); + } + return 0; + }, + getProgress: function () { + var chunksProcessed = rm.processedResumables(), total = rm.chunkCount; + if (total === 0) { + return 0; + } + return Math.ceil(chunksProcessed / total * 100); + }, + checkAborted: function (intervalId) { + if (self._isAborted()) { + clearInterval(intervalId); + self.unlock(); + } + }, + upload: function () { + var ids = fm.getIdList(), flag = 'new', intervalId; + intervalId = setInterval(function () { + var id; + rm.checkAborted(intervalId); + if (flag === 'new') { + self.lock(); + flag = 'processing'; + id = ids.shift(); + fm.initStats(id); + if (fm.stack[id]) { + rm.init(id, fm.stack[id], fm.getIndex(id)); + rm.processUpload(); + } + } + if (!fm.isPending(id) && rm.completed) { + flag = 'new'; + } + if (fm.isProcessed()) { + var $initThumbs = self.$preview.find('.file-preview-initial'); + if ($initThumbs.length) { + $h.addCss($initThumbs, $h.SORT_CSS); + self._initSortable(); + } + clearInterval(intervalId); + self._clearFileInput(); + self.unlock(); + setTimeout(function () { + var data = self.previewCache.data; + if (data) { + self.initialPreview = data.content; + self.initialPreviewConfig = data.config; + self.initialPreviewThumbTags = data.tags; + } + self._raise('filebatchuploadcomplete', [ + self.initialPreview, + self.initialPreviewConfig, + self.initialPreviewThumbTags, + self._getExtraData() + ]); + }, self.processDelay); + } + }, self.processDelay); + }, + uploadResumable: function () { + var i, pool, tm = self.taskManager, total = rm.chunkCount; + pool = tm.addPool(rm.id); + for (i = 0; i < total; i++) { + rm.logs[i] = !!(rm.chunksProcessed[rm.id] && rm.chunksProcessed[rm.id][i]); + if (!rm.logs[i]) { + rm.pushAjax(i, 0); + } + } + pool.run(opts.maxThreads) + .done(function () { + rm.setProcessed('success'); + }) + .fail(function () { + rm.setProcessed(pool.cancelled ? 'cancel' : 'error'); + }); + }, + processUpload: function () { + var fd, f, id = rm.id, fnBefore, fnSuccess, fnError, fnComplete, outData; + if (!opts.testUrl) { + rm.uploadResumable(); + return; + } + fd = new FormData(); + f = fm.stack[id]; + self._setUploadData(fd, { + fileId: id, + fileName: f.fileName, + fileSize: f.size, + fileRelativePath: f.relativePath, + chunkSize: rm.chunkSize, + chunkCount: rm.chunkCount + }); + fnBefore = function (jqXHR) { + outData = self._getOutData(fd, jqXHR); + self._raise('filetestbeforesend', [id, fm, rm, outData]); + }; + fnSuccess = function (data, textStatus, jqXHR) { + outData = self._getOutData(fd, jqXHR, data); + var pNames = self.uploadParamNames, chunksUploaded = pNames.chunksUploaded || 'chunksUploaded', + params = [id, fm, rm, outData]; + if (!data[chunksUploaded] || !$h.isArray(data[chunksUploaded])) { + self._raise('filetesterror', params); + } else { + if (!rm.chunksProcessed[id]) { + rm.chunksProcessed[id] = {}; + } + $.each(data[chunksUploaded], function (key, index) { + rm.logs[index] = true; + rm.chunksProcessed[id][index] = true; + }); + rm.chunksProcessed[id].data = data; + self._raise('filetestsuccess', params); + } + rm.uploadResumable(); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + outData = self._getOutData(fd, jqXHR); + self._raise('filetestajaxerror', [id, fm, rm, outData]); + rm.setAjaxError(jqXHR, textStatus, errorThrown, true); + rm.uploadResumable(); + }; + fnComplete = function () { + self._raise('filetestcomplete', [id, fm, rm, self._getOutData(fd)]); + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex, opts.testUrl); + }, + pushAjax: function (index, retry) { + var tm = self.taskManager, pool = tm.getPool(rm.id); + pool.addTask(pool.size() + 1, function (deferrer) { + // use fifo chunk stack + var arr = rm.stack.shift(), index; + index = arr[0]; + if (!rm.chunksProcessed[rm.id] || !rm.chunksProcessed[rm.id][index]) { + rm.sendAjax(index, arr[1], deferrer); + } else { + self._log(logs.chunkQueueError, {index: index}); + } + }); + rm.stack.push([index, retry]); + }, + sendAjax: function (index, retry, deferrer) { + var f, chunkSize = rm.chunkSize, id = rm.id, file = rm.file, $thumb = rm.$thumb, + msgs = $h.logMessages, $btnDelete = rm.$btnDelete, logError = function (msg, tokens) { + if (tokens) { + msg = msg.setTokens(tokens); + } + msg = msgs.resumableRequestError.setTokens({msg: msg}); + self._log(msg); + deferrer.reject(msg); + }; + if (rm.chunksProcessed[id] && rm.chunksProcessed[id][index]) { + return; + } + if (retry > opts.maxRetries) { + logError(msgs.resumableMaxRetriesReached, {n: opts.maxRetries}); + rm.setProcessed('error'); + return; + } + var fd, outData, fnBefore, fnSuccess, fnError, fnComplete, slice = file.slice ? 'slice' : + (file.mozSlice ? 'mozSlice' : (file.webkitSlice ? 'webkitSlice' : 'slice')), + blob = file[slice](chunkSize * index, chunkSize * (index + 1)); + fd = new FormData(); + f = fm.stack[id]; + self._setUploadData(fd, { + chunkCount: rm.chunkCount, + chunkIndex: index, + chunkSize: chunkSize, + chunkSizeStart: chunkSize * index, + fileBlob: [blob, rm.fileName], + fileId: id, + fileName: rm.fileName, + fileRelativePath: f.relativePath, + fileSize: file.size, + retryCount: retry + }); + if (rm.$progress && rm.$progress.length) { + rm.$progress.show(); + } + fnBefore = function (jqXHR) { + outData = self._getOutData(fd, jqXHR); + if (self.showPreview) { + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnDelete.attr('disabled', true); + } + self._raise('filechunkbeforesend', [id, index, retry, fm, rm, outData]); + }; + fnSuccess = function (data, textStatus, jqXHR) { + if (self._isAborted()) { + logError(msgs.resumableAborting); + return; + } + outData = self._getOutData(fd, jqXHR, data); + var paramNames = self.uploadParamNames, chunkIndex = paramNames.chunkIndex || 'chunkIndex', + params = [id, index, retry, fm, rm, outData]; + if (data.error) { + if (opts.showErrorLog) { + self._log(logs.retryStatus, { + retry: retry + 1, + filename: rm.fileName, + chunk: index + }); + } + self._raise('filechunkerror', params); + rm.pushAjax(index, retry + 1); + rm.error = data.error; + logError(data.error); + } else { + rm.logs[data[chunkIndex]] = true; + if (!rm.chunksProcessed[id]) { + rm.chunksProcessed[id] = {}; + } + rm.chunksProcessed[id][data[chunkIndex]] = true; + rm.chunksProcessed[id].data = data; + deferrer.resolve.call(null, data); + self._raise('filechunksuccess', params); + rm.check(); + } + }; + fnError = function (jqXHR, textStatus, errorThrown) { + if (self._isAborted()) { + logError(msgs.resumableAborting); + return; + } + outData = self._getOutData(fd, jqXHR); + rm.setAjaxError(jqXHR, textStatus, errorThrown); + self._raise('filechunkajaxerror', [id, index, retry, fm, rm, outData]); + rm.pushAjax(index, retry + 1); // push another task + logError(msgs.resumableRetryError, {n: retry - 1}); // resolve the current task + }; + fnComplete = function () { + if (!self._isAborted()) { + self._raise('filechunkcomplete', [id, index, retry, fm, rm, self._getOutData(fd)]); + } + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, fd, id, rm.fileIndex); + } + }; + rm.reset(); + }, + _initTemplateDefaults: function () { + var self = this, tMain1, tMain2, tPreview, tFileIcon, tClose, tCaption, tBtnDefault, tBtnLink, tBtnBrowse, + tModalMain, tModal, tProgress, tSize, tFooter, tActions, tActionDelete, tActionUpload, tActionDownload, + tActionZoom, tActionDrag, tIndicator, tTagBef, tTagBef1, tTagBef2, tTagAft, tGeneric, tHtml, tImage, + tText, tOffice, tGdocs, tVideo, tAudio, tFlash, tObject, tPdf, tOther, tStyle, tZoomCache, vDefaultDim, + tStats, tModalLabel, tDescClose, renderObject = function (type, mime) { + return '\n' + $h.DEFAULT_PREVIEW + '\n\n'; + }, defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss(); + tMain1 = '{preview}\n' + + '
\n' + + '
\n' + + '
\n' + + ' {caption}\n\n' + + ($h.isBs(5) ? '' : '
\n') + + ' {remove}\n' + + ' {cancel}\n' + + ' {pause}\n' + + ' {upload}\n' + + ' {browse}\n' + + ($h.isBs(5) ? '' : '
\n') + + '
' + '
'; + tMain2 = '{preview}\n
\n
\n' + + '{remove}\n{cancel}\n{upload}\n{browse}\n'; + tPreview = '
\n' + + ' {close}' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
\n' + + '
'; + tClose = $h.closeButton('fileinput-remove'); + tFileIcon = ''; + // noinspection HtmlUnknownAttribute + tCaption = '\n'; + //noinspection HtmlUnknownAttribute + tBtnDefault = ''; + //noinspection HtmlUnknownTarget,HtmlUnknownAttribute + tBtnLink = '
{icon} {label}'; + //noinspection HtmlUnknownAttribute + tBtnBrowse = '
{icon} {label}
'; + tModalLabel = $h.MODAL_ID + 'Label'; + tModalMain = ''; + tModal = '\n'; + tDescClose = ''; + tProgress = '
\n' + + '
\n' + + ' {status}\n' + + '
\n' + + '
{stats}'; + tStats = '
' + + '{pendingTime} ' + + '{uploadSpeed}' + + '
'; + tSize = ' ({sizeText})'; + tFooter = ''; + tActions = '
\n' + + ' \n' + + '
\n' + + '{drag}\n' + + '
'; + //noinspection HtmlUnknownAttribute + tActionDelete = '\n'; + tActionUpload = ''; + tActionDownload = '{downloadIcon}'; + tActionZoom = ''; + tActionDrag = '{dragIcon}'; + tIndicator = '
{indicator}
'; + tTagBef = '
\n'; + tTagBef2 = tTagBef + ' title="{caption}">
\n'; + tTagAft = '
{footer}\n{zoomCache}
\n'; + tGeneric = '{content}\n'; + tStyle = ' {style}'; + tHtml = renderObject('html', 'text/html'); + tText = renderObject('text', 'text/plain;charset=UTF-8'); + tPdf = renderObject('pdf', 'application/pdf'); + tImage = '{alt}\n'; + tOffice = ''; + tGdocs = ''; + tVideo = '\n'; + tAudio = '\n'; + tFlash = '\n'; + tObject = '\n' + '\n' + + $h.OBJECT_PARAMS + ' ' + $h.DEFAULT_PREVIEW + '\n\n'; + tOther = '
\n' + $h.DEFAULT_PREVIEW + '\n
\n'; + tZoomCache = '
{zoomContent}
'; + vDefaultDim = {width: '100%', height: '100%', 'min-height': '480px'}; + if (self._isPdfRendered()) { + tPdf = self.pdfRendererTemplate.replace('{renderer}', self._encodeURI(self.pdfRendererUrl)); + } + self.defaults = { + layoutTemplates: { + main1: tMain1, + main2: tMain2, + preview: tPreview, + close: tClose, + fileIcon: tFileIcon, + caption: tCaption, + modalMain: tModalMain, + modal: tModal, + descriptionClose: tDescClose, + progress: tProgress, + stats: tStats, + size: tSize, + footer: tFooter, + indicator: tIndicator, + actions: tActions, + actionDelete: tActionDelete, + actionUpload: tActionUpload, + actionDownload: tActionDownload, + actionZoom: tActionZoom, + actionDrag: tActionDrag, + btnDefault: tBtnDefault, + btnLink: tBtnLink, + btnBrowse: tBtnBrowse, + zoomCache: tZoomCache + }, + previewMarkupTags: { + tagBefore1: tTagBef1, + tagBefore2: tTagBef2, + tagAfter: tTagAft + }, + previewContentTemplates: { + generic: tGeneric, + html: tHtml, + image: tImage, + text: tText, + office: tOffice, + gdocs: tGdocs, + video: tVideo, + audio: tAudio, + flash: tFlash, + object: tObject, + pdf: tPdf, + other: tOther + }, + allowedPreviewTypes: ['image', 'html', 'text', 'video', 'audio', 'flash', 'pdf', 'object'], + previewTemplates: {}, + previewSettings: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: {width: '213px', height: '160px'}, + text: {width: '213px', height: '160px'}, + office: {width: '213px', height: '160px'}, + gdocs: {width: '213px', height: '160px'}, + video: {width: '213px', height: '160px'}, + audio: {width: '100%', height: '30px'}, + flash: {width: '213px', height: '160px'}, + object: {width: '213px', height: '160px'}, + pdf: {width: '100%', height: '160px', 'position': 'relative'}, + other: {width: '213px', height: '160px'} + }, + previewSettingsSmall: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: {width: '100%', height: '160px'}, + text: {width: '100%', height: '160px'}, + office: {width: '100%', height: '160px'}, + gdocs: {width: '100%', height: '160px'}, + video: {width: '100%', height: 'auto'}, + audio: {width: '100%', height: '30px'}, + flash: {width: '100%', height: 'auto'}, + object: {width: '100%', height: 'auto'}, + pdf: {width: '100%', height: '160px'}, + other: {width: '100%', height: '160px'} + }, + previewZoomSettings: { + image: {width: 'auto', height: 'auto', 'max-width': '100%', 'max-height': '100%'}, + html: vDefaultDim, + text: vDefaultDim, + office: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + gdocs: {width: '100%', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + video: {width: 'auto', height: '100%', 'max-width': '100%'}, + audio: {width: '100%', height: '30px'}, + flash: {width: 'auto', height: '480px'}, + object: {width: 'auto', height: '100%', 'max-width': '100%', 'min-height': '480px'}, + pdf: vDefaultDim, + other: {width: 'auto', height: '100%', 'min-height': '480px'} + }, + mimeTypeAliases: { + 'video/quicktime': 'video/mp4' + }, + fileTypeSettings: { + image: function (vType, vName) { + return ($h.compare(vType, 'image.*') && !$h.compare(vType, /(tiff?|wmf)$/i) || + $h.compare(vName, /\.(gif|png|jpe?g)$/i)); + }, + html: function (vType, vName) { + return $h.compare(vType, 'text/html') || $h.compare(vName, /\.(htm|html)$/i); + }, + office: function (vType, vName) { + return $h.compare(vType, /(word|excel|powerpoint|office)$/i) || + $h.compare(vName, /\.(docx?|xlsx?|pptx?|pps|potx?)$/i); + }, + gdocs: function (vType, vName) { + return $h.compare(vType, /(word|excel|powerpoint|office|iwork-pages|tiff?)$/i) || + $h.compare(vName, + /\.(docx?|xlsx?|pptx?|pps|potx?|rtf|ods|odt|pages|ai|dxf|ttf|tiff?|wmf|e?ps)$/i); + }, + text: function (vType, vName) { + return $h.compare(vType, 'text.*') || $h.compare(vName, /\.(xml|javascript)$/i) || + $h.compare(vName, /\.(txt|md|nfo|ini|json|php|js|css)$/i); + }, + video: function (vType, vName) { + return $h.compare(vType, 'video.*') && ($h.compare(vType, /(ogg|mp4|mp?g|mov|webm|3gp)$/i) || + $h.compare(vName, /\.(og?|mp4|webm|mp?g|mov|3gp)$/i)); + }, + audio: function (vType, vName) { + return $h.compare(vType, 'audio.*') && ($h.compare(vName, /(ogg|mp3|mp?g|wav)$/i) || + $h.compare(vName, /\.(og?|mp3|mp?g|wav)$/i)); + }, + flash: function (vType, vName) { + return $h.compare(vType, 'application/x-shockwave-flash', true) || $h.compare(vName, + /\.(swf)$/i); + }, + pdf: function (vType, vName) { + return $h.compare(vType, 'application/pdf', true) || $h.compare(vName, /\.(pdf)$/i); + }, + object: function () { + return true; + }, + other: function () { + return true; + } + }, + fileActionSettings: { + showRemove: true, + showUpload: true, + showDownload: true, + showZoom: true, + showDrag: true, + removeIcon: '', + removeClass: defBtnCss1, + removeErrorClass: 'btn btn-sm btn-kv btn-danger', + removeTitle: 'Remove file', + uploadIcon: '', + uploadClass: defBtnCss1, + uploadTitle: 'Upload file', + uploadRetryIcon: '', + uploadRetryTitle: 'Retry upload', + downloadIcon: '', + downloadClass: defBtnCss1, + downloadTitle: 'Download file', + zoomIcon: '', + zoomClass: defBtnCss1, + zoomTitle: 'View Details', + dragIcon: '', + dragClass: 'text-primary', + dragTitle: 'Move / Rearrange', + dragSettings: {}, + indicatorNew: '', + indicatorSuccess: '', + indicatorError: '', + indicatorLoading: '', + indicatorPaused: '', + indicatorNewTitle: 'Not uploaded yet', + indicatorSuccessTitle: 'Uploaded', + indicatorErrorTitle: 'Upload Error', + indicatorLoadingTitle: 'Uploading …', + indicatorPausedTitle: 'Upload Paused' + } + }; + $.each(self.defaults, function (key, setting) { + if (key === 'allowedPreviewTypes') { + if (self.allowedPreviewTypes === undefined) { + self.allowedPreviewTypes = setting; + } + return; + } + self[key] = $.extend(true, {}, setting, self[key]); + }); + self._initPreviewTemplates(); + }, + _initPreviewTemplates: function () { + var self = this, tags = self.previewMarkupTags, tagBef, tagAft = tags.tagAfter; + $.each(self.previewContentTemplates, function (key, value) { + if ($h.isEmpty(self.previewTemplates[key])) { + tagBef = tags.tagBefore2; + if (key === 'generic' || key === 'image') { + tagBef = tags.tagBefore1; + } + if (self._isPdfRendered() && key === 'pdf') { + tagBef = tagBef.replace('kv-file-content', 'kv-file-content kv-pdf-rendered'); + } + self.previewTemplates[key] = tagBef + value + tagAft; + } + }); + }, + _initPreviewCache: function () { + var self = this; + self.previewCache = { + data: {}, + init: function () { + var content = self.initialPreview; + if (content.length > 0 && !$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + self.previewCache.data = { + content: content, + config: self.initialPreviewConfig, + tags: self.initialPreviewThumbTags + }; + }, + count: function (skipNull) { + if (!self.previewCache.data || !self.previewCache.data.content) { + return 0; + } + if (skipNull) { + var chk = self.previewCache.data.content.filter(function (n) { + return n !== null; + }); + return chk.length; + } + return self.previewCache.data.content.length; + }, + get: function (i, isDisabled) { + var ind = $h.INIT_FLAG + i, data = self.previewCache.data, config = data.config[i], + content = data.content[i], out, $tmp, cat, ftr, + fname, ftype, frameClass, asData = $h.ifSet('previewAsData', config, self.initialPreviewAsData), + a = config ? {title: config.title || null, alt: config.alt || null} : {title: null, alt: null}, + parseTemplate = function (cat, dat, fname, ftype, ftr, ind, fclass, t) { + var fc = ' file-preview-initial ' + $h.SORT_CSS + (fclass ? ' ' + fclass : ''), + id = self.previewInitId + '-' + ind, + fileId = config && config.fileId || id; + /** @namespace config.zoomData */ + return self._generatePreviewTemplate(cat, dat, fname, ftype, id, fileId, false, null, fc, + ftr, ind, t, a, config && config.zoomData || dat); + }; + if (!content || !content.length) { + return ''; + } + isDisabled = isDisabled === undefined ? true : isDisabled; + cat = $h.ifSet('type', config, self.initialPreviewFileType || 'generic'); + fname = $h.ifSet('filename', config, $h.ifSet('caption', config)); + ftype = $h.ifSet('filetype', config, cat); + ftr = self.previewCache.footer(i, isDisabled, (config && config.size || null)); + frameClass = $h.ifSet('frameClass', config); + if (asData) { + out = parseTemplate(cat, content, fname, ftype, ftr, ind, frameClass); + } else { + out = parseTemplate('generic', content, fname, ftype, ftr, ind, frameClass, cat) + .setTokens({'content': data.content[i]}); + } + if (data.tags.length && data.tags[i]) { + out = $h.replaceTags(out, data.tags[i]); + } + /** @namespace config.frameAttr */ + if (!$h.isEmpty(config) && !$h.isEmpty(config.frameAttr)) { + $tmp = $h.createElement(out); + $tmp.find('.file-preview-initial').attr(config.frameAttr); + out = $tmp.html(); + $tmp.remove(); + } + return out; + }, + clean: function (data) { + data.content = $h.cleanArray(data.content); + data.config = $h.cleanArray(data.config); + data.tags = $h.cleanArray(data.tags); + self.previewCache.data = data; + }, + add: function (content, config, tags, append) { + var data = self.previewCache.data, index; + if (!content || !content.length) { + return 0; + } + index = content.length - 1; + if (!$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + if (append && data.content) { + index = data.content.push(content[0]) - 1; + data.config[index] = config; + data.tags[index] = tags; + } else { + data.content = content; + data.config = config; + data.tags = tags; + } + self.previewCache.clean(data); + return index; + }, + set: function (content, config, tags, append) { + var data = self.previewCache.data, i, chk; + if (!content || !content.length) { + return; + } + if (!$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + chk = content.filter(function (n) { + return n !== null; + }); + if (!chk.length) { + return; + } + if (data.content === undefined) { + data.content = []; + } + if (data.config === undefined) { + data.config = []; + } + if (data.tags === undefined) { + data.tags = []; + } + if (append) { + for (i = 0; i < content.length; i++) { + if (content[i]) { + data.content.push(content[i]); + } + } + for (i = 0; i < config.length; i++) { + if (config[i]) { + data.config.push(config[i]); + } + } + for (i = 0; i < tags.length; i++) { + if (tags[i]) { + data.tags.push(tags[i]); + } + } + } else { + data.content = content; + data.config = config; + data.tags = tags; + } + self.previewCache.clean(data); + }, + unset: function (index) { + var chk = self.previewCache.count(), rev = self.reversePreviewOrder; + if (!chk) { + return; + } + if (chk === 1) { + self.previewCache.data.content = []; + self.previewCache.data.config = []; + self.previewCache.data.tags = []; + self.initialPreview = []; + self.initialPreviewConfig = []; + self.initialPreviewThumbTags = []; + return; + } + self.previewCache.data.content = $h.spliceArray(self.previewCache.data.content, index, rev); + self.previewCache.data.config = $h.spliceArray(self.previewCache.data.config, index, rev); + self.previewCache.data.tags = $h.spliceArray(self.previewCache.data.tags, index, rev); + var data = $.extend(true, {}, self.previewCache.data); + self.previewCache.clean(data); + }, + out: function () { + var html = '', caption, len = self.previewCache.count(), i, content; + if (len === 0) { + return {content: '', caption: ''}; + } + for (i = 0; i < len; i++) { + content = self.previewCache.get(i); + html = self.reversePreviewOrder ? (content + html) : (html + content); + } + caption = self._getMsgSelected(len); + return {content: html, caption: caption}; + }, + footer: function (i, isDisabled, size) { + var data = self.previewCache.data || {}; + if ($h.isEmpty(data.content)) { + return ''; + } + if ($h.isEmpty(data.config) || $h.isEmpty(data.config[i])) { + data.config[i] = {}; + } + isDisabled = isDisabled === undefined ? true : isDisabled; + var config = data.config[i], caption = $h.ifSet('caption', config), a, + width = $h.ifSet('width', config, 'auto'), url = $h.ifSet('url', config, false), + key = $h.ifSet('key', config, null), fileId = $h.ifSet('fileId', config, null), + fs = self.fileActionSettings, initPreviewShowDel = self.initialPreviewShowDelete || false, + downloadInitialUrl = !self.initialPreviewDownloadUrl ? '' : + self.initialPreviewDownloadUrl + '?key=' + key + (fileId ? '&fileId=' + fileId : ''), + dUrl = config.downloadUrl || downloadInitialUrl, + dFil = config.filename || config.caption || '', + initPreviewShowDwl = !!(dUrl), + sDel = $h.ifSet('showRemove', config, initPreviewShowDel), + sDwl = $h.ifSet('showDownload', config, $h.ifSet('showDownload', fs, initPreviewShowDwl)), + sZm = $h.ifSet('showZoom', config, $h.ifSet('showZoom', fs, true)), + sDrg = $h.ifSet('showDrag', config, $h.ifSet('showDrag', fs, true)), + dis = (url === false) && isDisabled; + sDwl = sDwl && config.downloadUrl !== false && !!dUrl; + a = self._renderFileActions(config, false, sDwl, sDel, sZm, sDrg, dis, url, key, true, dUrl, dFil); + return self._getLayoutTemplate('footer').setTokens({ + 'progress': self._renderThumbProgress(), + 'actions': a, + 'caption': caption, + 'size': self._getSize(size), + 'width': width, + 'indicator': '' + }); + } + }; + self.previewCache.init(); + }, + _isPdfRendered: function () { + var self = this, useLib = self.usePdfRenderer, + flag = typeof useLib === 'function' ? useLib() : !!useLib; + return flag && self.pdfRendererUrl; + }, + _handler: function ($el, event, callback) { + var self = this, ns = self.namespace, ev = event.split(' ').join(ns + ' ') + ns; + if (!$el || !$el.length) { + return; + } + $el.off(ev).on(ev, callback); + }, + _encodeURI: function (vUrl) { + var self = this; + return self.encodeUrl ? encodeURI(vUrl) : vUrl; + }, + _log: function (msg, tokens) { + var self = this, id = self.$element.attr('id'); + if (!self.showConsoleLogs) { + return; + } + if (id) { + msg = '"' + id + '": ' + msg; + } + msg = 'bootstrap-fileinput: ' + msg; + if (typeof tokens === 'object') { + msg = msg.setTokens(tokens); + } + if (window.console && typeof window.console.log !== 'undefined') { + window.console.log(msg); + } else { + window.alert(msg); + } + }, + _validate: function () { + var self = this, status = self.$element.attr('type') === 'file'; + if (!status) { + self._log($h.logMessages.badInputType); + } + return status; + }, + _errorsExist: function () { + var self = this, $err, $errList = self.$errorContainer.find('li'); + if ($errList.length) { + return true; + } + $err = $h.createElement(self.$errorContainer.html()); + $err.find('.kv-error-close').remove(); + $err.find('ul').remove(); + return !!$.trim($err.text()).length; + }, + _errorHandler: function (evt, caption) { + var self = this, err = evt.target.error, showError = function (msg) { + self._showError(msg.replace('{name}', caption)); + }; + /** @namespace err.NOT_FOUND_ERR */ + /** @namespace err.SECURITY_ERR */ + /** @namespace err.NOT_READABLE_ERR */ + if (err.code === err.NOT_FOUND_ERR) { + showError(self.msgFileNotFound); + } else { + if (err.code === err.SECURITY_ERR) { + showError(self.msgFileSecured); + } else { + if (err.code === err.NOT_READABLE_ERR) { + showError(self.msgFileNotReadable); + } else { + if (err.code === err.ABORT_ERR) { + showError(self.msgFilePreviewAborted); + } else { + showError(self.msgFilePreviewError); + } + } + } + } + }, + _addError: function (msg) { + var self = this, $error = self.$errorContainer; + if (msg && $error.length) { + $h.setHtml($error, self.errorCloseButton + msg); + self._handler($error.find('.kv-error-close'), 'click', function () { + setTimeout(function () { + if (self.showPreview && !self.getFrames().length) { + self.clear(); + } + $error.fadeOut('slow'); + }, self.processDelay); + }); + } + }, + _setValidationError: function (css) { + var self = this; + css = (css ? css + ' ' : '') + 'has-error'; + self.$container.removeClass(css).addClass('has-error'); + $h.addCss(self.$caption, 'is-invalid'); + }, + _resetErrors: function (fade) { + var self = this, $error = self.$errorContainer, history = self.resumableUploadOptions.retainErrorHistory; + if (self.isPersistentError || (self.enableResumableUpload && history)) { + return; + } + self.isError = false; + self.$container.removeClass('has-error'); + self.$caption.removeClass('is-invalid is-valid file-processing'); + $error.html(''); + if (fade) { + $error.fadeOut('slow'); + } else { + $error.hide(); + } + }, + _showFolderError: function (folders) { + var self = this, $error = self.$errorContainer, msg; + if (!folders) { + return; + } + if (!self.isAjaxUpload) { + self._clearFileInput(); + } + msg = self.msgFoldersNotAllowed.replace('{n}', folders); + self._addError(msg); + self._setValidationError(); + $error.fadeIn(self.fadeDelay); + self._raise('filefoldererror', [folders, msg]); + }, + _showFileError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileuploaderror', + fId = params && params.fileId || '', e = params && params.id ? + '
  • ' + msg + '
  • ' : '
  • ' + msg + '
  • '; + + if ($error.find('ul').length === 0) { + self._addError('
      ' + e + '
    '); + } else { + $error.find('ul').append(e); + } + $error.fadeIn(self.fadeDelay); + self._raise(ev, [params, msg]); + self._setValidationError('file-input-new'); + return true; + }, + _showError: function (msg, params, event) { + var self = this, $error = self.$errorContainer, ev = event || 'fileerror'; + params = params || {}; + params.reader = self.reader; + self._addError(msg); + $error.fadeIn(self.fadeDelay); + self._raise(ev, [params, msg]); + if (!self.isAjaxUpload) { + self._clearFileInput(); + } + self._setValidationError('file-input-new'); + self.$btnUpload.attr('disabled', true); + return true; + }, + _noFilesError: function (params) { + var self = this, label = self.minFileCount > 1 ? self.filePlural : self.fileSingle, + msg = self.msgFilesTooLess.replace('{n}', self.minFileCount).replace('{files}', label), + $error = self.$errorContainer; + msg = '
  • ' + msg + '
  • '; + if ($error.find('ul').length === 0) { + self._addError('
      ' + msg + '
    '); + } else { + $error.find('ul').append(msg); + } + self.isError = true; + self._updateFileDetails(0); + $error.fadeIn(self.fadeDelay); + self._raise('fileerror', [params, msg]); + self._clearFileInput(); + self._setValidationError(); + }, + _parseError: function (operation, jqXHR, errorThrown, fileName) { + /** @namespace jqXHR.responseJSON */ + var self = this, errMsg = $.trim(errorThrown + ''), textPre, errText, text; + errText = jqXHR.responseJSON && jqXHR.responseJSON.error ? jqXHR.responseJSON.error.toString() : ''; + text = errText ? errText : jqXHR.responseText; + if (self.cancelling && self.msgUploadAborted) { + errMsg = self.msgUploadAborted; + } + if (self.showAjaxErrorDetails && text) { + if (errText) { + errMsg = $.trim(errText + ''); + } else { + text = $.trim(text.replace(/\n\s*\n/g, '\n')); + textPre = text.length ? '
    ' + text + '
    ' : ''; + errMsg += errMsg ? textPre : text; + } + } + if (!errMsg) { + errMsg = self.msgAjaxError.replace('{operation}', operation); + } + self.cancelling = false; + return fileName ? '' + fileName + ': ' + errMsg : errMsg; + }, + _parseFileType: function (type, name) { + var self = this, isValid, vType, cat, i, types = self.allowedPreviewTypes || []; + if (type === 'application/text-plain') { + return 'text'; + } + for (i = 0; i < types.length; i++) { + cat = types[i]; + isValid = self.fileTypeSettings[cat]; + vType = isValid(type, name) ? cat : ''; + if (!$h.isEmpty(vType)) { + return vType; + } + } + return 'other'; + }, + _getPreviewIcon: function (fname) { + var self = this, ext, out = null; + if (fname && fname.indexOf('.') > -1) { + ext = fname.split('.').pop(); + if (self.previewFileIconSettings) { + out = self.previewFileIconSettings[ext] || self.previewFileIconSettings[ext.toLowerCase()] || null; + } + if (self.previewFileExtSettings) { + $.each(self.previewFileExtSettings, function (key, func) { + if (self.previewFileIconSettings[key] && func(ext)) { + out = self.previewFileIconSettings[key]; + //noinspection UnnecessaryReturnStatementJS + return; + } + }); + } + } + return out || self.previewFileIcon; + }, + _parseFilePreviewIcon: function (content, fname) { + var self = this, icn = self._getPreviewIcon(fname), out = content; + if (out.indexOf('{previewFileIcon}') > -1) { + out = out.setTokens({'previewFileIconClass': self.previewFileIconClass, 'previewFileIcon': icn}); + } + return out; + }, + _raise: function (event, params) { + var self = this, e = $.Event(event); + if (params !== undefined) { + self.$element.trigger(e, params); + } else { + self.$element.trigger(e); + } + var out = e.result, isAborted = out === false; + if (e.isDefaultPrevented() || isAborted) { + return false; + } + if (e.type === 'filebatchpreupload' && (out || isAborted)) { + self.ajaxAborted = out; + return false; + } + switch (event) { + // ignore these events + case 'filebatchuploadcomplete': + case 'filebatchuploadsuccess': + case 'fileuploaded': + case 'fileclear': + case 'filecleared': + case 'filereset': + case 'fileerror': + case 'filefoldererror': + case 'fileuploaderror': + case 'filebatchuploaderror': + case 'filedeleteerror': + case 'filecustomerror': + case 'filesuccessremove': + break; + // receive data response via `filecustomerror` event` + default: + if (!self.ajaxAborted) { + self.ajaxAborted = out; + } + break; + } + return true; + }, + _listenFullScreen: function (isFullScreen) { + var self = this, $modal = self.$modal, $btnFull, $btnBord; + if (!$modal || !$modal.length) { + return; + } + $btnFull = $modal && $modal.find('.btn-kv-fullscreen'); + $btnBord = $modal && $modal.find('.btn-kv-borderless'); + if (!$btnFull.length || !$btnBord.length) { + return; + } + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + if (isFullScreen) { + $btnFull.addClass('active').attr('aria-pressed', 'true'); + } else { + $btnBord.addClass('active').attr('aria-pressed', 'true'); + } + if ($modal.hasClass('file-zoom-fullscreen')) { + self._maximizeZoomDialog(); + } else { + if (isFullScreen) { + self._maximizeZoomDialog(); + } else { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + } + } + }, + _listen: function () { + var self = this, $el = self.$element, $form = self.$form, $cont = self.$container, fullScreenEv; + self._handler($el, 'click', function (e) { + self._initFileSelected(); + if ($el.hasClass('file-no-browse')) { + if ($el.data('zoneClicked')) { + $el.data('zoneClicked', false); + } else { + e.preventDefault(); + } + } + }); + self._handler($el, 'change', $.proxy(self._change, self)); + self._handler(self.$caption, 'paste', $.proxy(self.paste, self)); + if (self.showBrowse) { + self._handler(self.$btnFile, 'click', $.proxy(self._browse, self)); + self._handler(self.$btnFile, 'keypress', function (e) { + var keycode = e.keyCode || e.which + if (keycode === 13) { + $el.trigger('click'); + self._browse(e); + } + }); + } + self._handler($cont.find('.fileinput-remove:not([disabled])'), 'click', $.proxy(self.clear, self)); + self._handler($cont.find('.fileinput-cancel'), 'click', $.proxy(self.cancel, self)); + self._handler($cont.find('.fileinput-pause'), 'click', $.proxy(self.pause, self)); + self._initDragDrop(); + self._handler($form, 'reset', $.proxy(self.clear, self)); + if (!self.isAjaxUpload) { + self._handler($form, 'submit', $.proxy(self._submitForm, self)); + } + self._handler(self.$container.find('.fileinput-upload'), 'click', $.proxy(self._uploadClick, self)); + self._handler($(window), 'resize', function () { + self._listenFullScreen(screen.width === window.innerWidth && screen.height === window.innerHeight); + }); + fullScreenEv = 'webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange'; + self._handler($(document), fullScreenEv, function () { + self._listenFullScreen($h.checkFullScreen()); + }); + self.$caption.on('focus', function () { + self.$captionContainer.focus(); + }); + self._autoFitContent(); + self._initClickable(); + self._refreshPreview(); + }, + _autoFitContent: function () { + var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, + self = this, config = width < 400 ? (self.previewSettingsSmall || self.defaults.previewSettingsSmall) : + (self.previewSettings || self.defaults.previewSettings), sel; + $.each(config, function (cat, settings) { + sel = '.file-preview-frame .file-preview-' + cat; + self.$preview.find(sel + '.kv-preview-data,' + sel + ' .kv-preview-data').css(settings); + }); + }, + _scanDroppedItems: function (item, files, path) { + path = path || ''; + var self = this, i, dirReader, readDir, errorHandler = function (e) { + self._log($h.logMessages.badDroppedFiles); + self._log(e); + }; + if (item.isFile) { + item.file(function (file) { + if (path) { + file.newPath = path + file.name; + } + files.push(file); + }, errorHandler); + } else { + if (item.isDirectory) { + dirReader = item.createReader(); + readDir = function () { + dirReader.readEntries(function (entries) { + if (entries && entries.length > 0) { + for (i = 0; i < entries.length; i++) { + self._scanDroppedItems(entries[i], files, path + item.name + '/'); + } + // recursively call readDir() again, since browser can only handle first 100 entries. + readDir(); + } + return null; + }, errorHandler); + }; + readDir(); + } + } + + }, + _initDragDrop: function () { + var self = this, $zone = self.$dropZone; + if (self.dropZoneEnabled && self.showPreview) { + self._handler($zone, 'dragenter dragover', $.proxy(self._zoneDragEnter, self)); + self._handler($zone, 'dragleave', $.proxy(self._zoneDragLeave, self)); + self._handler($zone, 'drop', $.proxy(self._zoneDrop, self)); + self._handler($(document), 'dragenter dragover drop', self._zoneDragDropInit); + } + }, + _zoneDragDropInit: function (e) { + e.stopPropagation(); + e.preventDefault(); + }, + _zoneDragEnter: function (e) { + var self = this, dt = e.originalEvent.dataTransfer, hasFiles = $.inArray('Files', dt.types) > -1; + self._zoneDragDropInit(e); + if (self.isDisabled || !hasFiles) { + dt.effectAllowed = 'none'; + dt.dropEffect = 'none'; + return; + } + dt.dropEffect = 'copy'; + if (self._raise('fileDragEnter', {'sourceEvent': e, 'files': dt.types.Files})) { + $h.addCss(self.$dropZone, 'file-highlighted'); + } + }, + _zoneDragLeave: function (e) { + var self = this; + self._zoneDragDropInit(e); + if (self.isDisabled) { + return; + } + if (self._raise('fileDragLeave', {'sourceEvent': e})) { + self.$dropZone.removeClass('file-highlighted'); + } + + }, + _dropFiles: function (e, files) { + var self = this, $el = self.$element; + if (!self.isAjaxUpload) { + self.changeTriggered = true; + $el.get(0).files = files; + setTimeout(function () { + self.changeTriggered = false; + $el.trigger('change' + self.namespace); + }, self.processDelay); + } else { + self._change(e, files); + } + self.$dropZone.removeClass('file-highlighted'); + }, + _zoneDrop: function (e) { + /** @namespace e.originalEvent.dataTransfer */ + var self = this, i, $el = self.$element, dt = e.originalEvent.dataTransfer, + files = dt.files, items = dt.items, folders = $h.getDragDropFolders(items); + e.preventDefault(); + if (self.isDisabled || $h.isEmpty(files)) { + return; + } + if (!self._raise('fileDragDrop', {'sourceEvent': e, 'files': files})) { + return; + } + if (folders > 0) { + if (!self.isAjaxUpload) { + self._showFolderError(folders); + return; + } + files = []; + for (i = 0; i < items.length; i++) { + var item = items[i].webkitGetAsEntry(); + if (item) { + self._scanDroppedItems(item, files); + } + } + setTimeout(function () { + self._dropFiles(e, files); + }, 500); + } else { + self._dropFiles(e, files); + } + }, + _uploadClick: function (e) { + var self = this, $btn = self.$container.find('.fileinput-upload'), $form, + isEnabled = !$btn.hasClass('disabled') && $h.isEmpty($btn.attr('disabled')); + if (e && e.isDefaultPrevented()) { + return; + } + if (!self.isAjaxUpload) { + if (isEnabled && $btn.attr('type') !== 'submit') { + $form = $btn.closest('form'); + // downgrade to normal form submit if possible + if ($form.length) { + $form.trigger('submit'); + } + e.preventDefault(); + } + return; + } + e.preventDefault(); + if (isEnabled) { + self.upload(); + } + }, + _submitForm: function () { + var self = this; + return self._isFileSelectionValid() && !self._abort({}); + }, + _clearPreview: function () { + var self = this, + $thumbs = self.showUploadedThumbs ? self.getFrames(':not(.file-preview-success)') : self.getFrames(); + $thumbs.each(function () { + var $thumb = $(this); + $thumb.remove(); + }); + if (!self.getFrames().length || !self.showPreview) { + self._resetUpload(); + } + self._validateDefaultPreview(); + }, + _initSortable: function () { + var self = this, $el = self.$preview, settings, selector = '.' + $h.SORT_CSS, $cont, $body = $('body'), + $html = $('html'), rev = self.reversePreviewOrder, Sortable = window.Sortable, beginGrab, endGrab; + if (!Sortable || $el.find(selector).length === 0) { + return; + } + $cont = $body.length ? $body : ($html.length ? $html : self.$container); + beginGrab = function () { + $cont.addClass('file-grabbing'); + }; + endGrab = function () { + $cont.removeClass('file-grabbing'); + }; + settings = { + handle: '.drag-handle-init', + dataIdAttr: 'data-fileid', + animation: 600, + draggable: selector, + scroll: false, + forceFallback: true, + onChoose: beginGrab, + onStart: beginGrab, + onUnchoose: endGrab, + onEnd: endGrab, + onSort: function (e) { + var oldIndex = e.oldIndex, newIndex = e.newIndex, i = 0, len = self.initialPreviewConfig.length, + exceedsLast = len > 0 && newIndex >= len, $item = $(e.item), $first; + if (exceedsLast) { + newIndex = len - 1; + } + self.initialPreview = $h.moveArray(self.initialPreview, oldIndex, newIndex, rev); + self.initialPreviewConfig = $h.moveArray(self.initialPreviewConfig, oldIndex, newIndex, rev); + self.previewCache.init(); + self.getFrames('.file-preview-initial').each(function () { + $(this).attr('data-fileindex', $h.INIT_FLAG + i); + i++; + }); + if (exceedsLast) { + $first = self.getFrames(':not(.file-preview-initial):first'); + if ($first.length) { + $item.slideUp(function () { + $item.insertBefore($first).slideDown(); + }); + } + } + self._raise('filesorted', { + previewId: $item.attr('id'), + 'oldIndex': oldIndex, + 'newIndex': newIndex, + stack: self.initialPreviewConfig + }); + }, + }; + $.extend(true, settings, self.fileActionSettings.dragSettings); + if (self.sortable) { + self.sortable.destroy(); + } + self.sortable = Sortable.create($el[0], settings); + }, + _setPreviewContent: function (content) { + var self = this; + $h.setHtml(self.$preview, content); + self._autoFitContent(); + }, + _initPreviewImageOrientations: function () { + var self = this, i = 0, canOrientImage = self.canOrientImage; + if (!self.autoOrientImageInitial && !canOrientImage) { + return; + } + self.getFrames('.file-preview-initial').each(function () { + var $thumb = $(this), $img, $zoomImg, id, config = self.initialPreviewConfig[i]; + /** @namespace config.exif */ + if (config && config.exif && config.exif.Orientation) { + id = $thumb.attr('id'); + $img = $thumb.find('>.kv-file-content img'); + $zoomImg = self._getZoom(id, ' >.kv-file-content img'); + if (canOrientImage) { + $img.css('image-orientation', (self.autoOrientImageInitial ? 'from-image' : 'none')); + } else { + self.setImageOrientation($img, $zoomImg, config.exif.Orientation, $thumb); + } + } + i++; + }); + }, + _initPreview: function (isInit) { + var self = this, cap = self.initialCaption || '', out; + if (!self.previewCache.count(true)) { + self._clearPreview(); + if (isInit) { + self._setCaption(cap); + } else { + self._initCaption(); + } + return; + } + out = self.previewCache.out(); + cap = isInit && self.initialCaption ? self.initialCaption : out.caption; + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + self._setCaption(cap); + self._initSortable(); + if (!$h.isEmpty(out.content)) { + self.$container.removeClass('file-input-new'); + } + self._initPreviewImageOrientations(); + }, + _getZoomButton: function (type) { + var self = this, label = self.previewZoomButtonIcons[type], css = self.previewZoomButtonClasses[type], + title = ' title="' + (self.previewZoomButtonTitles[type] || '') + '" ', tag = $h.isBs(5) ? 'bs-' : '', + params = title + (type === 'close' ? ' data-' + tag + 'dismiss="modal" aria-hidden="true"' : ''); + if (type === 'fullscreen' || type === 'borderless' || type === 'toggleheader') { + params += ' data-toggle="button" aria-pressed="false" autocomplete="off"'; + } + return ''; + }, + _getModalContent: function () { + var self = this; + return self._getLayoutTemplate('modal').setTokens({ + 'rtl': self.rtl ? ' kv-rtl' : '', + 'zoomFrameClass': self.frameClass, + 'prev': self._getZoomButton('prev'), + 'next': self._getZoomButton('next'), + 'toggleheader': self._getZoomButton('toggleheader'), + 'fullscreen': self._getZoomButton('fullscreen'), + 'borderless': self._getZoomButton('borderless'), + 'close': self._getZoomButton('close') + }); + }, + _listenModalEvent: function (event) { + var self = this, $modal = self.$modal, getParams = function (e) { + return { + sourceEvent: e, + previewId: $modal.data('previewId'), + modal: $modal + }; + }; + $modal.on(event + '.bs.modal', function (e) { + if (e.namespace !== 'bs.modal') { + return; + } + var $btnFull = $modal.find('.btn-fullscreen'), $btnBord = $modal.find('.btn-borderless'); + if ($modal.data('fileinputPluginId') === self.$element.attr('id')) { + self._raise('filezoom' + event, getParams(e)); + } + if (event === 'shown') { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + if ($modal.hasClass('file-zoom-fullscreen')) { + self._maximizeZoomDialog(); + if ($h.checkFullScreen()) { + $btnFull.addClass('active').attr('aria-pressed', 'true'); + } else { + $btnBord.addClass('active').attr('aria-pressed', 'true'); + } + } + } + }); + }, + _initZoom: function () { + var self = this, $dialog, modalMain = self._getLayoutTemplate('modalMain'), modalId = '#' + $h.MODAL_ID; + modalMain = self._setTabIndex('modal', modalMain); + if (!self.showPreview) { + return; + } + self.$modal = $(modalId); + if (!self.$modal || !self.$modal.length) { + $dialog = $h.createElement($h.cspBuffer.stash(modalMain)).insertAfter(self.$container); + self.$modal = $(modalId).insertBefore($dialog); + $h.cspBuffer.apply(self.$modal); + $dialog.remove(); + } + $h.initModal(self.$modal); + self.$modal.html($h.cspBuffer.stash(self._getModalContent())); + $h.cspBuffer.apply(self.$modal); + $.each($h.MODAL_EVENTS, function (key, event) { + self._listenModalEvent(event); + }); + }, + _initZoomButtons: function () { + var self = this, previewId = self.$modal.data('previewId') || '', $first, $last, + thumbs = self.getFrames().toArray(), len = thumbs.length, $prev = self.$modal.find('.btn-kv-prev'), + $next = self.$modal.find('.btn-kv-next'); + if (thumbs.length < 2) { + $prev.hide(); + $next.hide(); + return; + } else { + $prev.show(); + $next.show(); + } + if (!len) { + return; + } + $first = $(thumbs[0]); + $last = $(thumbs[len - 1]); + $prev.removeAttr('disabled'); + $next.removeAttr('disabled'); + if (self.reversePreviewOrder) { + [$prev, $next] = [$next, $prev]; // swap + } + if ($first.length && $first.attr('id') === previewId) { + $prev.attr('disabled', true); + } + if ($last.length && $last.attr('id') === previewId) { + $next.attr('disabled', true); + } + }, + _maximizeZoomDialog: function () { + var self = this, $modal = self.$modal, $head = $modal.find('.modal-header:visible'), + $foot = $modal.find('.modal-footer:visible'), $body = $modal.find('.kv-zoom-body'), + h = $(window).height(), diff = 0; + $modal.addClass('file-zoom-fullscreen'); + if ($head && $head.length) { + h -= $head.outerHeight(true); + } + if ($foot && $foot.length) { + h -= $foot.outerHeight(true); + } + if ($body && $body.length) { + diff = $body.outerHeight(true) - $body.height(); + h -= diff; + } + $modal.find('.kv-zoom-body').height(h); + }, + _resizeZoomDialog: function (fullScreen) { + var self = this, $modal = self.$modal, $btnFull = $modal.find('.btn-kv-fullscreen'), + $btnBord = $modal.find('.btn-kv-borderless'); + if ($modal.hasClass('file-zoom-fullscreen')) { + $h.toggleFullScreen(false); + if (!fullScreen) { + if (!$btnFull.hasClass('active')) { + $modal.removeClass('file-zoom-fullscreen'); + self.$modal.find('.kv-zoom-body').css('height', self.zoomModalHeight); + } else { + $btnFull.removeClass('active').attr('aria-pressed', 'false'); + } + } else { + if (!$btnFull.hasClass('active')) { + $modal.removeClass('file-zoom-fullscreen'); + self._resizeZoomDialog(true); + if ($btnBord.hasClass('active')) { + $btnBord.removeClass('active').attr('aria-pressed', 'false'); + } + } + } + } else { + if (!fullScreen) { + self._maximizeZoomDialog(); + return; + } + $h.toggleFullScreen(true); + } + $modal.focus(); + }, + _setZoomContent: function ($frame, navigate) { + var self = this, $content, tmplt, body, title, $body, $dataEl, config, previewId = $frame.attr('id'), + $zoomPreview = self._getZoom(previewId), $modal = self.$modal, $tmp, desc, $desc, + $btnFull = $modal.find('.btn-kv-fullscreen'), $btnBord = $modal.find('.btn-kv-borderless'), cap, size, + $btnTogh = $modal.find('.btn-kv-toggleheader'), dir = navigate === 'prev' ? 'Left' : 'Right', + slideIn = 'slideIn' + dir, slideOut = 'slideOut' + dir, parsed, zoomData = $frame.data('zoom'); + if (zoomData) { + zoomData = decodeURIComponent(zoomData); + parsed = $zoomPreview.html().replace($h.ZOOM_VAR, '').setTokens({zoomData: zoomData}); + $zoomPreview.html(parsed); + $frame.data('zoom', ''); + $zoomPreview.attr('data-zoom', zoomData); + } + tmplt = $zoomPreview.attr('data-template') || 'generic'; + $content = $zoomPreview.find('.kv-file-content'); + body = $content.length ? '\n' + $content.html() : ''; + cap = $frame.data('caption') || self.msgZoomModalHeading; + size = $frame.data('size') || ''; + desc = $frame.data('description') || ''; + $modal.find('.kv-zoom-caption').attr('title', cap).html(cap); + $modal.find('.kv-zoom-size').html(size); + $desc = $modal.find('.kv-zoom-description').hide(); + if (desc) { + if (self.showDescriptionClose) { + desc = self._getLayoutTemplate('descriptionClose').setTokens({ + closeIcon: self.previewZoomButtonIcons.close + }) + '' + desc; + } + $desc.show().html(desc); + if (self.showDescriptionClose) { + self._handler($modal.find('.kv-desc-hide'), 'click', function () { + $(this).parent().fadeOut('fast', function () { + $modal.focus(); + }); + }); + } + } + $body = $modal.find('.kv-zoom-body'); + $modal.removeClass('kv-single-content'); + if (navigate) { + $tmp = $body.addClass('file-thumb-loading').clone().insertAfter($body); + $h.setHtml($body, body).hide(); + $tmp.fadeOut('fast', function () { + $body.fadeIn('fast', function () { + $body.removeClass('file-thumb-loading'); + }); + $tmp.remove(); + }); + } else { + $h.setHtml($body, body); + } + config = self.previewZoomSettings[tmplt]; + if (config) { + $dataEl = $body.find('.kv-preview-data'); + $h.addCss($dataEl, 'file-zoom-detail'); + $.each(config, function (key, value) { + $dataEl.css(key, value); + if (($dataEl.attr('width') && key === 'width') || ($dataEl.attr('height') && key === 'height')) { + $dataEl.removeAttr(key); + } + }); + } + $modal.data('previewId', previewId); + self._handler($modal.find('.btn-kv-prev'), 'click', function () { + self._zoomSlideShow('prev', previewId); + }); + self._handler($modal.find('.btn-kv-next'), 'click', function () { + self._zoomSlideShow('next', previewId); + }); + self._handler($btnFull, 'click', function () { + self._resizeZoomDialog(true); + }); + self._handler($btnBord, 'click', function () { + self._resizeZoomDialog(false); + }); + self._handler($btnTogh, 'click', function () { + var $header = $modal.find('.modal-header'), $floatBar = $modal.find('.floating-buttons'), + ht, $actions = $header.find('.kv-zoom-actions'), resize = function (height) { + var $body = self.$modal.find('.kv-zoom-body'), h = self.zoomModalHeight; + if ($modal.hasClass('file-zoom-fullscreen')) { + h = $body.outerHeight(true); + if (!height) { + h = h - $header.outerHeight(true); + } + } + $body.css('height', height ? h + height : h); + }; + if ($header.is(':visible')) { + ht = $header.outerHeight(true); + $header.slideUp('slow', function () { + $actions.find('.btn').appendTo($floatBar); + resize(ht); + }); + } else { + $floatBar.find('.btn').appendTo($actions); + $header.slideDown('slow', function () { + resize(); + }); + } + $modal.focus(); + }); + self._handler($modal, 'keydown', function (e) { + var key = e.which || e.keyCode, delay = self.processDelay + 1, $prev = $(this).find('.btn-kv-prev'), + $next = $(this).find('.btn-kv-next'), vId = $(this).data('previewId'), vPrevKey, vNextKey; + [vPrevKey, vNextKey] = self.rtl ? [39, 37] : [37, 39]; + $.each({prev: [$prev, vPrevKey], next: [$next, vNextKey]}, function (direction, config) { + var $btn = config[0], vKey = config[1]; + if (key === vKey && $btn.length) { + $modal.focus(); + if (!$btn.attr('disabled')) { + $btn.focus(); + self._zoomSlideShow(direction, vId); + setTimeout(function () { + if ($btn.attr('disabled')) { + $modal.focus(); + } + }, delay); + } + } + }); + }); + }, + _showModal: function ($frame) { + var self = this, $modal = self.$modal, bs5Modal; + if (!$frame || !$frame.length) { + return; + } + $h.initModal($modal); + $h.setHtml($modal, self._getModalContent()); + self._setZoomContent($frame); + $modal.data({backdrop: false}); + //$modal.data('fileinputPluginId', self.$element.attr('id')); + $modal.modal('show'); + self._initZoomButtons(); + }, + _zoomPreview: function ($btn) { + var self = this, $frame; + if (!$btn.length) { + throw 'Cannot zoom to detailed preview!'; + } + $frame = $btn.closest($h.FRAMES); + self._showModal($frame); + }, + _zoomSlideShow: function (dir, previewId) { + var self = this, $btn = self.$modal.find('.kv-zoom-actions .btn-kv-' + dir), $targFrame, i, $thumb, + thumbsData = self.getFrames().toArray(), thumbs = [], len = thumbsData.length, out; + if (self.reversePreviewOrder) { + dir = dir === 'prev' ? 'next' : 'prev'; + } + if ($btn.attr('disabled')) { + return; + } + for (i = 0; i < len; i++) { + $thumb = $(thumbsData[i]); + if ($thumb && $thumb.length && $thumb.find('.kv-file-zoom:visible').length) { + thumbs.push(thumbsData[i]); + } + } + len = thumbs.length; + for (i = 0; i < len; i++) { + if ($(thumbs[i]).attr('id') === previewId) { + out = dir === 'prev' ? i - 1 : i + 1; + break; + } + } + if (out < 0 || out >= len || !thumbs[out]) { + return; + } + $targFrame = $(thumbs[out]); + if ($targFrame.length) { + self._setZoomContent($targFrame, dir); + } + self._initZoomButtons(); + self._raise('filezoom' + dir, {'previewId': previewId, modal: self.$modal}); + }, + _initZoomButton: function () { + var self = this; + self.$preview.find('.kv-file-zoom').each(function () { + var $el = $(this); + self._handler($el, 'click', function () { + self._zoomPreview($el); + }); + }); + }, + _inputFileCount: function () { + return this.$element[0].files.length; + }, + _refreshPreview: function () { + var self = this, files; + if ((!self._inputFileCount() && !self.isAjaxUpload) || !self.showPreview || !self.isPreviewable) { + return; + } + if (self.isAjaxUpload) { + if (self.fileManager.count() > 0) { + files = $.extend(true, {}, self.getFileList()); + self.fileManager.clear(); + self._clearFileInput(); + } else { + files = self.$element[0].files; + } + } else { + files = self.$element[0].files; + } + if (files && files.length) { + self.readFiles(files); + self._setFileDropZoneTitle(); + } + }, + _clearObjects: function ($el) { + $el.find('video audio').each(function () { + this.pause(); + $(this).remove(); + }); + $el.find('img object div').each(function () { + $(this).remove(); + }); + }, + _clearFileInput: function () { + var self = this, $el = self.$element, $srcFrm, $tmpFrm, $tmpEl; + if (!self._inputFileCount()) { + return; + } + $srcFrm = $el.closest('form'); + $tmpFrm = $(document.createElement('form')); + $tmpEl = $(document.createElement('div')); + $el.before($tmpEl); + if ($srcFrm.length) { + $srcFrm.after($tmpFrm); + } else { + $tmpEl.after($tmpFrm); + } + $tmpFrm.append($el).trigger('reset'); + $tmpEl.before($el).remove(); + $tmpFrm.remove(); + }, + _resetUpload: function () { + var self = this; + self.uploadStartTime = $h.now(); + self.uploadCache = []; + self.$btnUpload.removeAttr('disabled'); + self._setProgress(0); + self._hideProgress(); + self._resetErrors(false); + self._initAjax(); + self.fileManager.clearImages(); + self._resetCanvas(); + if (self.overwriteInitial) { + self.initialPreview = []; + self.initialPreviewConfig = []; + self.initialPreviewThumbTags = []; + self.previewCache.data = { + content: [], + config: [], + tags: [] + }; + } + }, + _resetCanvas: function () { + var self = this; + if (self.imageCanvas && self.imageCanvasContext) { + self.imageCanvasContext.clearRect(0, 0, self.imageCanvas.width, self.imageCanvas.height); + } + }, + _hasInitialPreview: function () { + var self = this; + return !self.overwriteInitial && self.previewCache.count(true); + }, + _resetPreview: function () { + var self = this, out, cap, $div, hasSuc = self.showUploadedThumbs, hasErr = !self.removeFromPreviewOnError, + includeProcessed = (hasSuc || hasErr) && self.isDuplicateError; + if (self.previewCache.count(true)) { + out = self.previewCache.out(); + if (includeProcessed) { + $div = $h.createElement('').insertAfter(self.$container); + self.getFrames().each(function () { + var $thumb = $(this); + if ((hasSuc && $thumb.hasClass('file-preview-success')) || + (hasErr && $thumb.hasClass('file-preview-error'))) { + $div.append($thumb); + } + }); + } + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + cap = self.initialCaption ? self.initialCaption : out.caption; + self._setCaption(cap); + if (includeProcessed) { + $div.contents().appendTo(self.$preview); + $div.remove(); + } + } else { + self._clearPreview(); + self._initCaption(); + } + if (self.showPreview) { + self._initZoom(); + self._initSortable(); + } + self.isDuplicateError = false; + }, + _clearDefaultPreview: function () { + var self = this; + self.$preview.find('.file-default-preview').remove(); + }, + _validateDefaultPreview: function () { + var self = this; + if (!self.showPreview || $h.isEmpty(self.defaultPreviewContent)) { + return; + } + self._setPreviewContent('
    ' + self.defaultPreviewContent + '
    '); + self.$container.removeClass('file-input-new'); + self._initClickable(); + }, + _resetPreviewThumbs: function (isAjax) { + var self = this, out; + if (isAjax) { + self._clearPreview(); + self.clearFileStack(); + return; + } + if (self._hasInitialPreview()) { + out = self.previewCache.out(); + self._setPreviewContent(out.content); + self._setInitThumbAttr(); + self._setCaption(out.caption); + self._initPreviewActions(); + } else { + self._clearPreview(); + } + }, + _getLayoutTemplate: function (t) { + var self = this, template = self.layoutTemplates[t]; + if ($h.isEmpty(self.customLayoutTags)) { + return template; + } + return $h.replaceTags(template, self.customLayoutTags); + }, + _getPreviewTemplate: function (t) { + var self = this, templates = self.previewTemplates, template = templates[t] || templates.other; + if ($h.isEmpty(self.customPreviewTags)) { + return template; + } + return $h.replaceTags(template, self.customPreviewTags); + }, + _getOutData: function (formdata, jqXHR, responseData, filesData) { + var self = this; + jqXHR = jqXHR || {}; + responseData = responseData || {}; + filesData = filesData || self.fileManager.list(); + return { + formdata: formdata, + files: filesData, + filenames: self.filenames, + filescount: self.getFilesCount(), + extra: self._getExtraData(), + response: responseData, + reader: self.reader, + jqXHR: jqXHR + }; + }, + _getMsgSelected: function (n, processing) { + var self = this, strFiles = n === 1 ? self.fileSingle : self.filePlural; + return n > 0 ? self.msgSelected.replace('{n}', n).replace('{files}', strFiles) : + (processing ? self.msgProcessing : self.msgNoFilesSelected); + }, + _getFrame: function (id, skipWarning) { + var self = this, $frame = $h.getFrameElement(self.$preview, id); + if (self.showPreview && !skipWarning && !$frame.length) { + self._log($h.logMessages.invalidThumb, {id: id}); + } + return $frame; + }, + _getZoom: function (id, selector) { + var self = this, $frame = $h.getZoomElement(self.$preview, id, selector); + if (self.showPreview && !$frame.length) { + self._log($h.logMessages.invalidThumb, {id: id}); + } + return $frame; + }, + _getThumbs: function (css) { + css = css || ''; + return this.getFrames(':not(.file-preview-initial)' + css); + }, + _getThumbId: function (fileId) { + var self = this; + return self.previewInitId + '-' + fileId; + }, + _getExtraData: function (fileId, index) { + var self = this, data = self.uploadExtraData; + if (typeof self.uploadExtraData === 'function') { + data = self.uploadExtraData(fileId, index); + } + return data; + }, + _initXhr: function (xhrobj, fileId) { + var self = this, fm = self.fileManager, func = function (event) { + var pct = 0, total = event.total, loaded = event.loaded || event.position, + stats = fm.getUploadStats(fileId, loaded, total); + /** @namespace event.lengthComputable */ + if (event.lengthComputable && !self.enableResumableUpload) { + pct = $h.round(loaded / total * 100); + } + if (fileId) { + self._setFileUploadStats(fileId, pct, stats); + } else { + self._setProgress(pct, null, null, self._getStats(stats)); + } + self._raise('fileajaxprogress', [stats]); + }; + if (xhrobj.upload) { + if (self.progressDelay) { + func = $h.debounce(func, self.progressDelay); + } + xhrobj.upload.addEventListener('progress', func, false); + } + return xhrobj; + }, + _initAjaxSettings: function () { + var self = this; + self._ajaxSettings = $.extend(true, {}, self.ajaxSettings); + self._ajaxDeleteSettings = $.extend(true, {}, self.ajaxDeleteSettings); + }, + _mergeAjaxCallback: function (funcName, srcFunc, type) { + var self = this, settings = self._ajaxSettings, flag = self.mergeAjaxCallbacks, targFunc; + if (type === 'delete') { + settings = self._ajaxDeleteSettings; + flag = self.mergeAjaxDeleteCallbacks; + } + targFunc = settings[funcName]; + if (flag && typeof targFunc === 'function') { + if (flag === 'before') { + settings[funcName] = function () { + targFunc.apply(this, arguments); + srcFunc.apply(this, arguments); + }; + } else { + settings[funcName] = function () { + srcFunc.apply(this, arguments); + targFunc.apply(this, arguments); + }; + } + } else { + settings[funcName] = srcFunc; + } + }, + _ajaxSubmit: function (fnBefore, fnSuccess, fnComplete, fnError, formdata, fileId, index, vUrl) { + var self = this, settings, defaults, data, ajaxTask; + if (!self._raise('filepreajax', [formdata, fileId, index])) { + return; + } + formdata.append('initialPreview', JSON.stringify(self.initialPreview)); + formdata.append('initialPreviewConfig', JSON.stringify(self.initialPreviewConfig)); + formdata.append('initialPreviewThumbTags', JSON.stringify(self.initialPreviewThumbTags)); + self._initAjaxSettings(); + self._mergeAjaxCallback('beforeSend', fnBefore); + self._mergeAjaxCallback('success', fnSuccess); + self._mergeAjaxCallback('complete', fnComplete); + self._mergeAjaxCallback('error', fnError); + vUrl = vUrl || self.uploadUrlThumb || self.uploadUrl; + if (typeof vUrl === 'function') { + vUrl = vUrl(); + } + data = self._getExtraData(fileId, index) || {}; + if (typeof data === 'object') { + $.each(data, function (key, value) { + formdata.append(key, value); + }); + } + defaults = { + xhr: function () { + var xhrobj = $.ajaxSettings.xhr(); + return self._initXhr(xhrobj, fileId); + }, + url: self._encodeURI(vUrl), + type: 'POST', + dataType: 'json', + data: formdata, + cache: false, + processData: false, + contentType: false + }; + settings = $.extend(true, {}, defaults, self._ajaxSettings); + ajaxTask = self.taskManager.addTask(fileId + '-' + index, function () { + var self = this.self, config, xhr; + config = self.ajaxQueue.shift(); + xhr = $.ajax(config); + self.ajaxRequests.push(xhr); + }); + self.ajaxQueue.push(settings); + ajaxTask.runWithContext({self: self}); + }, + _mergeArray: function (prop, content) { + var self = this, arr1 = $h.cleanArray(self[prop]), arr2 = $h.cleanArray(content); + self[prop] = arr1.concat(arr2); + }, + _initUploadSuccess: function (out, $thumb, allFiles) { + var self = this, append, data, index, $div, content, config, tags, id, i; + if (!self.showPreview || typeof out !== 'object' || $.isEmptyObject(out)) { + self._resetCaption(); + return; + } + if (out.initialPreview !== undefined && out.initialPreview.length > 0) { + self.hasInitData = true; + content = out.initialPreview || []; + config = out.initialPreviewConfig || []; + tags = out.initialPreviewThumbTags || []; + append = out.append === undefined || out.append; + if (content.length > 0 && !$h.isArray(content)) { + content = content.split(self.initialPreviewDelimiter); + } + if (content.length) { + self._mergeArray('initialPreview', content); + self._mergeArray('initialPreviewConfig', config); + self._mergeArray('initialPreviewThumbTags', tags); + } + if ($thumb !== undefined) { + if (!allFiles) { + index = self.previewCache.add(content[0], config[0], tags[0], append); + data = self.previewCache.get(index, false); + $div = $h.createElement(data).hide().appendTo($thumb); + $thumb.fadeOut('slow', function () { + var $newThumb = $div.find('> .file-preview-frame'); + if ($newThumb && $newThumb.length) { + $newThumb.insertBefore($thumb).fadeIn('slow').css('display:inline-block'); + } + self._initPreviewActions(); + self._clearFileInput(); + $thumb.remove(); + $div.remove(); + self._initSortable(); + }); + } else { + id = $thumb.attr('id'); + i = self._getUploadCacheIndex(id); + if (i !== null) { + self.uploadCache[i] = { + id: id, + content: content[0], + config: config[0] || [], + tags: tags[0] || [], + append: append + }; + } + } + } else { + self.previewCache.set(content, config, tags, append); + self._initPreview(); + self._initPreviewActions(); + } + } + self._resetCaption(); + }, + _getUploadCacheIndex: function (id) { + var self = this, i, len = self.uploadCache.length, config; + for (i = 0; i < len; i++) { + config = self.uploadCache[i]; + if (config.id === id) { + return i; + } + } + return null; + }, + _initSuccessThumbs: function () { + var self = this; + if (!self.showPreview) { + return; + } + setTimeout(function () { + self._getThumbs($h.FRAMES + '.file-preview-success').each(function () { + var $thumb = $(this), $remove = $thumb.find('.kv-file-remove'); + $remove.removeAttr('disabled'); + self._handler($remove, 'click', function () { + var id = $thumb.attr('id'), + out = self._raise('filesuccessremove', [id, $thumb.attr('data-fileindex')]); + $h.cleanMemory($thumb); + if (out === false) { + return; + } + self.$caption.attr('title', ''); + $thumb.fadeOut('slow', function () { + var fm = self.fileManager; + $thumb.remove(); + if (!self.getFrames().length) { + self.reset(); + } + }); + }); + }); + }, self.processDelay); + }, + _updateInitialPreview: function () { + var self = this, u = self.uploadCache; + if (self.showPreview) { + $.each(u, function (key, setting) { + self.previewCache.add(setting.content, setting.config, setting.tags, setting.append); + }); + if (self.hasInitData) { + self._initPreview(); + self._initPreviewActions(); + } + } + }, + _getThumbFileId: function ($thumb) { + var self = this; + if (self.showPreview && $thumb !== undefined) { + return $thumb.attr('data-fileid'); + } + return null; + }, + _getThumbFile: function ($thumb) { + var self = this, id = self._getThumbFileId($thumb); + return id ? self.fileManager.getFile(id) : null; + }, + _uploadSingle: function (i, id, isBatch) { + var self = this, fm = self.fileManager, count = fm.count(), formdata = new FormData(), outData, + previewId = self._getThumbId(id), $thumb, chkComplete, $btnUpload, $btnDelete, + hasPostData = count > 0 || !$.isEmptyObject(self.uploadExtraData), uploadFailed, $prog, fnBefore, + errMsg, fnSuccess, fnComplete, fnError, updateUploadLog, op = self.ajaxOperations.uploadThumb, + fileObj = fm.getFile(id), params = {id: previewId, index: i, fileId: id}, + fileName = self.fileManager.getFileName(id, true); + if (self.enableResumableUpload) { // not enabled for resumable uploads + return; + } + if (self.showPreview) { + $thumb = fm.getThumb(id); + $prog = $thumb.find('.file-thumb-progress'); + $btnUpload = $thumb.find('.kv-file-upload'); + $btnDelete = $thumb.find('.kv-file-remove'); + $prog.show(); + } + if (count === 0 || !hasPostData || (self.showPreview && $btnUpload && $btnUpload.hasClass('disabled')) || + self._abort(params)) { + return; + } + updateUploadLog = function () { + if (!uploadFailed) { + fm.removeFile(id); + } else { + fm.errors.push(id); + } + fm.setProcessed(id); + if (fm.isProcessed()) { + self.fileBatchCompleted = true; + chkComplete(); + } + }; + chkComplete = function () { + var $initThumbs; + if (!self.fileBatchCompleted) { + return; + } + setTimeout(function () { + var triggerReset = fm.count() === 0, errCount = fm.errors.length; + self._updateInitialPreview(); + self.unlock(triggerReset); + if (triggerReset) { + self._clearFileInput(); + } + $initThumbs = self.$preview.find('.file-preview-initial'); + if (self.uploadAsync && $initThumbs.length) { + $h.addCss($initThumbs, $h.SORT_CSS); + self._initSortable(); + } + self._raise('filebatchuploadcomplete', [fm.stack, self._getExtraData()]); + if (!self.retryErrorUploads || errCount === 0) { + fm.clear(); + } + self._setProgress(101); + self.ajaxAborted = false; + }, self.processDelay); + }; + fnBefore = function (jqXHR) { + outData = self._getOutData(formdata, jqXHR); + fm.initStats(id); + self.fileBatchCompleted = false; + if (!isBatch) { + self.ajaxAborted = false; + } + if (self.showPreview) { + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + } + if (!isBatch) { + self.lock(); + } + if (fm.errors.indexOf(id) !== -1) { + delete fm.errors[id]; + } + self._raise('filepreupload', [outData, previewId, i, self._getThumbFileId($thumb)]); + $.extend(true, params, outData); + if (self._abort(params)) { + jqXHR.abort(); + if (!isBatch) { + self._setThumbStatus($thumb, 'New'); + $thumb.removeClass('file-uploading'); + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + } + self._setProgressCancelled(); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + var pid = self.showPreview && $thumb.attr('id') ? $thumb.attr('id') : previewId; + outData = self._getOutData(formdata, jqXHR, data); + $.extend(true, params, outData); + setTimeout(function () { + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + if (self.showPreview) { + self._setThumbStatus($thumb, 'Success'); + $btnUpload.hide(); + self._initUploadSuccess(data, $thumb, isBatch); + self._setProgress(101, $prog); + } + self._raise('fileuploaded', [outData, pid, i, self._getThumbFileId($thumb)]); + if (!isBatch) { + self.fileManager.remove($thumb); + } else { + updateUploadLog(); + } + } else { + uploadFailed = true; + errMsg = self._parseError(op, jqXHR, self.msgUploadError, self.fileManager.getFileName(id)); + self._showFileError(errMsg, params); + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $btnUpload.hide(); + } + if (isBatch) { + updateUploadLog(); + } + self._setProgress(101, self._getFrame(pid).find('.file-thumb-progress'), + self.msgUploadError); + } + }, self.processDelay); + }; + fnComplete = function () { + if (self.showPreview) { + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + $thumb.removeClass('file-uploading'); + } + if (!isBatch) { + self.unlock(false); + self._clearFileInput(); + } else { + chkComplete(); + } + self._initSuccessThumbs(); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + errMsg = self._parseError(op, jqXHR, errorThrown, self.fileManager.getFileName(id)); + uploadFailed = true; + setTimeout(function () { + var $prog; + if (isBatch) { + updateUploadLog(); + } + self.fileManager.setProgress(id, 100); + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $btnUpload.hide(); + } + $.extend(true, params, self._getOutData(formdata, jqXHR)); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + $prog = self.showPreview && $thumb ? $thumb.find('.file-thumb-progress') : ''; + self._setProgress(101, $prog, self.msgUploadError); + self._showFileError(errMsg, params); + }, self.processDelay); + }; + self._setFileData(formdata, fileObj.file, fileName, id); + self._setUploadData(formdata, {fileId: id}); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata, id, i); + }, + _setFileData: function (formdata, file, fileName, fileId) { + var self = this, preProcess = self.preProcessUpload; + if (preProcess && typeof preProcess === 'function') { + formdata.append(self.uploadFileAttr, preProcess(fileId, file)); + } else { + formdata.append(self.uploadFileAttr, file, fileName); + } + }, + _checkBatchPreupload: function (outData, jqXHR) { + var self = this, out = self._raise('filebatchpreupload', [outData]); + if (out) { + return true; + } + self._abort(outData); + if (jqXHR) { + jqXHR.abort(); + } + self._getThumbs().each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), + $btnDelete = $thumb.find('.kv-file-remove'); + if ($thumb.hasClass('file-preview-loading')) { + self._setThumbStatus($thumb, 'New'); + $thumb.removeClass('file-uploading'); + } + $btnUpload.removeAttr('disabled'); + $btnDelete.removeAttr('disabled'); + }); + self._setProgressCancelled(); + return false; + }, + _uploadBatch: function () { + var self = this, fm = self.fileManager, total = fm.total(), params = {}, fnBefore, fnSuccess, fnError, + fnComplete, hasPostData = total > 0 || !$.isEmptyObject(self.uploadExtraData), errMsg, + setAllUploaded, formdata = new FormData(), op = self.ajaxOperations.uploadBatch; + if (total === 0 || !hasPostData || self._abort(params)) { + return; + } + setAllUploaded = function () { + self.fileManager.clear(); + self._clearFileInput(); + }; + fnBefore = function (jqXHR) { + self.lock(); + fm.initStats(); + var outData = self._getOutData(formdata, jqXHR); + self.ajaxAborted = false; + if (self.showPreview) { + self._getThumbs().each(function () { + var $thumb = $(this), $btnUpload = $thumb.find('.kv-file-upload'), + $btnDelete = $thumb.find('.kv-file-remove'); + if (!$thumb.hasClass('file-preview-success')) { + self._setThumbStatus($thumb, 'Loading'); + $h.addCss($thumb, 'file-uploading'); + } + $btnUpload.attr('disabled', true); + $btnDelete.attr('disabled', true); + }); + } + self._checkBatchPreupload(outData, jqXHR); + }; + fnSuccess = function (data, textStatus, jqXHR) { + /** @namespace data.errorkeys */ + var outData = self._getOutData(formdata, jqXHR, data), key = 0, + $thumbs = self._getThumbs(':not(.file-preview-success)'), + keys = $h.isEmpty(data) || $h.isEmpty(data.errorkeys) ? [] : data.errorkeys; + + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + setAllUploaded(); + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this); + self._setThumbStatus($thumb, 'Success'); + $thumb.removeClass('file-uploading'); + $thumb.find('.kv-file-upload').hide().removeAttr('disabled'); + }); + self._initUploadSuccess(data); + } else { + self.reset(); + } + self._setProgress(101); + } else { + if (self.showPreview) { + $thumbs.each(function () { + var $thumb = $(this); + $thumb.removeClass('file-uploading'); + $thumb.find('.kv-file-upload').removeAttr('disabled'); + $thumb.find('.kv-file-remove').removeAttr('disabled'); + if (keys.length === 0 || $.inArray(key, keys) !== -1) { + self._setPreviewError($thumb, true); + if (!self.retryErrorUploads) { + $thumb.find('.kv-file-upload').hide(); + self.fileManager.remove($thumb); + } + } else { + $thumb.find('.kv-file-upload').hide(); + self._setThumbStatus($thumb, 'Success'); + self.fileManager.remove($thumb); + } + if (!$thumb.hasClass('file-preview-error') || self.retryErrorUploads) { + key++; + } + }); + self._initUploadSuccess(data); + } + errMsg = self._parseError(op, jqXHR, self.msgUploadError); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self._setProgress(101, self.$progress, self.msgUploadError); + } + }; + fnComplete = function () { + self.unlock(); + self._initSuccessThumbs(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.fileManager.stack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(formdata, jqXHR); + errMsg = self._parseError(op, jqXHR, errorThrown); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self.uploadFileCount = total - 1; + if (!self.showPreview) { + return; + } + self._getThumbs().each(function () { + var $thumb = $(this); + $thumb.removeClass('file-uploading'); + if (self._getThumbFile($thumb)) { + self._setPreviewError($thumb); + } + }); + self._getThumbs().removeClass('file-uploading'); + self._getThumbs(' .kv-file-upload').removeAttr('disabled'); + self._getThumbs(' .kv-file-delete').removeAttr('disabled'); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + }; + var ctr = 0; + $.each(self.fileManager.stack, function (key, data) { + if (!$h.isEmpty(data.file)) { + self._setFileData(formdata, data.file, (data.nameFmt || ('untitled_' + ctr)), key); + } + ctr++; + }); + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata); + }, + _uploadExtraOnly: function () { + var self = this, params = {}, fnBefore, fnSuccess, fnComplete, fnError, formdata = new FormData(), errMsg, + op = self.ajaxOperations.uploadExtra; + fnBefore = function (jqXHR) { + self.lock(); + var outData = self._getOutData(formdata, jqXHR); + self._setProgress(50); + params.data = outData; + params.xhr = jqXHR; + self._checkBatchPreupload(outData, jqXHR); + }; + fnSuccess = function (data, textStatus, jqXHR) { + var outData = self._getOutData(formdata, jqXHR, data); + if ($h.isEmpty(data) || $h.isEmpty(data.error)) { + self._raise('filebatchuploadsuccess', [outData]); + self._clearFileInput(); + self._initUploadSuccess(data); + self._setProgress(101); + } else { + errMsg = self._parseError(op, jqXHR, self.msgUploadError); + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + } + }; + fnComplete = function () { + self.unlock(); + self._clearFileInput(); + self._raise('filebatchuploadcomplete', [self.fileManager.stack, self._getExtraData()]); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var outData = self._getOutData(formdata, jqXHR); + errMsg = self._parseError(op, jqXHR, errorThrown); + params.data = outData; + self._showFileError(errMsg, outData, 'filebatchuploaderror'); + self._setProgress(101, self.$progress, self.msgAjaxProgressError.replace('{operation}', op)); + }; + self._ajaxSubmit(fnBefore, fnSuccess, fnComplete, fnError, formdata); + }, + _deleteFileIndex: function ($frame) { + var self = this, ind = $frame.attr('data-fileindex'), rev = self.reversePreviewOrder; + if (ind.substring(0, 5) === $h.INIT_FLAG) { + ind = parseInt(ind.replace($h.INIT_FLAG, '')); + self.initialPreview = $h.spliceArray(self.initialPreview, ind, rev); + self.initialPreviewConfig = $h.spliceArray(self.initialPreviewConfig, ind, rev); + self.initialPreviewThumbTags = $h.spliceArray(self.initialPreviewThumbTags, ind, rev); + self.getFrames().each(function () { + var $nFrame = $(this), nInd = $nFrame.attr('data-fileindex'); + if (nInd.substring(0, 5) === $h.INIT_FLAG) { + nInd = parseInt(nInd.replace($h.INIT_FLAG, '')); + if (nInd > ind) { + nInd--; + $nFrame.attr('data-fileindex', $h.INIT_FLAG + nInd); + } + } + }); + } + }, + _resetCaption: function () { + var self = this; + setTimeout(function () { + var cap = '', n, chk = self.previewCache.count(true), len = self.fileManager.count(), file, + incomplete = ':not(.file-preview-success):not(.file-preview-error)', cfg, + hasThumb = self.showPreview && self.getFrames(incomplete).length; + if (len === 0 && chk === 0 && !hasThumb) { + self.reset(); + } else { + n = chk + len; + if (n > 1) { + cap = self._getMsgSelected(n); + } else { + if (len === 0) { + cfg = self.initialPreviewConfig[0]; + cap = ''; + if (cfg) { + cap = cfg.caption || cfg.filename || '' + } + if (!cap) { + cap = self._getMsgSelected(n); + } + } else { + file = self.fileManager.getFirstFile(); + cap = file ? file.nameFmt : '_'; + } + } + self._setCaption(cap); + } + }, self.processDelay); + }, + _initFileActions: function () { + var self = this; + if (!self.showPreview) { + return; + } + self._initZoomButton(); + self.getFrames(' .kv-file-remove').each(function () { + var $el = $(this), $frame = $el.closest($h.FRAMES), hasError, id = $frame.attr('id'), + ind = $frame.attr('data-fileindex'), status, fm = self.fileManager; + self._handler($el, 'click', function () { + status = self._raise('filepreremove', [id, ind]); + if (status === false || !self._validateMinCount()) { + return false; + } + hasError = $frame.hasClass('file-preview-error'); + $h.cleanMemory($frame); + $frame.fadeOut('slow', function () { + self.fileManager.remove($frame); + self._clearObjects($frame); + $frame.remove(); + if (id && hasError) { + self.$errorContainer.find('li[data-thumb-id="' + id + '"]').fadeOut('fast', function () { + $(this).remove(); + if (!self._errorsExist()) { + self._resetErrors(); + } + }); + } + self._clearFileInput(); + self._resetCaption(); + self._raise('fileremoved', [id, ind]); + }); + }); + }); + self.getFrames(' .kv-file-upload').each(function () { + var $el = $(this); + self._handler($el, 'click', function () { + var $frame = $el.closest($h.FRAMES), fileId = self._getThumbFileId($frame); + self._hideProgress(); + if ($frame.hasClass('file-preview-error') && !self.retryErrorUploads) { + return; + } + self._uploadSingle(self.fileManager.getIndex(fileId), fileId, false); + }); + }); + }, + _initPreviewActions: function () { + var self = this, $preview = self.$preview, deleteExtraData = self.deleteExtraData || {}, + btnRemove = $h.FRAMES + ' .kv-file-remove', settings = self.fileActionSettings, + origClass = settings.removeClass, errClass = settings.removeErrorClass, + resetProgress = function () { + var hasFiles = self.isAjaxUpload ? self.previewCache.count(true) : self._inputFileCount(); + if (!self.getFrames().length && !hasFiles) { + self._setCaption(''); + self.reset(); + self.initialCaption = ''; + } else { + self._resetCaption(); + } + }; + self._initZoomButton(); + $preview.find(btnRemove).each(function () { + var $el = $(this), vUrl = $el.data('url') || self.deleteUrl, vKey = $el.data('key'), errMsg, fnBefore, + fnSuccess, fnError, op = self.ajaxOperations.deleteThumb; + if ($h.isEmpty(vUrl) || vKey === undefined) { + return; + } + if (typeof vUrl === 'function') { + vUrl = vUrl(); + } + var $frame = $el.closest($h.FRAMES), cache = self.previewCache.data, settings, params, config, + fileName, extraData, index = $frame.attr('data-fileindex'); + index = parseInt(index.replace($h.INIT_FLAG, '')); + config = $h.isEmpty(cache.config) && $h.isEmpty(cache.config[index]) ? null : cache.config[index]; + extraData = $h.isEmpty(config) || $h.isEmpty(config.extra) ? deleteExtraData : config.extra; + fileName = config && (config.filename || config.caption) || ''; + if (typeof extraData === 'function') { + extraData = extraData(); + } + params = {id: $el.attr('id'), key: vKey, extra: extraData}; + fnBefore = function (jqXHR) { + self.ajaxAborted = false; + self._raise('filepredelete', [vKey, jqXHR, extraData]); + if (self._abort()) { + jqXHR.abort(); + } else { + $el.removeClass(errClass); + $h.addCss($frame, 'file-uploading'); + $h.addCss($el, 'disabled ' + origClass); + } + }; + fnSuccess = function (data, textStatus, jqXHR) { + var n, cap; + if (!$h.isEmpty(data) && !$h.isEmpty(data.error)) { + params.jqXHR = jqXHR; + params.response = data; + errMsg = self._parseError(op, jqXHR, self.msgDeleteError, fileName); + self._showFileError(errMsg, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + $el.removeClass('disabled ' + origClass).addClass(errClass); + resetProgress(); + return; + } + $frame.removeClass('file-uploading').addClass('file-deleted'); + $frame.fadeOut('slow', function () { + index = parseInt(($frame.attr('data-fileindex')).replace($h.INIT_FLAG, '')); + self.previewCache.unset(index); + self._deleteFileIndex($frame); + n = self.previewCache.count(true); + cap = n > 0 ? self._getMsgSelected(n) : ''; + self._setCaption(cap); + self._raise('filedeleted', [vKey, jqXHR, extraData]); + self._clearObjects($frame); + $frame.remove(); + resetProgress(); + }); + }; + fnError = function (jqXHR, textStatus, errorThrown) { + var errMsg = self._parseError(op, jqXHR, errorThrown, fileName); + params.jqXHR = jqXHR; + params.response = {}; + self._showFileError(errMsg, params, 'filedeleteerror'); + $frame.removeClass('file-uploading'); + $el.removeClass('disabled ' + origClass).addClass(errClass); + resetProgress(); + }; + self._initAjaxSettings(); + self._mergeAjaxCallback('beforeSend', fnBefore, 'delete'); + self._mergeAjaxCallback('success', fnSuccess, 'delete'); + self._mergeAjaxCallback('error', fnError, 'delete'); + settings = $.extend(true, {}, { + url: self._encodeURI(vUrl), + type: 'POST', + dataType: 'json', + data: $.extend(true, {}, {key: vKey}, extraData) + }, self._ajaxDeleteSettings); + self._handler($el, 'click', function () { + if (!self._validateMinCount()) { + return false; + } + self.ajaxAborted = false; + self._raise('filebeforedelete', [vKey, extraData]); + if (self.ajaxAborted instanceof Promise) { + self.ajaxAborted.then(function (result) { + if (!result) { + $.ajax(settings); + } + }); + } else { + if (!self.ajaxAborted) { + $.ajax(settings); + } + } + }); + }); + }, + _hideFileIcon: function () { + var self = this; + if (self.overwriteInitial) { + self.$captionContainer.removeClass('icon-visible'); + } + }, + _showFileIcon: function () { + var self = this; + $h.addCss(self.$captionContainer, 'icon-visible'); + }, + _getSize: function (bytes, sizes) { + var self = this, size = parseFloat(bytes), i, func = self.fileSizeGetter, out; + if (!$.isNumeric(bytes) || !$.isNumeric(size)) { + return ''; + } + if (typeof func === 'function') { + out = func(size); + } else { + if (size === 0) { + out = '0.00 B'; + } else { + if (!sizes) { + sizes = self.sizeUnits; + } + i = Math.floor(Math.log(size) / Math.log(self.bytesToKB)); + out = (size / Math.pow(self.bytesToKB, i)).toFixed(2) + ' ' + sizes[i]; + } + } + return self._getLayoutTemplate('size').replace('{sizeText}', out); + }, + _getFileType: function (ftype) { + var self = this; + return self.mimeTypeAliases[ftype] || ftype; + }, + _generatePreviewTemplate: function ( + cat, + data, + fname, + ftype, + previewId, + fileId, + isError, + size, + frameClass, + foot, + ind, + templ, + attrs, + zoomData + ) { + var self = this, caption = self.slug(fname), prevContent, zoomContent = '', styleAttribs = '', + screenW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth, + config, title = caption, alt = caption, typeCss = 'type-default', getContent, + footer = foot || self._renderFileFooter(cat, caption, size, 'auto', isError), + forcePrevIcon = self.preferIconicPreview, forceZoomIcon = self.preferIconicZoomPreview, + newCat = forcePrevIcon ? 'other' : cat; + config = screenW < 400 ? (self.previewSettingsSmall[newCat] || self.defaults.previewSettingsSmall[newCat]) : + (self.previewSettings[newCat] || self.defaults.previewSettings[newCat]); + if (config) { + $.each(config, function (key, val) { + styleAttribs += key + ':' + val + ';'; + }); + } + getContent = function (vCat, vData, zoom, frameCss, vZoomData) { + var id = zoom ? 'zoom-' + previewId : previewId, tmplt = self._getPreviewTemplate(vCat), + css = (frameClass || '') + ' ' + frameCss, tokens; + if (self.frameClass) { + css = self.frameClass + ' ' + css; + } + if (zoom) { + css = css.replace(' ' + $h.SORT_CSS, ''); + } + tmplt = self._parseFilePreviewIcon(tmplt, fname); + if (cat === 'object' && !ftype) { + $.each(self.defaults.fileTypeSettings, function (key, func) { + if (key === 'object' || key === 'other') { + return; + } + if (func(fname, ftype)) { + typeCss = 'type-' + key; + } + }); + } + if (!$h.isEmpty(attrs)) { + if (attrs.title !== undefined && attrs.title !== null) { + title = attrs.title; + } + if (attrs.alt !== undefined && attrs.alt !== null) { + title = attrs.alt; + } + } + tokens = { + 'previewId': id, + 'caption': caption, + 'title': title, + 'alt': alt, + 'frameClass': css, + 'type': self._getFileType(ftype), + 'fileindex': ind, + 'fileid': fileId || '', + 'typeCss': typeCss, + 'footer': footer, + 'data': vData, +// 'data': zoom && vZoomData ? $h.ZOOM_VAR + '{zoomData}' : vData, + 'template': templ || cat, + 'style': styleAttribs ? 'style="' + styleAttribs + '"' : '', + 'zoomData': vZoomData ? encodeURIComponent(vZoomData) : '' + }; + if (zoom) { + tokens.zoomCache = ''; + tokens.zoomData = '{zoomData}'; + } + return tmplt.setTokens(tokens); + }; + ind = ind || previewId.slice(previewId.lastIndexOf('-') + 1); + if (self.fileActionSettings.showZoom) { + zoomContent = getContent((forceZoomIcon ? 'other' : cat), data, true, 'kv-zoom-thumb', zoomData); + } + zoomContent = '\n' + self._getLayoutTemplate('zoomCache').replace('{zoomContent}', zoomContent); + if (typeof self.sanitizeZoomCache === 'function') { + zoomContent = self.sanitizeZoomCache(zoomContent); + } + prevContent = getContent((forcePrevIcon ? 'other' : cat), data, false, 'kv-preview-thumb', zoomData); + return prevContent.setTokens({zoomCache: zoomContent}); + }, + _addToPreview: function ($preview, content) { + var self = this, $el; + content = $h.cspBuffer.stash(content); + $el = self.reversePreviewOrder ? $preview.prepend(content) : $preview.append(content); + $h.cspBuffer.apply($preview); + return $el; + }, + _previewDefault: function (file, isDisabled) { + var self = this, $preview = self.$preview; + if (!self.showPreview) { + return; + } + var fname = $h.getFileName(file), ftype = file ? file.type : '', content, size = file.size || 0, + caption = self._getFileName(file, ''), isError = isDisabled === true && !self.isAjaxUpload, + data = $h.createObjectURL(file), fileId = self.fileManager.getId(file), + previewId = self._getThumbId(fileId); + self._clearDefaultPreview(); + content = self._generatePreviewTemplate('other', data, fname, ftype, previewId, fileId, isError, size); + self._addToPreview($preview, content); + self._setThumbAttr(previewId, caption, size); + if (isDisabled === true && self.isAjaxUpload) { + self._setThumbStatus(self._getFrame(previewId), 'Error'); + } + }, + _previewFile: function (i, file, theFile, data, fileInfo) { + if (!this.showPreview) { + return; + } + var self = this, fname = $h.getFileName(file), ftype = fileInfo.type, caption = fileInfo.name, + cat = self._parseFileType(ftype, fname), content, $preview = self.$preview, fsize = file.size || 0, + iData = cat === 'image' ? theFile.target.result : data, fm = self.fileManager, + fileId = fm.getId(file), previewId = self._getThumbId(fileId); + /** @namespace window.DOMPurify */ + content = self._generatePreviewTemplate(cat, iData, fname, ftype, previewId, fileId, false, fsize); + self._clearDefaultPreview(); + self._addToPreview($preview, content); + var $thumb = self._getFrame(previewId); + self._validateImageOrientation($thumb.find('img'), file, previewId, fileId, caption, ftype, fsize, iData); + self._setThumbAttr(previewId, caption, fsize); + self._initSortable(); + }, + _setThumbAttr: function (id, caption, size, description) { + var self = this, $frame = self._getFrame(id); + if ($frame.length) { + size = size && size > 0 ? self._getSize(size) : ''; + $frame.data({'caption': caption, 'size': size, 'description': description || ''}); + } + }, + _setInitThumbAttr: function () { + var self = this, data = self.previewCache.data, len = self.previewCache.count(true), config, + caption, size, description, previewId; + if (len === 0) { + return; + } + for (var i = 0; i < len; i++) { + config = data.config[i]; + previewId = self.previewInitId + '-' + $h.INIT_FLAG + i; + caption = $h.ifSet('caption', config, $h.ifSet('filename', config)); + size = $h.ifSet('size', config); + description = $h.ifSet('description', config); + self._setThumbAttr(previewId, caption, size, description); + } + }, + _slugDefault: function (text) { + // noinspection RegExpRedundantEscape + return $h.isEmpty(text, true) ? '' : String(text).replace(/[\[\]\/\{}:;#%=\(\)\*\+\?\\\^\$\|<>&"']/g, '_'); + }, + _updateFileDetails: function (numFiles) { + var self = this, $el = self.$element, label, n, log, nFiles, file, + name = ($h.isIE(9) && $h.findFileName($el.val())) || ($el[0].files[0] && $el[0].files[0].name); + if (!name && self.fileManager.count() > 0) { + file = self.fileManager.getFirstFile(); + label = file.nameFmt; + } else { + label = name ? self.slug(name) : '_'; + } + n = self.isAjaxUpload ? self.fileManager.count() : numFiles; + nFiles = self.previewCache.count(true) + n; + log = n === 1 ? label : self._getMsgSelected(nFiles, !self.isAjaxUpload && !self.isError); + if (self.isError) { + self.$previewContainer.removeClass('file-thumb-loading'); + self._initCapStatus(); + self.$previewStatus.html(''); + self.$captionContainer.removeClass('icon-visible'); + } else { + self._showFileIcon(); + } + self._setCaption(log, self.isError); + self.$container.removeClass('file-input-new file-input-ajax-new'); + self._raise('fileselect', [numFiles, label]); + if (self.previewCache.count(true)) { + self._initPreviewActions(); + } + }, + _setThumbStatus: function ($thumb, status) { + var self = this; + if (!self.showPreview) { + return; + } + var icon = 'indicator' + status, msg = icon + 'Title', + css = 'file-preview-' + status.toLowerCase(), + $indicator = $thumb.find('.file-upload-indicator'), + config = self.fileActionSettings; + $thumb.removeClass('file-preview-success file-preview-error file-preview-paused file-preview-loading'); + if (status === 'Success') { + $thumb.find('.file-drag-handle').remove(); + } + $h.setHtml($indicator, config[icon]); + $indicator.attr('title', config[msg]); + $thumb.addClass(css); + if (status === 'Error' && !self.retryErrorUploads) { + $thumb.find('.kv-file-upload').attr('disabled', true); + } + }, + _setProgressCancelled: function () { + var self = this; + self._setProgress(101, self.$progress, self.msgCancelled); + }, + _setProgress: function (p, $el, error, stats) { + var self = this; + $el = $el || self.$progress; + if (!$el.length) { + return; + } + var pct = Math.min(p, 100), out, pctLimit = self.progressUploadThreshold, + t = p <= 100 ? self.progressTemplate : self.progressCompleteTemplate, + template = pct < 100 ? self.progressTemplate : + (error ? (self.paused ? self.progressPauseTemplate : self.progressErrorTemplate) : t); + if (p >= 100) { + stats = ''; + } + if (!$h.isEmpty(template)) { + if (pctLimit && pct > pctLimit && p <= 100) { + out = template.setTokens({'percent': pctLimit, 'status': self.msgUploadThreshold}); + } else { + out = template.setTokens({'percent': pct, 'status': (p > 100 ? self.msgUploadEnd : pct + '%')}); + } + stats = stats || ''; + out = out.setTokens({stats: stats}); + $h.setHtml($el, out); + if (error) { + $h.setHtml($el.find('[role="progressbar"]'), error); + } + } + }, + _hasFiles: function () { + var el = this.$element[0]; + return !!(el && el.files && el.files.length); + }, + _setFileDropZoneTitle: function () { + var self = this, $zone = self.$container.find('.file-drop-zone'), title = self.dropZoneTitle, strFiles; + if (self.isClickable) { + strFiles = $h.isEmpty(self.$element.attr('multiple')) ? self.fileSingle : self.filePlural; + title += self.dropZoneClickTitle.replace('{files}', strFiles); + } + $zone.find('.' + self.dropZoneTitleClass).remove(); + if (!self.showPreview || $zone.length === 0 || self.fileManager.count() > 0 || !self.dropZoneEnabled || + self.previewCache.count() > 0 || (!self.isAjaxUpload && self._hasFiles())) { + return; + } + if ($zone.find($h.FRAMES).length === 0 && $h.isEmpty(self.defaultPreviewContent)) { + $zone.prepend('
    ' + title + '
    '); + } + self.$container.removeClass('file-input-new'); + $h.addCss(self.$container, 'file-input-ajax-new'); + }, + _getStats: function (stats) { + var self = this, pendingTime, t; + if (!self.showUploadStats || !stats || !stats.bitrate) { + return ''; + } + t = self._getLayoutTemplate('stats'); + pendingTime = (!stats.elapsed || !stats.bps) ? self.msgCalculatingTime : + self.msgPendingTime.setTokens({time: $h.getElapsed(Math.ceil(stats.pendingBytes / stats.bps))}); + + return t.setTokens({ + uploadSpeed: stats.bitrate, + pendingTime: pendingTime + }); + }, + _setResumableProgress: function (pct, stats, $thumb) { + var self = this, rm = self.resumableManager, obj = $thumb ? rm : self, + $prog = $thumb ? $thumb.find('.file-thumb-progress') : null; + if (obj.lastProgress === 0) { + obj.lastProgress = pct; + } + if (pct < obj.lastProgress) { + pct = obj.lastProgress; + } + self._setProgress(pct, $prog, null, self._getStats(stats)); + obj.lastProgress = pct; + }, + _toggleResumableProgress: function (template, message) { + var self = this, $progress = self.$progress; + if ($progress && $progress.length) { + $h.setHtml($progress, template.setTokens({ + percent: 101, + status: message, + stats: '' + })); + } + }, + _setFileUploadStats: function (id, pct, stats) { + var self = this, $prog = self.$progress; + if (!self.showPreview && (!$prog || !$prog.length)) { + return; + } + var fm = self.fileManager, rm = self.resumableManager, $thumb = fm.getThumb(id), pctTot, + totUpSize = 0, totSize = fm.getTotalSize(), totStats = $.extend(true, {}, stats); + if (self.enableResumableUpload) { + var loaded = stats.loaded, currUplSize = rm.getUploadedSize(), currTotSize = rm.file.size, totLoaded; + loaded += currUplSize; + totLoaded = fm.uploadedSize + loaded; + pct = $h.round(100 * loaded / currTotSize); + stats.pendingBytes = currTotSize - currUplSize; + self._setResumableProgress(pct, stats, $thumb); + pctTot = Math.floor(100 * totLoaded / totSize); + totStats.pendingBytes = totSize - totLoaded; + self._setResumableProgress(pctTot, totStats); + } else { + fm.setProgress(id, pct); + $prog = $thumb && $thumb.length ? $thumb.find('.file-thumb-progress') : null; + self._setProgress(pct, $prog, null, self._getStats(stats)); + $.each(fm.stats, function (id, cfg) { + totUpSize += cfg.loaded; + }); + totStats.pendingBytes = totSize - totUpSize; + pctTot = $h.round(totUpSize / totSize * 100); + self._setProgress(pctTot, null, null, self._getStats(totStats)); + } + }, + _validateMinCount: function () { + var self = this, len = self.isAjaxUpload ? self.fileManager.count() : self._inputFileCount(); + if (self.validateInitialCount && self.minFileCount > 0 && self._getFileCount(len - 1) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return true; + }, + _getFileCount: function (fileCount, includeInitial) { + var self = this, addCount = 0; + if (includeInitial === undefined) { + includeInitial = self.validateInitialCount && !self.overwriteInitial; + } + if (includeInitial) { + addCount = self.previewCache.count(true); + fileCount += addCount; + } + return fileCount; + }, + _getFileId: function (file) { + return $h.getFileId(file, this.generateFileId); + }, + _getFileName: function (file, defaultValue) { + var self = this, fileName = $h.getFileName(file); + return fileName ? self.slug(fileName) : defaultValue; + }, + _getFileNames: function (skipNull) { + var self = this; + return self.filenames.filter(function (n) { + return (skipNull ? n !== undefined : n !== undefined && n !== null); + }); + }, + _setPreviewError: function ($thumb, keepFile) { + var self = this, removeFrame = self.removeFromPreviewOnError && !self.retryErrorUploads; + if (!keepFile || removeFrame) { + self.fileManager.remove($thumb); + } + if (!self.showPreview) { + return; + } + if (removeFrame) { + $thumb.remove(); + return; + } else { + self._setThumbStatus($thumb, 'Error'); + } + self._refreshUploadButton($thumb); + }, + _refreshUploadButton: function ($thumb) { + var self = this, $btn = $thumb.find('.kv-file-upload'), cfg = self.fileActionSettings, + icon = cfg.uploadIcon, title = cfg.uploadTitle; + if (!$btn.length) { + return; + } + if (self.retryErrorUploads) { + icon = cfg.uploadRetryIcon; + title = cfg.uploadRetryTitle; + } + $btn.attr('title', title); + $h.setHtml($btn, icon); + }, + _checkDimensions: function (i, chk, $img, $thumb, fname, type, params) { + var self = this, msg, dim, tag = chk === 'Small' ? 'min' : 'max', limit = self[tag + 'Image' + type], + $imgEl, isValid; + if ($h.isEmpty(limit) || !$img.length) { + return; + } + $imgEl = $img[0]; + dim = (type === 'Width') ? $imgEl.naturalWidth || $imgEl.width : $imgEl.naturalHeight || $imgEl.height; + isValid = chk === 'Small' ? dim >= limit : dim <= limit; + if (isValid) { + return; + } + msg = self['msgImage' + type + chk].setTokens({'name': fname, 'size': limit}); + self._showFileError(msg, params); + self._setPreviewError($thumb); + }, + _getExifObj: function (data) { + var self = this, exifObj, error = $h.logMessages.exifWarning; + if (data.slice(0, 23) !== 'data:image/jpeg;base64,' && data.slice(0, 22) !== 'data:image/jpg;base64,') { + exifObj = null; + return; + } + try { + exifObj = window.piexif ? window.piexif.load(data) : null; + } catch (err) { + exifObj = null; + error = err && err.message || ''; + } + if (!exifObj) { + self._log($h.logMessages.badExifParser, {details: error}); + } + return exifObj; + }, + setImageOrientation: function ($img, $zoomImg, value, $thumb) { + var self = this, invalidImg = !$img || !$img.length, invalidZoomImg = !$zoomImg || !$zoomImg.length, $mark, + isHidden = false, $div, zoomOnly = invalidImg && $thumb && $thumb.attr('data-template') === 'image', ev; + if (invalidImg && invalidZoomImg) { + return; + } + ev = 'load.fileinputimageorient'; + if (zoomOnly) { + $img = $zoomImg; + $zoomImg = null; + $img.css(self.previewSettings.image); + $div = $(document.createElement('div')).appendTo($thumb.find('.kv-file-content')); + $mark = $(document.createElement('span')).insertBefore($img); + $img.css('visibility', 'hidden').removeClass('file-zoom-detail').appendTo($div); + } else { + isHidden = !$img.is(':visible'); + } + $img.off(ev).on(ev, function () { + if (isHidden) { + self.$preview.removeClass('hide-content'); + $thumb.find('.kv-file-content').css('visibility', 'hidden'); + } + var img = $img[0], zoomImg = $zoomImg && $zoomImg.length ? $zoomImg[0] : null, + h = img.offsetHeight, w = img.offsetWidth, r = $h.getRotation(value); + if (isHidden) { + $thumb.find('.kv-file-content').css('visibility', 'visible'); + self.$preview.addClass('hide-content'); + } + $img.data('orientation', value); + if (zoomImg) { + $zoomImg.data('orientation', value); + } + if (value < 5) { + $h.setTransform(img, r); + $h.setTransform(zoomImg, r); + return; + } + var offsetAngle = Math.atan(w / h), origFactor = Math.sqrt(Math.pow(h, 2) + Math.pow(w, 2)), + scale = !origFactor ? 1 : (h / Math.cos(Math.PI / 2 + offsetAngle)) / origFactor, + s = ' scale(' + Math.abs(scale) + ')'; + $h.setTransform(img, r + s); + $h.setTransform(zoomImg, r + s); + if (zoomOnly) { + $img.css('visibility', 'visible').insertAfter($mark).addClass('file-zoom-detail'); + $mark.remove(); + $div.remove(); + } + }); + }, + _validateImageOrientation: function ($img, file, previewId, fileId, caption, ftype, fsize, iData) { + var self = this, exifObj = null, value, autoOrientImage = self.autoOrientImage, selector; + if (self.canOrientImage) { + $img.css('image-orientation', (autoOrientImage ? 'from-image' : 'none')); + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + return; + } + selector = $h.getZoomSelector(previewId, ' img'); + exifObj = autoOrientImage ? self._getExifObj(iData) : null; + value = exifObj ? exifObj['0th'][piexif.ImageIFD.Orientation] : null; // jshint ignore:line + if (!value) { + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + return; + } + self.setImageOrientation($img, $(selector), value, self._getFrame(previewId)); + self._raise('fileimageoriented', {'$img': $img, 'file': file}); + self._validateImage(previewId, fileId, caption, ftype, fsize, iData, exifObj); + }, + _validateImage: function (previewId, fileId, fname, ftype, fsize, iData, exifObj) { + var self = this, $preview = self.$preview, params, w1, w2, $thumb = self._getFrame(previewId), + i = $thumb.attr('data-fileindex'), $img = $thumb.find('img'); + fname = fname || 'Untitled'; + $img.one('load', function () { + w1 = $thumb.width(); + w2 = $preview.width(); + if (w1 > w2) { + $img.css('width', '100%'); + } + params = {ind: i, id: previewId, fileId: fileId}; + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Small', $img, $thumb, fname, 'Height', params); + if (!self.resizeImage) { + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Width', params); + self._checkDimensions(i, 'Large', $img, $thumb, fname, 'Height', params); + } + self._raise('fileimageloaded', [previewId]); + self.fileManager.addImage(fileId, { + ind: i, + img: $img, + thumb: $thumb, + pid: previewId, + typ: ftype, + siz: fsize, + validated: false, + imgData: iData, + exifObj: exifObj + }); + $thumb.data('exif', exifObj); + self._validateAllImages(); + }).one('error', function () { + self._raise('fileimageloaderror', [previewId]); + }); + }, + _validateAllImages: function () { + var self = this, counter = {val: 0}, numImgs = self.fileManager.getImageCount(), fsize, + minSize = self.resizeIfSizeMoreThan; + if (numImgs !== self.fileManager.totalImages) { + return; + } + self._raise('fileimagesloaded'); + if (!self.resizeImage) { + return; + } + $.each(self.fileManager.loadedImages, function (id, config) { + if (!config.validated) { + fsize = config.siz; + if (fsize && fsize > minSize * self.bytesToKB) { + self._getResizedImage(id, config, counter, numImgs); + } + config.validated = true; + } + }); + }, + _getResizedImage: function (id, config, counter, numImgs) { + var self = this, img = $(config.img)[0], width = img.naturalWidth, height = img.naturalHeight, blob, + ratio = 1, maxWidth = self.maxImageWidth || width, maxHeight = self.maxImageHeight || height, + isValidImage = !!(width && height), chkWidth, chkHeight, canvas = self.imageCanvas, dataURI, + context = self.imageCanvasContext, type = config.typ, pid = config.pid, ind = config.ind, + $thumb = config.thumb, throwError, msg, exifObj = config.exifObj, exifStr, file, params, evParams; + throwError = function (msg, params, ev) { + if (self.isAjaxUpload) { + self._showFileError(msg, params, ev); + } else { + self._showError(msg, params, ev); + } + self._setPreviewError($thumb); + }; + file = self.fileManager.getFile(id); + params = {id: pid, 'index': ind, fileId: id}; + evParams = [id, pid, ind]; + if (!file || !isValidImage || (width <= maxWidth && height <= maxHeight)) { + if (isValidImage && file) { + self._raise('fileimageresized', evParams); + } + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized'); + } + if (!isValidImage) { + throwError(self.msgImageResizeError, params, 'fileimageresizeerror'); + return; + } + } + type = type || self.resizeDefaultImageType; + chkWidth = width > maxWidth; + chkHeight = height > maxHeight; + if (self.resizePreference === 'width') { + ratio = chkWidth ? maxWidth / width : (chkHeight ? maxHeight / height : 1); + } else { + ratio = chkHeight ? maxHeight / height : (chkWidth ? maxWidth / width : 1); + } + self._resetCanvas(); + width *= ratio; + height *= ratio; + canvas.width = width; + canvas.height = height; + try { + context.drawImage(img, 0, 0, width, height); + dataURI = canvas.toDataURL(type, self.resizeQuality); + if (exifObj) { + exifStr = window.piexif.dump(exifObj); + dataURI = window.piexif.insert(exifStr, dataURI); + } + blob = $h.dataURI2Blob(dataURI); + self.fileManager.setFile(id, blob); + self._raise('fileimageresized', evParams); + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized', [undefined, undefined]); + } + if (!(blob instanceof Blob)) { + throwError(self.msgImageResizeError, params, 'fileimageresizeerror'); + } + } catch (err) { + counter.val++; + if (counter.val === numImgs) { + self._raise('fileimagesresized', [undefined, undefined]); + } + msg = self.msgImageResizeException.replace('{errors}', err.message); + throwError(msg, params, 'fileimageresizeexception'); + } + }, + _showProgress: function () { + var self = this; + if (self.$progress && self.$progress.length) { + self.$progress.show(); + } + }, + _hideProgress: function () { + var self = this; + if (self.$progress && self.$progress.length) { + self.$progress.hide(); + } + }, + _initBrowse: function ($container) { + var self = this, $el = self.$element; + if (self.showBrowse) { + self.$btnFile = $container.find('.btn-file').append($el); + } else { + $el.appendTo($container).attr('tabindex', -1); + $h.addCss($el, 'file-no-browse'); + } + }, + _initClickable: function () { + var self = this, $zone, $tmpZone; + if (!self.isClickable) { + return; + } + $zone = self.$dropZone; + if (!self.isAjaxUpload) { + $tmpZone = self.$preview.find('.file-default-preview'); + if ($tmpZone.length) { + $zone = $tmpZone; + } + } + + $h.addCss($zone, 'clickable'); + $zone.attr('tabindex', -1); + self._handler($zone, 'click', function (e) { + var $tar = $(e.target); + if (!self.$errorContainer.is(':visible') && (!$tar.parents( + '.file-preview-thumbnails').length || $tar.parents( + '.file-default-preview').length)) { + self.$element.data('zoneClicked', true).trigger('click'); + $zone.blur(); + } + }); + }, + _initCaption: function () { + var self = this, cap = self.initialCaption || ''; + if (self.overwriteInitial || $h.isEmpty(cap)) { + self.$caption.val(''); + return false; + } + self._setCaption(cap); + return true; + }, + _setCaption: function (content, isError) { + var self = this, title, out, icon, n, cap, file; + if (!self.$caption.length) { + return; + } + self.$captionContainer.removeClass('icon-visible'); + if (isError) { + title = $('
    ' + self.msgValidationError + '
    ').text(); + n = self.fileManager.count(); + if (n) { + file = self.fileManager.getFirstFile(); + cap = n === 1 && file ? file.nameFmt : self._getMsgSelected(n); + } else { + cap = self._getMsgSelected(self.msgNo); + } + out = $h.isEmpty(content) ? cap : content; + icon = '' + self.msgValidationErrorIcon + ''; + } else { + if ($h.isEmpty(content)) { + self.$caption.attr('title', ''); + return; + } + title = $('
    ' + content + '
    ').text(); + out = title; + icon = self._getLayoutTemplate('fileIcon'); + } + self.$captionContainer.addClass('icon-visible'); + self.$caption.attr('title', title).val(out); + $h.setHtml(self.$captionIcon, icon); + }, + _createContainer: function () { + var self = this, attribs = {'class': 'file-input file-input-new' + (self.rtl ? ' kv-rtl' : '')}, + $container = $h.createElement($h.cspBuffer.stash(self._renderMain())); + $h.cspBuffer.apply($container); + $container.insertBefore(self.$element).attr(attribs); + self._initBrowse($container); + if (self.theme) { + $container.addClass('theme-' + self.theme); + } + return $container; + }, + _refreshContainer: function () { + var self = this, $container = self.$container, $el = self.$element; + $el.insertAfter($container); + $h.setHtml($container, self._renderMain()); + self._initBrowse($container); + self._validateDisabled(); + }, + _validateDisabled: function () { + var self = this; + self.$caption.attr({readonly: self.isDisabled}); + }, + _setTabIndex: function (type, html) { + var self = this, index = self.tabIndexConfig[type]; + return html.setTokens({ + tabIndexConfig: index === undefined || index === null ? '' : 'tabindex="' + index + '"' + }); + }, + _renderMain: function () { + var self = this, + dropCss = self.dropZoneEnabled ? ' file-drop-zone' : 'file-drop-disabled', + close = !self.showClose ? '' : self._getLayoutTemplate('close'), + preview = !self.showPreview ? '' : self._getLayoutTemplate('preview') + .setTokens({'class': self.previewClass, 'dropClass': dropCss}), + css = self.isDisabled ? self.captionClass + ' file-caption-disabled' : self.captionClass, + caption = self.captionTemplate.setTokens({'class': css + ' kv-fileinput-caption'}); + caption = self._setTabIndex('caption', caption); + return self.mainTemplate.setTokens({ + 'class': self.mainClass + (!self.showBrowse && self.showCaption ? ' no-browse' : ''), + 'inputGroupClass': self.inputGroupClass, + 'preview': preview, + 'close': close, + 'caption': caption, + 'upload': self._renderButton('upload'), + 'remove': self._renderButton('remove'), + 'cancel': self._renderButton('cancel'), + 'pause': self._renderButton('pause'), + 'browse': self._renderButton('browse') + }); + + }, + _renderButton: function (type) { + var self = this, tmplt = self._getLayoutTemplate('btnDefault'), css = self[type + 'Class'], + title = self[type + 'Title'], icon = self[type + 'Icon'], label = self[type + 'Label'], + status = self.isDisabled ? ' disabled' : '', btnType = 'button'; + switch (type) { + case 'remove': + if (!self.showRemove) { + return ''; + } + break; + case 'cancel': + if (!self.showCancel) { + return ''; + } + css += ' kv-hidden'; + break; + case 'pause': + if (!self.showPause) { + return ''; + } + css += ' kv-hidden'; + break; + case 'upload': + if (!self.showUpload) { + return ''; + } + if (self.isAjaxUpload && !self.isDisabled) { + tmplt = self._getLayoutTemplate('btnLink').replace('{href}', self.uploadUrl); + } else { + btnType = 'submit'; + } + break; + case 'browse': + if (!self.showBrowse) { + return ''; + } + tmplt = self._getLayoutTemplate('btnBrowse'); + break; + default: + return ''; + } + tmplt = self._setTabIndex(type, tmplt); + + css += type === 'browse' ? ' btn-file' : ' fileinput-' + type + ' fileinput-' + type + '-button'; + if (!$h.isEmpty(label)) { + label = ' ' + label + ''; + } + return tmplt.setTokens({ + 'type': btnType, 'css': css, 'title': title, 'status': status, 'icon': icon, 'label': label + }); + }, + _renderThumbProgress: function () { + var self = this; + return '
    ' + + self.progressInfoTemplate.setTokens({percent: 101, status: self.msgUploadBegin, stats: ''}) + + '
    '; + }, + _renderFileFooter: function (cat, caption, size, width, isError) { + var self = this, config = self.fileActionSettings, rem = config.showRemove, drg = config.showDrag, + upl = config.showUpload, zoom = config.showZoom, out, params, + template = self._getLayoutTemplate('footer'), tInd = self._getLayoutTemplate('indicator'), + ind = isError ? config.indicatorError : config.indicatorNew, + title = isError ? config.indicatorErrorTitle : config.indicatorNewTitle, + indicator = tInd.setTokens({'indicator': ind, 'indicatorTitle': title}); + size = self._getSize(size); + params = {type: cat, caption: caption, size: size, width: width, progress: '', indicator: indicator}; + if (self.isAjaxUpload) { + params.progress = self._renderThumbProgress(); + params.actions = self._renderFileActions(params, upl, false, rem, zoom, drg, false, false, false); + } else { + params.actions = self._renderFileActions(params, false, false, false, zoom, drg, false, false, false); + } + out = template.setTokens(params); + out = $h.replaceTags(out, self.previewThumbTags); + return out; + }, + _renderFileActions: function ( + cfg, + showUpl, + showDwn, + showDel, + showZoom, + showDrag, + disabled, + url, + key, + isInit, + dUrl, + dFile + ) { + var self = this; + if (!cfg.type && isInit) { + cfg.type = 'image'; + } + if (self.enableResumableUpload) { + showUpl = false; + } else { + if (typeof showUpl === 'function') { + showUpl = showUpl(cfg); + } + } + if (typeof showDwn === 'function') { + showDwn = showDwn(cfg); + } + if (typeof showDel === 'function') { + showDel = showDel(cfg); + } + if (typeof showZoom === 'function') { + showZoom = showZoom(cfg); + } + if (typeof showDrag === 'function') { + showDrag = showDrag(cfg); + } + if (!showUpl && !showDwn && !showDel && !showZoom && !showDrag) { + return ''; + } + var vUrl = url === false ? '' : ' data-url="' + url + '"', btnZoom = '', btnDrag = '', css, + vKey = key === false ? '' : ' data-key="' + key + '"', btnDelete = '', btnUpload = '', btnDownload = '', + template = self._getLayoutTemplate('actions'), config = self.fileActionSettings, + otherButtons = self.otherActionButtons.setTokens({'dataKey': vKey, 'key': key}), + removeClass = disabled ? config.removeClass + ' disabled' : config.removeClass; + if (showDel) { + btnDelete = self._getLayoutTemplate('actionDelete').setTokens({ + 'removeClass': removeClass, + 'removeIcon': config.removeIcon, + 'removeTitle': config.removeTitle, + 'dataUrl': vUrl, + 'dataKey': vKey, + 'key': key + }); + } + if (showUpl) { + btnUpload = self._getLayoutTemplate('actionUpload').setTokens({ + 'uploadClass': config.uploadClass, + 'uploadIcon': config.uploadIcon, + 'uploadTitle': config.uploadTitle + }); + } + if (showDwn) { + btnDownload = self._getLayoutTemplate('actionDownload').setTokens({ + 'downloadClass': config.downloadClass, + 'downloadIcon': config.downloadIcon, + 'downloadTitle': config.downloadTitle, + 'downloadUrl': dUrl || self.initialPreviewDownloadUrl + }); + btnDownload = btnDownload.setTokens({'filename': dFile, 'key': key}); + } + if (showZoom) { + btnZoom = self._getLayoutTemplate('actionZoom').setTokens({ + 'zoomClass': config.zoomClass, + 'zoomIcon': config.zoomIcon, + 'zoomTitle': config.zoomTitle + }); + } + if (showDrag && isInit) { + css = 'drag-handle-init ' + config.dragClass; + btnDrag = self._getLayoutTemplate('actionDrag').setTokens({ + 'dragClass': css, + 'dragTitle': config.dragTitle, + 'dragIcon': config.dragIcon + }); + } + return template.setTokens({ + 'delete': btnDelete, + 'upload': btnUpload, + 'download': btnDownload, + 'zoom': btnZoom, + 'drag': btnDrag, + 'other': otherButtons + }); + }, + _browse: function (e) { + var self = this; + if (e && e.isDefaultPrevented() || !self._raise('filebrowse')) { + return; + } + if (self.isError && !self.isAjaxUpload) { + self.clear(); + } + if (self.focusCaptionOnBrowse) { + self.$captionContainer.focus(); + } + }, + _change: function (e) { + var self = this; + $(document.body).off('focusin.fileinput focusout.fileinput'); + if (self.changeTriggered) { + return; + } + self._setLoading('show'); + var $el = self.$element, isDragDrop = arguments.length > 1, isAjaxUpload = self.isAjaxUpload, + tfiles, files = isDragDrop ? arguments[1] : $el[0].files, ctr = self.fileManager.count(), + total, initCount, len, isSingleUpl = $h.isEmpty($el.attr('multiple')), + maxCount = !isAjaxUpload && isSingleUpl ? 1 : self.maxFileCount, maxTotCount = self.maxTotalFileCount, + inclAll = maxTotCount > 0 && maxTotCount > maxCount, flagSingle = (isSingleUpl && ctr > 0), + throwError = function (mesg, file, previewId, index) { + var p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files), {id: previewId, index: index}), + p2 = {id: previewId, index: index, file: file, files: files}; + self.isPersistentError = true; + self._setLoading('hide'); + return isAjaxUpload ? self._showFileError(mesg, p1) : self._showError(mesg, p2); + }, + maxCountCheck = function (n, m, all) { + var msg = all ? self.msgTotalFilesTooMany : self.msgFilesTooMany; + msg = msg.replace('{m}', m).replace('{n}', n); + self.isError = throwError(msg, null, null, null); + self.$captionContainer.removeClass('icon-visible'); + self._setCaption('', true); + self.$container.removeClass('file-input-new file-input-ajax-new'); + }; + self.reader = null; + self._resetUpload(); + self._hideFileIcon(); + if (self.dropZoneEnabled) { + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); + } + if (!isAjaxUpload) { + if (e.target && e.target.files === undefined) { + files = e.target.value ? [{name: e.target.value.replace(/^.+\\/, '')}] : []; + } else { + files = e.target.files || {}; + } + } + tfiles = files; + if ($h.isEmpty(tfiles) || tfiles.length === 0) { + if (!isAjaxUpload) { + self.clear(); + } + self._raise('fileselectnone'); + return; + } + self._resetErrors(); + len = tfiles.length; + initCount = isAjaxUpload ? (self.fileManager.count() + len) : len; + total = self._getFileCount(initCount, inclAll ? false : undefined); + if (maxCount > 0 && total > maxCount) { + if (!self.autoReplace || len > maxCount) { + maxCountCheck((self.autoReplace && len > maxCount ? len : total), maxCount); + return; + } + if (total > maxCount) { + self._resetPreviewThumbs(isAjaxUpload); + } + } else { + if (inclAll) { + total = self._getFileCount(initCount, true); + if (maxTotCount > 0 && total > maxTotCount) { + if (!self.autoReplace || len > maxCount) { + maxCountCheck((self.autoReplace && len > maxTotCount ? len : total), maxTotCount, true); + return; + } + if (total > maxCount) { + self._resetPreviewThumbs(isAjaxUpload); + } + } + } + if (!isAjaxUpload || flagSingle) { + self._resetPreviewThumbs(false); + if (flagSingle) { + self.clearFileStack(); + } + } else { + if (isAjaxUpload && ctr === 0 && (!self.previewCache.count(true) || self.overwriteInitial)) { + self._resetPreviewThumbs(true); + } + } + } + self.readFiles(tfiles); + self._setLoading('hide'); + }, + _abort: function (params) { + var self = this, data; + if (self.ajaxAborted && typeof self.ajaxAborted === 'object' && self.ajaxAborted.message !== undefined) { + data = $.extend(true, {}, self._getOutData(null), params); + data.abortData = self.ajaxAborted.data || {}; + data.abortMessage = self.ajaxAborted.message; + self._setProgress(101, self.$progress, self.msgCancelled); + self._showFileError(self.ajaxAborted.message, data, 'filecustomerror'); + self.cancel(); + self.unlock(); + return true; + } + return !!self.ajaxAborted; + }, + _resetFileStack: function () { + var self = this, i = 0; + self._getThumbs().each(function () { + var $thumb = $(this), ind = $thumb.attr('data-fileindex'), pid = $thumb.attr('id'); + if (ind === '-1' || ind === -1) { + return; + } + if (!self._getThumbFile($thumb)) { + $thumb.attr({'data-fileindex': i}); + i++; + } else { + $thumb.attr({'data-fileindex': '-1'}); + } + self._getZoom(pid).attr({ + 'data-fileindex': $thumb.attr('data-fileindex') + }); + }); + }, + _isFileSelectionValid: function (cnt) { + var self = this; + cnt = cnt || 0; + if (self.required && !self.getFilesCount()) { + self.$errorContainer.html(''); + self._showFileError(self.msgFileRequired); + return false; + } + if (self.minFileCount > 0 && self._getFileCount(cnt) < self.minFileCount) { + self._noFilesError({}); + return false; + } + return true; + }, + _canPreview: function (file) { + var self = this; + if (!file || !self.showPreview || !self.$preview || !self.$preview.length) { + return false; + } + var name = file.name || '', type = file.type || '', size = (file.size || 0) / self.bytesToKB, + cat = self._parseFileType(type, name), allowedTypes, allowedMimes, allowedExts, skipPreview, + types = self.allowedPreviewTypes, mimes = self.allowedPreviewMimeTypes, + exts = self.allowedPreviewExtensions || [], dTypes = self.disabledPreviewTypes, + dMimes = self.disabledPreviewMimeTypes, dExts = self.disabledPreviewExtensions || [], + maxSize = self.maxFilePreviewSize && parseFloat(self.maxFilePreviewSize) || 0, + expAllExt = new RegExp('\\.(' + exts.join('|') + ')$', 'i'), + expDisExt = new RegExp('\\.(' + dExts.join('|') + ')$', 'i'); + allowedTypes = !types || types.indexOf(cat) !== -1; + allowedMimes = !mimes || mimes.indexOf(type) !== -1; + allowedExts = !exts.length || $h.compare(name, expAllExt); + skipPreview = (dTypes && dTypes.indexOf(cat) !== -1) || (dMimes && dMimes.indexOf(type) !== -1) || + (dExts.length && $h.compare(name, expDisExt)) || (maxSize && !isNaN(maxSize) && size > maxSize); + return !skipPreview && (allowedTypes || allowedMimes || allowedExts); + }, + addToStack: function (file, id) { + this.fileManager.add(file, id); + }, + clearFileStack: function () { + var self = this; + self.fileManager.clear(); + self._initResumableUpload(); + if (self.enableResumableUpload) { + if (self.showPause === null) { + self.showPause = true; + } + if (self.showCancel === null) { + self.showCancel = false; + } + } else { + self.showPause = false; + if (self.showCancel === null) { + self.showCancel = true; + } + } + return self.$element; + }, + getFileStack: function () { + return this.fileManager.stack; + }, + getFileList: function () { + return this.fileManager.list(); + }, + getFilesSize: function () { + return this.fileManager.getTotalSize(); + }, + getFilesCount: function (includeInitial) { + var self = this, len = self.isAjaxUpload ? self.fileManager.count() : self._inputFileCount(); + if (includeInitial) { + len += self.previewCache.count(true); + } + return self._getFileCount(len); + }, + _initCapStatus: function (status) { + var self = this, $cap = self.$caption; + $cap.removeClass('is-valid file-processing'); + if (!status) { + return; + } + if (status === 'processing') { + $cap.addClass('file-processing'); + } else { + $cap.addClass('is-valid'); + } + }, + _setLoading: function (type) { + var self = this; + self.$previewStatus.html(type === 'hide' ? '' : self.msgProcessing); + self.$container.removeClass('file-thumb-loading'); + self._initCapStatus(type === 'hide' ? '' : 'processing'); + if (type !== 'hide') { + if (self.dropZoneEnabled) { + self.$container.find('.file-drop-zone .' + self.dropZoneTitleClass).remove(); + } + self.$container.addClass('file-thumb-loading'); + } + }, + _initFileSelected: function () { + var self = this, $el = self.$element, $body = $(document.body), ev = 'focusin.fileinput focusout.fileinput'; + if ($body.length) { + $body.off(ev).on('focusout.fileinput', function () { + self._setLoading('show'); + }).on('focusin.fileinput', function () { + setTimeout(function () { + if (!$el.val()) { + self._setLoading('hide'); + self._setFileDropZoneTitle(); + } + $body.off(ev); + }, 2500); + }); + } else { + self._setLoading('hide'); + } + }, + readFiles: function (files) { + this.reader = new FileReader(); + var self = this, reader = self.reader, $container = self.$previewContainer, + $status = self.$previewStatus, msgLoading = self.msgLoading, msgProgress = self.msgProgress, + previewInitId = self.previewInitId, numFiles = files.length, settings = self.fileTypeSettings, + readFile, fileTypes = self.allowedFileTypes, typLen = fileTypes ? fileTypes.length : 0, + fileExt = self.allowedFileExtensions, strExt = $h.isEmpty(fileExt) ? '' : fileExt.join(', '), + throwError = function (msg, file, previewId, index, fileId) { + var $thumb, p1 = $.extend(true, {}, self._getOutData(null, {}, {}, files), + {id: previewId, index: index, fileId: fileId}), + p2 = {id: previewId, index: index, fileId: fileId, file: file, files: files}; + self._previewDefault(file, true); + $thumb = self._getFrame(previewId, true); + self._setLoading('hide'); + if (self.isAjaxUpload) { + setTimeout(function () { + readFile(index + 1); + }, self.processDelay); + } else { + self.unlock(); + numFiles = 0; + } + if (self.removeFromPreviewOnError && $thumb.length) { + $thumb.remove(); + } else { + self._initFileActions(); + $thumb.find('.kv-file-upload').remove(); + } + self.isPersistentError = true; + self.isError = self.isAjaxUpload ? self._showFileError(msg, p1) : self._showError(msg, p2); + self._updateFileDetails(numFiles); + }; + self.fileManager.clearImages(); + $.each(files, function (key, file) { + var func = self.fileTypeSettings.image; + if (func && func(file.type)) { + self.fileManager.totalImages++; + } + }); + readFile = function (i) { + var $error = self.$errorContainer, errors, fm = self.fileManager; + if (i >= numFiles) { + self.unlock(); + if (self.duplicateErrors.length) { + errors = '
  • ' + self.duplicateErrors.join('
  • ') + '
  • '; + if ($error.find('ul').length === 0) { + $h.setHtml($error, self.errorCloseButton + '
      ' + errors + '
    '); + } else { + $error.find('ul').append(errors); + } + $error.fadeIn(self.fadeDelay); + self._handler($error.find('.kv-error-close'), 'click', function () { + $error.fadeOut(self.fadeDelay); + }); + self.duplicateErrors = []; + } + if (self.isAjaxUpload) { + self._raise('filebatchselected', [fm.stack]); + if (fm.count() === 0 && !self.isError) { + self.reset(); + } + } else { + self._raise('filebatchselected', [files]); + } + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + $status.html(''); + return; + } + self.lock(true); + var file = files[i], id = self._getFileId(file), previewId = previewInitId + '-' + id, fSizeKB, j, msg, + fnImage = settings.image, typ, chk, typ1, typ2, + caption = self._getFileName(file, ''), fileSize = (file && file.size || 0) / self.bytesToKB, + fileExtExpr = '', previewData = $h.createObjectURL(file), fileCount = 0, + strTypes = '', fileId, canLoad, fileReaderAborted = false, + func, knownTypes = 0, isImage, txtFlag, processFileLoaded = function () { + var isImageResized = !!fm.loadedImages[id], msg = msgProgress.setTokens({ + 'index': i + 1, + 'files': numFiles, + 'percent': 50, + 'name': caption + }); + setTimeout(function () { + $status.html(msg); + self._updateFileDetails(numFiles); + readFile(i + 1); + }, self.processDelay); + if (self._raise('fileloaded', [file, previewId, id, i, reader]) && self.isAjaxUpload) { + if (!isImageResized) { + fm.add(file); + } + } else { + if (isImageResized) { + fm.removeFile(id); + } + } + }; + if (!file) { + return; + } + fileId = fm.getId(file); + if (typLen > 0) { + for (j = 0; j < typLen; j++) { + typ1 = fileTypes[j]; + typ2 = self.msgFileTypes[typ1] || typ1; + strTypes += j === 0 ? typ2 : ', ' + typ2; + } + } + if (caption === false) { + readFile(i + 1); + return; + } + if (caption.length === 0) { + msg = self.msgInvalidFileName.replace('{name}', $h.htmlEncode($h.getFileName(file), '[unknown]')); + throwError(msg, file, previewId, i, fileId); + return; + } + if (!$h.isEmpty(fileExt)) { + fileExtExpr = new RegExp('\\.(' + fileExt.join('|') + ')$', 'i'); + } + fSizeKB = fileSize.toFixed(2); + if (self.isAjaxUpload && fm.exists(fileId) || self._getFrame(previewId, true).length) { + var p2 = {id: previewId, index: i, fileId: fileId, file: file, files: files}; + msg = self.msgDuplicateFile.setTokens({name: caption, size: fSizeKB}); + if (self.isAjaxUpload) { + self.duplicateErrors.push(msg); + self.isDuplicateError = true; + self._raise('fileduplicateerror', [file, fileId, caption, fSizeKB, previewId, i]); + readFile(i + 1); + self._updateFileDetails(numFiles); + } else { + self._showError(msg, p2); + self.unlock(); + numFiles = 0; + self._clearFileInput(); + self.reset(); + self._updateFileDetails(numFiles); + } + return; + } + if (self.maxFileSize > 0 && fileSize > self.maxFileSize) { + msg = self.msgSizeTooLarge.setTokens({ + 'name': caption, + 'size': fSizeKB, + 'maxSize': self.maxFileSize + }); + throwError(msg, file, previewId, i, fileId); + return; + } + if (self.minFileSize !== null && fileSize <= $h.getNum(self.minFileSize)) { + msg = self.msgSizeTooSmall.setTokens({ + 'name': caption, + 'size': fSizeKB, + 'minSize': self.minFileSize + }); + throwError(msg, file, previewId, i, fileId); + return; + } + if (!$h.isEmpty(fileTypes) && $h.isArray(fileTypes)) { + for (j = 0; j < fileTypes.length; j += 1) { + typ = fileTypes[j]; + func = settings[typ]; + fileCount += !func || (typeof func !== 'function') ? 0 : (func(file.type, + $h.getFileName(file)) ? 1 : 0); + } + if (fileCount === 0) { + msg = self.msgInvalidFileType.setTokens({name: caption, types: strTypes}); + throwError(msg, file, previewId, i, fileId); + return; + } + } + if (fileCount === 0 && !$h.isEmpty(fileExt) && $h.isArray(fileExt) && !$h.isEmpty(fileExtExpr)) { + chk = $h.compare(caption, fileExtExpr); + fileCount += $h.isEmpty(chk) ? 0 : chk.length; + if (fileCount === 0) { + msg = self.msgInvalidFileExtension.setTokens({name: caption, extensions: strExt}); + throwError(msg, file, previewId, i, fileId); + return; + } + } + if (!self._canPreview(file)) { + canLoad = self.isAjaxUpload && self._raise('filebeforeload', [file, i, reader]); + if (self.isAjaxUpload && canLoad) { + fm.add(file); + } + if (self.showPreview && canLoad) { + $container.addClass('file-thumb-loading'); + self._initCapStatus('processing'); + self._previewDefault(file); + self._initFileActions(); + } + setTimeout(function () { + if (canLoad) { + self._updateFileDetails(numFiles); + } + readFile(i + 1); + self._raise('fileloaded', [file, previewId, id, i]); + }, 10); + return; + } + isImage = fnImage(file.type, caption); + $status.html(msgLoading.replace('{index}', i + 1).replace('{files}', numFiles)); + $container.addClass('file-thumb-loading'); + self._initCapStatus('processing'); + reader.onerror = function (evt) { + self._errorHandler(evt, caption); + }; + reader.onload = function (theFile) { + var hex, fileInfo, uint, byte, bytes = [], contents, mime, readImage = function () { + var newReader = new FileReader(); + newReader.onerror = function (theFileNew) { + self._errorHandler(theFileNew, caption); + }; + newReader.onload = function (theFileNew) { + if (self.isAjaxUpload && !self._raise('filebeforeload', [file, i, reader])) { + fileReaderAborted = true; + self._resetCaption(); + reader.abort(); + $status.html(''); + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + self.enable(); + return; + } + self._previewFile(i, file, theFileNew, previewData, fileInfo); + self._initFileActions(); + processFileLoaded(); + }; + newReader.readAsDataURL(file); + }; + fileInfo = {'name': caption, 'type': file.type}; + $.each(settings, function (k, f) { + if (k !== 'object' && k !== 'other' && typeof f === 'function' && f(file.type, caption)) { + knownTypes++; + } + }); + if (knownTypes === 0) { // auto detect mime types from content if no known file types detected + uint = new Uint8Array(theFile.target.result); + for (j = 0; j < uint.length; j++) { + byte = uint[j].toString(16); + bytes.push(byte); + } + hex = bytes.join('').toLowerCase().substring(0, 8); + mime = $h.getMimeType(hex, '', ''); + if ($h.isEmpty(mime)) { // look for ascii text content + contents = $h.arrayBuffer2String(reader.result); + mime = $h.isSvg(contents) ? 'image/svg+xml' : $h.getMimeType(hex, contents, file.type); + } + fileInfo = {'name': caption, 'type': mime}; + isImage = fnImage(mime, ''); + if (isImage) { + readImage(txtFlag); + return; + } + } + if (self.isAjaxUpload && !self._raise('filebeforeload', [file, i, reader])) { + fileReaderAborted = true; + self._resetCaption(); + reader.abort(); + $status.html(''); + $container.removeClass('file-thumb-loading'); + self._initCapStatus('valid'); + self.enable(); + return; + } + self._previewFile(i, file, theFile, previewData, fileInfo); + self._initFileActions(); + processFileLoaded(); + }; + reader.onprogress = function (data) { + if (data.lengthComputable) { + var fact = (data.loaded / data.total) * 100, progress = Math.ceil(fact); + msg = msgProgress.setTokens({ + 'index': i + 1, + 'files': numFiles, + 'percent': progress, + 'name': caption + }); + setTimeout(function () { + if (!fileReaderAborted) { + $status.html(msg); + } + }, self.processDelay); + } + }; + if (isImage) { + reader.readAsDataURL(file); + } else { + reader.readAsArrayBuffer(file); + } + }; + + readFile(0); + self._updateFileDetails(numFiles); + }, + lock: function (selectMode) { + var self = this, $container = self.$container; + self._resetErrors(); + self.disable(); + if (!selectMode && self.showCancel) { + $container.find('.fileinput-cancel').show(); + } + if (!selectMode && self.showPause) { + $container.find('.fileinput-pause').show(); + } + self._initCapStatus('processing'); + self._raise('filelock', [self.fileManager.stack, self._getExtraData()]); + return self.$element; + }, + unlock: function (reset) { + var self = this, $container = self.$container; + if (reset === undefined) { + reset = true; + } + self.enable(); + $container.removeClass('is-locked'); + if (self.showCancel) { + $container.find('.fileinput-cancel').hide(); + } + if (self.showPause) { + $container.find('.fileinput-pause').hide(); + } + if (reset) { + self._resetFileStack(); + } + self._initCapStatus(); + self._raise('fileunlock', [self.fileManager.stack, self._getExtraData()]); + return self.$element; + }, + resume: function () { + var self = this, fm = self.fileManager, flag = false, rm = self.resumableManager; + fm.bpsLog = []; + fm.bps = 0; + if (!self.enableResumableUpload) { + return self.$element; + } + if (self.paused) { + self._toggleResumableProgress(self.progressPauseTemplate, self.msgUploadResume); + } else { + flag = true; + } + self.paused = false; + if (flag) { + self._toggleResumableProgress(self.progressInfoTemplate, self.msgUploadBegin); + } + setTimeout(function () { + rm.upload(); + }, self.processDelay); + return self.$element; + }, + paste: function (e) { + var self = this, ev = e.originalEvent, files = ev.clipboardData && ev.clipboardData.files || null; + if (files) { + self._dropFiles(e, files); + } + return self.$element; + }, + pause: function () { + var self = this, rm = self.resumableManager, xhr = self.ajaxRequests, len = xhr.length, i, + pct = rm.getProgress(), actions = self.fileActionSettings, tm = self.taskManager, + pool = tm.getPool(rm.id); + if (!self.enableResumableUpload) { + return self.$element; + } else { + if (pool) { + pool.cancel(); + } + } + self._raise('fileuploadpaused', [self.fileManager, rm]); + if (len > 0) { + for (i = 0; i < len; i += 1) { + self.paused = true; + xhr[i].abort(); + } + } + if (self.showPreview) { + self._getThumbs().each(function () { + var $thumb = $(this), t = self._getLayoutTemplate('stats'), stats, + $indicator = $thumb.find('.file-upload-indicator'); + $thumb.removeClass('file-uploading'); + if ($indicator.attr('title') === actions.indicatorLoadingTitle) { + self._setThumbStatus($thumb, 'Paused'); + stats = t.setTokens({pendingTime: self.msgPaused, uploadSpeed: ''}); + self.paused = true; + self._setProgress(pct, $thumb.find('.file-thumb-progress'), pct + '%', stats); + } + if (!self._getThumbFile($thumb)) { + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); + } + }); + } + self._setProgress(101, self.$progress, self.msgPaused); + return self.$element; + }, + cancel: function () { + var self = this, xhr = self.ajaxRequests, + rm = self.resumableManager, tm = self.taskManager, + pool = rm ? tm.getPool(rm.id) : undefined, len = xhr.length, i; + + if (self.enableResumableUpload && pool) { + pool.cancel().done(function () { + self._setProgressCancelled(); + }); + rm.reset(); + self._raise('fileuploadcancelled', [self.fileManager, rm]); + } else { + self._raise('fileuploadcancelled', [self.fileManager]); + } + self._initAjax(); + if (len > 0) { + for (i = 0; i < len; i += 1) { + self.cancelling = true; + xhr[i].abort(); + } + } + self._getThumbs().each(function () { + var $thumb = $(this), $prog = $thumb.find('.file-thumb-progress'); + $thumb.removeClass('file-uploading'); + self._setProgress(0, $prog); + $prog.hide(); + if (!self._getThumbFile($thumb)) { + $thumb.find('.kv-file-upload').removeClass('disabled').removeAttr('disabled'); + $thumb.find('.kv-file-remove').removeClass('disabled').removeAttr('disabled'); + } + self.unlock(); + }); + setTimeout(function () { + self._setProgressCancelled(); + }, self.processDelay); + return self.$element; + }, + clear: function () { + var self = this, cap; + if (!self._raise('fileclear')) { + return; + } + self.$btnUpload.removeAttr('disabled'); + self._getThumbs().find('video,audio,img').each(function () { + $h.cleanMemory($(this)); + }); + self._clearFileInput(); + self._resetUpload(); + self.clearFileStack(); + self.isDuplicateError = false; + self.isPersistentError = false; + self._resetErrors(true); + if (self._hasInitialPreview()) { + self._showFileIcon(); + self._resetPreview(); + self._initPreviewActions(); + self.$container.removeClass('file-input-new'); + } else { + self._getThumbs().each(function () { + self._clearObjects($(this)); + }); + if (self.isAjaxUpload) { + self.previewCache.data = {}; + } + self.$preview.html(''); + cap = (!self.overwriteInitial && self.initialCaption.length > 0) ? self.initialCaption : ''; + self.$caption.attr('title', '').val(cap); + $h.addCss(self.$container, 'file-input-new'); + self._validateDefaultPreview(); + } + if (self.$container.find($h.FRAMES).length === 0) { + if (!self._initCaption()) { + self.$captionContainer.removeClass('icon-visible'); + } + } + self._hideFileIcon(); + if (self.focusCaptionOnClear) { + self.$captionContainer.focus(); + } + self._setFileDropZoneTitle(); + self._raise('filecleared'); + return self.$element; + }, + reset: function () { + var self = this; + if (!self._raise('filereset')) { + return; + } + self.lastProgress = 0; + self._resetPreview(); + self.$container.find('.fileinput-filename').text(''); + $h.addCss(self.$container, 'file-input-new'); + if (self.getFrames().length) { + self.$container.removeClass('file-input-new'); + } + self.clearFileStack(); + self._setFileDropZoneTitle(); + return self.$element; + }, + disable: function () { + var self = this, $container = self.$container; + self.isDisabled = true; + self._raise('filedisabled'); + self.$element.attr('disabled', 'disabled'); + $container.addClass('is-locked'); + $h.addCss($container.find('.btn-file'), 'disabled'); + $container.find('.kv-fileinput-caption').addClass('file-caption-disabled'); + $container.find('.fileinput-remove, .fileinput-upload, .file-preview-frame button') + .attr('disabled', true); + self._initDragDrop(); + return self.$element; + }, + enable: function () { + var self = this, $container = self.$container; + self.isDisabled = false; + self._raise('fileenabled'); + self.$element.removeAttr('disabled'); + $container.removeClass('is-locked'); + $container.find('.kv-fileinput-caption').removeClass('file-caption-disabled'); + $container.find('.fileinput-remove, .fileinput-upload, .file-preview-frame button') + .removeAttr('disabled'); + $container.find('.btn-file').removeClass('disabled'); + self._initDragDrop(); + return self.$element; + }, + upload: function () { + var self = this, fm = self.fileManager, totLen = fm.count(), i, outData, + hasExtraData = !$.isEmptyObject(self._getExtraData()); + fm.bpsLog = []; + fm.bps = 0; + if (!self.isAjaxUpload || self.isDisabled || !self._isFileSelectionValid(totLen)) { + return; + } + self.lastProgress = 0; + self._resetUpload(); + if (totLen === 0 && !hasExtraData) { + self._showFileError(self.msgUploadEmpty); + return; + } + self.cancelling = false; + self._showProgress(); + self.lock(); + if (totLen === 0 && hasExtraData) { + self._setProgress(2); + self._uploadExtraOnly(); + return; + } + if (self.enableResumableUpload) { + return self.resume(); + } + if (self.uploadAsync || self.enableResumableUpload) { + outData = self._getOutData(null); + if (!self._checkBatchPreupload(outData)) { + return; + } + self.fileBatchCompleted = false; + self.uploadCache = []; + $.each(self.getFileStack(), function (id) { + var previewId = self._getThumbId(id); + self.uploadCache.push({id: previewId, content: null, config: null, tags: null, append: true}); + }); + self.$preview.find('.file-preview-initial').removeClass($h.SORT_CSS); + self._initSortable(); + } + self._setProgress(2); + self.hasInitData = false; + if (self.uploadAsync) { + i = 0; + $.each(self.getFileStack(), function (id) { + self._uploadSingle(i, id, true); + i++; + }); + return; + } + self._uploadBatch(); + return self.$element; + }, + destroy: function () { + var self = this, $form = self.$form, $cont = self.$container, $el = self.$element, ns = self.namespace; + $(document).off(ns); + $(window).off(ns); + if ($form && $form.length) { + $form.off(ns); + } + if (self.isAjaxUpload) { + self._clearFileInput(); + } + self._cleanup(); + self._initPreviewCache(); + $el.insertBefore($cont).off(ns).removeData(); + $cont.off().remove(); + return $el; + }, + refresh: function (options) { + var self = this, $el = self.$element; + if (typeof options !== 'object' || $h.isEmpty(options)) { + options = self.options; + } else { + options = $.extend(true, {}, self.options, options); + } + self._init(options, true); + self._listen(); + return $el; + }, + zoom: function (frameId) { + var self = this, $frame = self._getFrame(frameId); + self._showModal($frame); + }, + getExif: function (frameId) { + var self = this, $frame = self._getFrame(frameId); + return $frame && $frame.data('exif') || null; + }, + getFrames: function (cssFilter) { + var self = this, $frames; + cssFilter = cssFilter || ''; + $frames = self.$preview.find($h.FRAMES + cssFilter); + if (self.reversePreviewOrder) { + $frames = $($frames.get().reverse()); + } + return $frames; + }, + getPreview: function () { + var self = this; + return { + content: self.initialPreview, + config: self.initialPreviewConfig, + tags: self.initialPreviewThumbTags + }; + } + }; + + $.fn.fileinput = function (option) { + if (!$h.hasFileAPISupport() && !$h.isIE(9)) { + return; + } + var args = Array.apply(null, arguments), retvals = []; + args.shift(); + this.each(function () { + var self = $(this), data = self.data('fileinput'), options = typeof option === 'object' && option, + theme = options.theme || self.data('theme'), l = {}, t = {}, + lang = options.language || self.data('language') || $.fn.fileinput.defaults.language || 'en', opt; + if (!data) { + if (theme) { + t = $.fn.fileinputThemes[theme] || {}; + } + if (lang !== 'en' && !$h.isEmpty($.fn.fileinputLocales[lang])) { + l = $.fn.fileinputLocales[lang] || {}; + } + opt = $.extend(true, {}, $.fn.fileinput.defaults, t, $.fn.fileinputLocales.en, l, options, self.data()); + data = new FileInput(this, opt); + self.data('fileinput', data); + } + + if (typeof option === 'string') { + retvals.push(data[option].apply(data, args)); + } + }); + switch (retvals.length) { + case 0: + return this; + case 1: + return retvals[0]; + default: + return retvals; + } + }; + + var IFRAME_ATTRIBS = 'class="kv-preview-data file-preview-pdf" src="{renderer}?file={data}" {style}', + defBtnCss1 = 'btn btn-sm btn-kv ' + $h.defaultButtonCss(), defBtnCss2 = 'btn ' + $h.defaultButtonCss(true); + + $.fn.fileinput.defaults = { + language: 'zh', + bytesToKB: 1024, + showCaption: true, + showBrowse: true, + showPreview: true, + showRemove: true, + showUpload: true, + showUploadStats: true, + showCancel: null, + showPause: null, + showClose: true, + showUploadedThumbs: true, + showConsoleLogs: false, + browseOnZoneClick: false, + autoReplace: false, + showDescriptionClose: true, + autoOrientImage: function () { // applicable for JPEG images only and non ios safari + var ua = window.navigator.userAgent, webkit = !!ua.match(/WebKit/i), + iOS = !!ua.match(/iP(od|ad|hone)/i), iOSSafari = iOS && webkit && !ua.match(/CriOS/i); + return !iOSSafari; + }, + autoOrientImageInitial: true, + required: false, + rtl: false, + hideThumbnailContent: false, + encodeUrl: true, + focusCaptionOnBrowse: true, + focusCaptionOnClear: true, + generateFileId: null, + previewClass: '', + captionClass: '', + frameClass: 'krajee-default', + mainClass: '', + inputGroupClass: '', + mainTemplate: null, + fileSizeGetter: null, + initialCaption: '', + initialPreview: [], + initialPreviewDelimiter: '*$$*', + initialPreviewAsData: false, + initialPreviewFileType: 'image', + initialPreviewConfig: [], + initialPreviewThumbTags: [], + previewThumbTags: {}, + initialPreviewShowDelete: true, + initialPreviewDownloadUrl: '', + removeFromPreviewOnError: false, + deleteUrl: '', + deleteExtraData: {}, + overwriteInitial: true, + sanitizeZoomCache: function (content) { + var $container = $h.createElement(content); + $container.find('input,textarea,select,datalist,form,.file-thumbnail-footer').remove(); + return $container.html(); + }, + previewZoomButtonIcons: { + prev: '', + next: '', + toggleheader: '', + fullscreen: '', + borderless: '', + close: '' + }, + previewZoomButtonClasses: { + prev: 'btn btn-default btn-outline-secondary btn-navigate', + next: 'btn btn-default btn-outline-secondary btn-navigate', + toggleheader: defBtnCss1, + fullscreen: defBtnCss1, + borderless: defBtnCss1, + close: defBtnCss1 + }, + previewTemplates: {}, + previewContentTemplates: {}, + preferIconicPreview: false, + preferIconicZoomPreview: false, + allowedFileTypes: null, + allowedFileExtensions: null, + allowedPreviewTypes: undefined, + allowedPreviewMimeTypes: null, + allowedPreviewExtensions: null, + disabledPreviewTypes: undefined, + disabledPreviewExtensions: ['msi', 'exe', 'com', 'zip', 'rar', 'app', 'vb', 'scr'], + disabledPreviewMimeTypes: null, + defaultPreviewContent: null, + customLayoutTags: {}, + customPreviewTags: {}, + previewFileIcon: '', + previewFileIconClass: 'file-other-icon', + previewFileIconSettings: {}, + previewFileExtSettings: {}, + buttonLabelClass: 'hidden-xs', + browseIcon: ' ', + browseClass: 'btn btn-primary', + removeIcon: '', + removeClass: defBtnCss2, + cancelIcon: '', + cancelClass: defBtnCss2, + pauseIcon: '', + pauseClass: defBtnCss2, + uploadIcon: '', + uploadClass: defBtnCss2, + uploadUrl: null, + uploadUrlThumb: null, + uploadAsync: true, + uploadParamNames: { + chunkCount: 'chunkCount', + chunkIndex: 'chunkIndex', + chunkSize: 'chunkSize', + chunkSizeStart: 'chunkSizeStart', + chunksUploaded: 'chunksUploaded', + fileBlob: 'fileBlob', + fileId: 'fileId', + fileName: 'fileName', + fileRelativePath: 'fileRelativePath', + fileSize: 'fileSize', + retryCount: 'retryCount' + }, + maxAjaxThreads: 5, + fadeDelay: 800, + processDelay: 100, + bitrateUpdateDelay: 500, + queueDelay: 10, // must be lesser than process delay + progressDelay: 0, // must be lesser than process delay + enableResumableUpload: false, + resumableUploadOptions: { + fallback: null, + testUrl: null, // used for checking status of chunks/ files previously / partially uploaded + chunkSize: 2048, // in KB + maxThreads: 4, + maxRetries: 3, + showErrorLog: true, + retainErrorHistory: true, // display complete error history always unless user explicitly resets upload + skipErrorsAndProceed: false // when set to true, files with errors will be skipped and upload will continue with other files + }, + uploadExtraData: {}, + zoomModalHeight: 480, + minImageWidth: null, + minImageHeight: null, + maxImageWidth: null, + maxImageHeight: null, + resizeImage: false, + resizePreference: 'width', + resizeQuality: 0.92, + resizeDefaultImageType: 'image/jpeg', + resizeIfSizeMoreThan: 0, // in KB + minFileSize: -1, + maxFileSize: 0, + maxFilePreviewSize: 25600, // 25 MB + minFileCount: 0, + maxFileCount: 0, + maxTotalFileCount: 0, + validateInitialCount: false, + msgValidationErrorClass: 'text-danger', + msgValidationErrorIcon: ' ', + msgErrorClass: 'file-error-message', + progressThumbClass: 'progress-bar progress-bar-striped active progress-bar-animated', + progressClass: 'progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated', + progressInfoClass: 'progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated', + progressCompleteClass: 'progress-bar bg-success progress-bar-success', + progressPauseClass: 'progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated', + progressErrorClass: 'progress-bar bg-danger progress-bar-danger', + progressUploadThreshold: 99, + previewFileType: 'image', + elCaptionContainer: null, + elCaptionText: null, + elPreviewContainer: null, + elPreviewImage: null, + elPreviewStatus: null, + elErrorContainer: null, + errorCloseButton: undefined, + slugCallback: null, + dropZoneEnabled: true, + dropZoneTitleClass: 'file-drop-zone-title', + fileActionSettings: {}, + otherActionButtons: '', + textEncoding: 'UTF-8', + preProcessUpload: null, + ajaxSettings: {}, + ajaxDeleteSettings: {}, + showAjaxErrorDetails: true, + mergeAjaxCallbacks: false, + mergeAjaxDeleteCallbacks: false, + retryErrorUploads: true, + reversePreviewOrder: false, + usePdfRenderer: function () { + var isIE11 = !!window.MSInputMethodContext && !!document.documentMode; + return !!navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/i) || isIE11; + }, + pdfRendererUrl: '', + pdfRendererTemplate: '', + tabIndexConfig: { + browse: 500, + remove: 500, + upload: 500, + cancel: null, + pause: null, + modal: -1 + } + }; + + // noinspection HtmlUnknownAttribute + $.fn.fileinputLocales.en = { + sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], + bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'], + fileSingle: 'file', + filePlural: 'files', + browseLabel: 'Browse …', + removeLabel: 'Remove', + removeTitle: 'Clear all unprocessed files', + cancelLabel: 'Cancel', + cancelTitle: 'Abort ongoing upload', + pauseLabel: 'Pause', + pauseTitle: 'Pause ongoing upload', + uploadLabel: 'Upload', + uploadTitle: 'Upload selected files', + msgNo: 'No', + msgNoFilesSelected: 'No files selected', + msgCancelled: 'Cancelled', + msgPaused: 'Paused', + msgPlaceholder: 'Select {files} ...', + msgZoomModalHeading: 'Detailed Preview', + msgFileRequired: 'You must select a file to upload.', + msgSizeTooSmall: 'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.', + msgSizeTooLarge: 'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.', + msgFilesTooLess: 'You must select at least {n} {files} to upload.', + msgFilesTooMany: 'Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.', + msgTotalFilesTooMany: 'You can upload a maximum of {m} files ({n} files detected).', + msgFileNotFound: 'File "{name}" not found!', + msgFileSecured: 'Security restrictions prevent reading the file "{name}".', + msgFileNotReadable: 'File "{name}" is not readable.', + msgFilePreviewAborted: 'File preview aborted for "{name}".', + msgFilePreviewError: 'An error occurred while reading the file "{name}".', + msgInvalidFileName: 'Invalid or unsupported characters in file name "{name}".', + msgInvalidFileType: 'Invalid type for file "{name}". Only "{types}" files are supported.', + msgInvalidFileExtension: 'Invalid extension for file "{name}". Only "{extensions}" files are supported.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: 'The file upload was aborted', + msgUploadThreshold: 'Processing …', + msgUploadBegin: 'Initializing …', + msgUploadEnd: 'Done', + msgUploadResume: 'Resuming upload …', + msgUploadEmpty: 'No valid data available for upload.', + msgUploadError: 'Upload Error', + msgDeleteError: 'Delete Error', + msgProgressError: 'Error', + msgValidationError: 'Validation Error', + msgLoading: 'Loading file {index} of {files} …', + msgProgress: 'Loading file {index} of {files} - {name} - {percent}% completed.', + msgSelected: '{n} {files} selected', + msgProcessing: 'Processing ...', + msgFoldersNotAllowed: 'Drag & drop files only! {n} folder(s) dropped were skipped.', + msgImageWidthSmall: 'Width of image file "{name}" must be at least {size} px.', + msgImageHeightSmall: 'Height of image file "{name}" must be at least {size} px.', + msgImageWidthLarge: 'Width of image file "{name}" cannot exceed {size} px.', + msgImageHeightLarge: 'Height of image file "{name}" cannot exceed {size} px.', + msgImageResizeError: 'Could not get the image dimensions to resize.', + msgImageResizeException: 'Error while resizing the image.
    {errors}
    ', + msgAjaxError: 'Something went wrong with the {operation} operation. Please try again later!', + msgAjaxProgressError: '{operation} failed', + msgDuplicateFile: 'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.', + msgResumableUploadRetriesExceeded: 'Upload aborted beyond {max} retries for file {file}! Error Details:
    {error}
    ', + msgPendingTime: '{time} remaining', + msgCalculatingTime: 'calculating time remaining', + ajaxOperations: { + deleteThumb: 'file delete', + uploadThumb: 'file upload', + uploadBatch: 'batch file upload', + uploadExtra: 'form data upload' + }, + dropZoneTitle: 'Drag & drop files here …', + dropZoneClickTitle: '
    (or click to select {files})', + previewZoomButtonTitles: { + prev: 'View previous file', + next: 'View next file', + toggleheader: 'Toggle header', + fullscreen: 'Toggle full screen', + borderless: 'Toggle borderless mode', + close: 'Close detailed preview' + } + }; + + $.fn.fileinputLocales.zh = { + sizeUnits: ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], + bitRateUnits: ['B/s', 'KB/s', 'MB/s', 'GB/s', 'TB/s', 'PB/s', 'EB/s', 'ZB/s', 'YB/s'], + fileSingle: '文件', + filePlural: '个文件', + browseLabel: '选择 …', + removeLabel: '移除', + removeTitle: '清除选中文件', + cancelLabel: '取消', + cancelTitle: '取消进行中的上传', + pauseLabel: '暂停', + pauseTitle: '暂停上传', + uploadLabel: '上传', + uploadTitle: '上传选中文件', + msgNo: '没有', + msgNoFilesSelected: '未选择文件', + msgPaused: '已暂停', + msgCancelled: '取消', + msgPlaceholder: '选择 {files} ...', + msgZoomModalHeading: '详细预览', + msgFileRequired: '必须选择一个文件上传.', + msgSizeTooSmall: '文件 "{name}" ({size} KB) 必须大于限定大小 {minSize} KB.', + msgSizeTooLarge: '文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB.', + msgFilesTooLess: '你必须选择最少 {n} {files} 来上传. ', + msgFilesTooMany: '选择的上传文件个数 ({n}) 超出最大文件的限制个数 {m}.', + msgTotalFilesTooMany: '你最多可以上传 {m} 个文件 (当前有{n} 个文件).', + msgFileNotFound: '文件 "{name}" 未找到!', + msgFileSecured: '安全限制,为了防止读取文件 "{name}".', + msgFileNotReadable: '文件 "{name}" 不可读.', + msgFilePreviewAborted: '取消 "{name}" 的预览.', + msgFilePreviewError: '读取 "{name}" 时出现了一个错误.', + msgInvalidFileName: '文件名 "{name}" 包含非法字符.', + msgInvalidFileType: '不正确的类型 "{name}". 只支持 "{types}" 类型的文件.', + msgInvalidFileExtension: '不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.', + msgFileTypes: { + 'image': 'image', + 'html': 'HTML', + 'text': 'text', + 'video': 'video', + 'audio': 'audio', + 'flash': 'flash', + 'pdf': 'PDF', + 'object': 'object' + }, + msgUploadAborted: '该文件上传被中止', + msgUploadThreshold: '处理中 …', + msgUploadBegin: '正在初始化 …', + msgUploadEnd: '完成', + msgUploadResume: '继续上传 …', + msgUploadEmpty: '无效的文件上传.', + msgUploadError: '上传出错', + msgDeleteError: '删除出错', + msgProgressError: '上传出错', + msgValidationError: '验证错误', + msgLoading: '加载第 {index} 文件 共 {files} …', + msgProgress: '加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.', + msgSelected: '{n} {files} 选中', + msgProcessing: '处理中 ...', + msgFoldersNotAllowed: '只支持拖拽文件! 跳过 {n} 拖拽的文件夹.', + msgImageWidthSmall: '图像文件的"{name}"的宽度必须是至少{size}像素.', + msgImageHeightSmall: '图像文件的"{name}"的高度必须至少为{size}像素.', + msgImageWidthLarge: '图像文件"{name}"的宽度不能超过{size}像素.', + msgImageHeightLarge: '图像文件"{name}"的高度不能超过{size}像素.', + msgImageResizeError: '无法获取的图像尺寸调整。', + msgImageResizeException: '调整图像大小时发生错误。
    {errors}
    ', + msgAjaxError: '{operation} 发生错误. 请重试!', + msgAjaxProgressError: '{operation} 失败', + msgDuplicateFile: '文件 "{name}",大小 "{size} KB" 已经被选中.忽略相同的文件.', + msgResumableUploadRetriesExceeded: '文件 {file} 上传失败超过 {max} 次重试 ! 错误详情:
    {error}
    ', + msgPendingTime: '{time} 剩余', + msgCalculatingTime: '计算剩余时间', + ajaxOperations: { + deleteThumb: '删除文件', + uploadThumb: '上传文件', + uploadBatch: '批量上传', + uploadExtra: '表单数据上传' + }, + dropZoneTitle: '拖拽文件到这里 …
    支持多文件同时上传', + dropZoneClickTitle: '
    (或点击{files}按钮选择文件)', + fileActionSettings: { + removeTitle: '删除文件', + uploadTitle: '上传文件', + downloadTitle: '下载文件', + uploadRetryTitle: '重试', + zoomTitle: '查看详情', + dragTitle: '移动 / 重置', + indicatorNewTitle: '没有上传', + indicatorSuccessTitle: '上传', + indicatorErrorTitle: '上传错误', + indicatorPausedTitle: '上传已暂停', + indicatorLoadingTitle: '上传 …' + }, + previewZoomButtonTitles: { + prev: '预览上一个文件', + next: '预览下一个文件', + toggleheader: '缩放', + fullscreen: '全屏', + borderless: '无边界模式', + close: '关闭当前预览' + } + }; + + $.fn.fileinput.Constructor = FileInput; + + /** + * Convert automatically file inputs with class 'file' into a bootstrap fileinput control. + */ + $(document).ready(function () { + var $input = $('input.file[type=file]'); + if ($input.length) { + $input.fileinput(); + } + }); +})); diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css new file mode 100644 index 00000000..8865aec9 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.css @@ -0,0 +1,12 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Krajee default styling for bootstrap-fileinput. + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */.btn-file input[type=file],.file-caption-icon,.file-no-browse,.file-preview .fileinput-remove,.file-zoom-dialog .btn-navigate,.file-zoom-dialog .floating-buttons,.krajee-default .file-thumb-progress{position:absolute}.file-loading input[type=file],input[type=file].file-loading{width:0;height:0}.file-no-browse{left:50%;bottom:20%;width:1px;height:1px;font-size:0;opacity:0;border:none;background:0 0;outline:0;box-shadow:none}.file-caption-icon,.file-input-ajax-new .fileinput-remove-button,.file-input-ajax-new .fileinput-upload-button,.file-input-ajax-new .no-browse .input-group-btn,.file-input-new .close,.file-input-new .file-preview,.file-input-new .fileinput-remove-button,.file-input-new .fileinput-upload-button,.file-input-new .glyphicon-file,.file-input-new .no-browse .input-group-btn,.file-zoom-dialog .modal-header:after,.file-zoom-dialog .modal-header:before,.hide-content .kv-file-content,.is-locked .fileinput-remove-button,.is-locked .fileinput-upload-button,.kv-hidden{display:none}.file-caption-icon .kv-caption-icon{line-height:inherit}.btn-file,.file-caption,.file-input,.file-loading:before,.file-preview,.file-zoom-dialog .modal-dialog,.krajee-default .file-thumbnail-footer,.krajee-default.file-preview-frame{position:relative}.file-error-message pre,.file-error-message ul,.krajee-default .file-actions,.krajee-default .file-other-error{text-align:left}.file-error-message pre,.file-error-message ul{margin:0}.krajee-default .file-drag-handle,.krajee-default .file-upload-indicator{float:left;margin-top:10px;width:16px;height:16px}.file-thumb-progress .progress,.file-thumb-progress .progress-bar{font-family:Verdana,Helvetica,sans-serif;font-size:.7rem}.krajee-default .file-thumb-progress .progress,.kv-upload-progress .progress{background-color:#ccc}.krajee-default .file-caption-info,.krajee-default .file-size-info{display:block;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:160px;height:15px;margin:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-image,.file-zoom-content>.file-object.type-video{max-width:100%;max-height:100%;width:auto}.file-zoom-content>.file-object.type-flash,.file-zoom-content>.file-object.type-video{height:100%}.file-zoom-content>.file-object.type-default,.file-zoom-content>.file-object.type-html,.file-zoom-content>.file-object.type-pdf,.file-zoom-content>.file-object.type-text{width:100%}.file-loading:before{content:" Loading...";display:inline-block;padding-left:20px;line-height:16px;font-size:13px;font-variant:small-caps;color:#999;background:url(loading.gif) top left no-repeat}.file-object{margin:0 0 -5px;padding:0}.btn-file{overflow:hidden}.btn-file input[type=file]{top:0;left:0;min-width:100%;min-height:100%;text-align:right;opacity:0;background:none;cursor:inherit;display:block}.btn-file ::-ms-browse{font-size:10000px;width:100%;height:100%}.file-caption.icon-visible .file-caption-icon{display:inline-block}.file-caption.icon-visible .file-caption-name{padding-left:25px;}.file-caption.icon-visible>.input-group-lg .file-caption-name{padding-left:30px;}.file-caption.icon-visible>.input-group-sm .file-caption-name{padding-left:22px;}.file-caption-name:not(.file-caption-disabled){background-color:transparent}.file-caption-name.file-processing{font-style:italic;border-color:#bbb;opacity:.5}.file-caption-icon{padding:7px 5px;left:4px}.input-group-lg .file-caption-icon{font-size:1.25rem}.input-group-sm .file-caption-icon{font-size:.875rem;padding:.25rem}.file-error-message{color:#a94442;background-color:#f2dede;margin:5px;border:1px solid #ebccd1;border-radius:4px;padding:15px}.file-error-message pre{margin:5px 0}.file-caption-disabled{background-color:#eee;cursor:not-allowed;opacity:1}.file-preview{border-radius:5px;border:1px solid #ddd;padding:8px;width:100%;margin-bottom:5px}.file-preview .btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.file-preview .fileinput-remove{top:1px;right:1px;line-height:10px}.file-preview .clickable{cursor:pointer}.file-preview-image{font:40px Impact,Charcoal,sans-serif;color:green;width:auto;height:auto;max-width:100%;max-height:100%}.krajee-default.file-preview-frame{margin:8px;border:1px solid rgba(0,0,0,.2);box-shadow:0 0 10px 0 rgba(0,0,0,.2);padding:6px;float:left;text-align:center}.krajee-default.file-preview-frame .kv-file-content{width:213px;height:160px}.krajee-default .file-preview-other-frame{display:flex;align-items:center;justify-content:center}.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:400px}.krajee-default.file-preview-frame[data-template=audio] .kv-file-content{width:240px;height:55px}.krajee-default.file-preview-frame .file-thumbnail-footer{height:70px}.krajee-default.file-preview-frame:not(.file-preview-error):hover{border:1px solid rgba(0,0,0,.3);box-shadow:0 0 10px 0 rgba(0,0,0,.4)}.krajee-default .file-preview-text{color:#428bca;border:1px solid #ddd;outline:0;resize:none}.krajee-default .file-preview-html{border:1px solid #ddd}.krajee-default .file-other-icon{font-size:6em;line-height:1}.krajee-default .file-footer-buttons{float:right}.krajee-default .file-footer-caption{display:block;text-align:center;padding-top:4px;font-size:11px;color:#777;margin-bottom:30px}.file-upload-stats{font-size:10px;text-align:center;width:100%}.kv-upload-progress .file-upload-stats{font-size:12px;margin:-10px 0 5px}.krajee-default .file-preview-error{opacity:.65;box-shadow:none}.krajee-default .file-thumb-progress{top:37px;left:0;right:0}.krajee-default.kvsortable-ghost{background:#e1edf7;border:2px solid #a1abff}.krajee-default .file-preview-other:hover{opacity:.8}.krajee-default .file-preview-frame:not(.file-preview-error) .file-footer-caption:hover{color:#000}.kv-upload-progress .progress{height:20px;margin:10px 0;overflow:hidden}.kv-upload-progress .progress-bar{height:20px;font-family:Verdana,Helvetica,sans-serif}.file-zoom-dialog .file-other-icon{font-size:22em;font-size:50vmin}.file-zoom-dialog .modal-dialog{width:auto}.file-zoom-dialog .modal-header{display:flex;align-items:center;justify-content:space-between}.file-zoom-dialog .btn-navigate{margin:0 .1rem;padding:0;font-size:1.2rem;width:2.4rem;height:2.4rem;top:50%;border-radius:50%;text-align:center}.btn-navigate *{width:auto}.file-zoom-dialog .floating-buttons{top:5px;right:10px}.file-zoom-dialog .btn-kv-prev{left:0}.file-zoom-dialog .btn-kv-next{right:0}.file-zoom-dialog .kv-zoom-caption{max-width:50%;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.file-zoom-dialog .kv-zoom-header{padding:.5rem}.file-zoom-dialog .kv-zoom-body{padding:.25rem .5rem .25rem 0}.file-zoom-dialog .kv-zoom-description{position:absolute;opacity:.8;font-size:.8rem;background-color:#1a1a1a;padding:1rem;text-align:center;border-radius:.5rem;color:#fff;left:15%;right:15%;bottom:15%}.file-zoom-dialog .kv-desc-hide{float:right;color:#fff;padding:0 .1rem;background:0 0;border:none}.file-zoom-dialog .kv-desc-hide:hover{opacity:.7}.file-zoom-dialog .kv-desc-hide:focus{opacity:.9}.file-input-ajax-new .no-browse .form-control,.file-input-new .no-browse .form-control{border-top-right-radius:4px;border-bottom-right-radius:4px}.file-caption{width:100%;position:relative}.file-thumb-loading{background:url(loading.gif) center center no-repeat content-box!important}.file-drop-zone{border:1px dashed #aaa;min-height:260px;border-radius:4px;text-align:center;vertical-align:middle;margin:12px 15px 12px 12px;padding:5px}.file-drop-zone.clickable:hover{border:2px dashed #999}.file-drop-zone.clickable:focus{border:2px solid #5acde2}.file-drop-zone .file-preview-thumbnails{cursor:default}.file-drop-zone-title{color:#aaa;font-size:1.6em;text-align:center;padding:85px 10px;cursor:default}.file-highlighted{border:2px dashed #999!important;background-color:#eee}.file-uploading{background:url(loading-sm.gif) center bottom 10px no-repeat;opacity:.65}.file-zoom-fullscreen .modal-dialog{min-width:100%;margin:0}.file-zoom-fullscreen .modal-content{border-radius:0;box-shadow:none;min-height:100vh}.file-zoom-fullscreen .kv-zoom-body{overflow-y:auto}.floating-buttons{z-index:3000}.floating-buttons .btn-kv{margin-left:3px;z-index:3000}.kv-zoom-actions .btn-kv{margin-left:3px}.file-zoom-content{text-align:center;white-space:nowrap;min-height:300px}.file-zoom-content:hover{background:0 0}.file-zoom-content>*{display:inline-block;vertical-align:middle}.file-zoom-content .kv-spacer{height:100%}.file-zoom-content .file-preview-image,.file-zoom-content .file-preview-video{max-height:100%}.file-zoom-content>.file-object.type-image{height:auto;min-height:inherit}.file-zoom-content>.file-object.type-audio{width:auto;height:30px}@media (min-width:576px){.file-zoom-dialog .modal-dialog{max-width:500px}}@media (min-width:992px){.file-zoom-dialog .modal-lg{max-width:800px}}@media (max-width:767px){.file-preview-thumbnails{display:flex;justify-content:center;align-items:center;flex-direction:column}.file-zoom-dialog .modal-header{flex-direction:column}}@media (max-width:350px){.krajee-default.file-preview-frame:not([data-template=audio]) .kv-file-content{width:160px}}@media (max-width:420px){.krajee-default.file-preview-frame .kv-file-content.kv-pdf-rendered{width:100%}}.file-loading[dir=rtl]:before{background:url(loading.gif) top right no-repeat;padding-left:0;padding-right:20px}.clickable .file-drop-zone-title{cursor:pointer}.file-sortable .file-drag-handle:hover{opacity:.7}.file-sortable .file-drag-handle{cursor:grab;opacity:1}.file-grabbing,.file-grabbing *{cursor:not-allowed!important}.file-grabbing .file-preview-thumbnails *{cursor:grabbing!important}.file-preview-frame.sortable-chosen{background-color:#d9edf7;border-color:#17a2b8;box-shadow:none!important}.file-preview .kv-zoom-cache{display:none} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js new file mode 100644 index 00000000..c6c1d2d9 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/fileinput.min.js @@ -0,0 +1,11 @@ +/*! + * bootstrap-fileinput v5.2.4 + * http://plugins.krajee.com/file-input + * + * Author: Kartik Visweswaran + * Copyright: 2014 - 2021, Kartik Visweswaran, Krajee.com + * + * Licensed under the BSD-3-Clause + * https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md + */ +!function(e){"use strict";"function"==typeof define&&define.amd?define(["jquery"],e):"object"==typeof module&&module.exports?module.exports=e(require("jquery")):e(window.jQuery)}(function(L){"use strict";L.fn.fileinputLocales={},L.fn.fileinputThemes={},L.fn.fileinputBsVersion||(L.fn.fileinputBsVersion=window.Alert&&window.Alert.VERSION||window.bootstrap&&window.bootstrap.Alert&&bootstrap.Alert.VERSION||"3.x.x"),String.prototype.setTokens=function(e){var t,i,a=this.toString();for(t in e)e.hasOwnProperty(t)&&(i=new RegExp("{"+t+"}","g"),a=a.replace(i,e[t]));return a},Array.prototype.flatMap||(Array.prototype.flatMap=function(e){return[].concat(this.map(e))}),document.currentScript||(document.currentScript=(i=document.getElementsByTagName("script"))[i.length-1]);var e,N={FRAMES:".kv-preview-thumb",SORT_CSS:"file-sortable",INIT_FLAG:"init-",ZOOM_VAR:(e=document.currentScript.src).substring(0,e.lastIndexOf("/"))+"/loading.gif?kvTemp__2873389129__=",OBJECT_PARAMS:'\n\n\n\n\n\n',DEFAULT_PREVIEW:'
    \n{previewFileIcon}\n
    ',MODAL_ID:"kvFileinputModal",MODAL_EVENTS:["show","shown","hide","hidden","loaded"],logMessages:{ajaxError:"{status}: {error}. Error Details: {text}.",badDroppedFiles:"Error scanning dropped files!",badExifParser:"Error loading the piexif.js library. {details}",badInputType:'The input "type" must be set to "file" for initializing the "bootstrap-fileinput" plugin.',exifWarning:'To avoid this warning, either set "autoOrientImage" to "false" OR ensure you have loaded the "piexif.js" library correctly on your page before the "fileinput.js" script.',invalidChunkSize:'Invalid upload chunk size: "{chunkSize}". Resumable uploads are disabled.',invalidThumb:'Invalid thumb frame with id: "{id}".',noResumableSupport:"The browser does not support resumable or chunk uploads.",noUploadUrl:'The "uploadUrl" is not set. Ajax uploads and resumable uploads have been disabled.',retryStatus:"Retrying upload for chunk # {chunk} for {filename}... retry # {retry}.",chunkQueueError:"Could not push task to ajax pool for chunk index # {index}.",resumableMaxRetriesReached:"Maximum resumable ajax retries ({n}) reached.",resumableRetryError:"Could not retry the resumable request (try # {n})... aborting.",resumableAborting:"Aborting / cancelling the resumable request.",resumableRequestError:"Error processing resumable request. {msg}"},objUrl:window.URL||window.webkitURL,isBs:function(e){var t=L.trim((L.fn.fileinputBsVersion||"")+"");return e=parseInt(e,10),t?e===parseInt(t.charAt(0),10):4===e},defaultButtonCss:function(e){return"btn-default btn-"+(e?"":"outline-")+"secondary"},now:function(){return(new Date).getTime()},round:function(e){return e=parseFloat(e),isNaN(e)?0:Math.floor(Math.round(e))},getArray:function(e){for(var t=[],i=e&&e.length||0,a=0;a >4){case 0:case 1:case 2:case 3:case 4:case 5:case 6:case 7:n+=String.fromCharCode(t);break;case 12:case 13:i=r[o++],n+=String.fromCharCode((31&t)<<6|63&i);break;case 14:i=r[o++],a=r[o++],n+=String.fromCharCode((15&t)<<12|(63&i)<<6|(63&a)<<0)}return n},isHtml:function(e){var t=document.createElement("div");t.innerHTML=e;for(var i=t.childNodes,a=i.length;a--;)if(1===i[a].nodeType)return!0;return!1},isSvg:function(e){return e.match(/^\s*<\?xml/i)&&(e.match(/"+e+""))},uniqId:function(){return((new Date).getTime()+Math.floor(Math.random()*Math.pow(10,15))).toString(36)},cspBuffer:{CSP_ATTRIB:"data-csp-01928735",domElementsStyles:{},stash:function(e){var n=this,t=L.parseHTML("
    "+e+"
    "),e=L(t);return e.find("[style]").each(function(e,t){var i=L(t),a=i[0].style,t=N.uniqId(),r={};a&&a.length&&(L(a).each(function(){r[this]=a[this]}),n.domElementsStyles[t]=r,i.removeAttr("style").attr(n.CSP_ATTRIB,t))}),e.filter("*").removeAttr("style"),(Object.values?Object.values(t):Object.keys(t).map(function(e){return t[e]})).flatMap(function(e){return e.innerHTML}).join("")},apply:function(e){var a=this;L(e).find("["+a.CSP_ATTRIB+"]").each(function(e,t){var i=L(t),t=i.attr(a.CSP_ATTRIB),t=a.domElementsStyles[t];t&&i.css(t),i.removeAttr(a.CSP_ATTRIB)}),a.domElementsStyles={}}},setHtml:function(e,t){var i=N.cspBuffer;return e.html(i.stash(t)),i.apply(e),e},htmlEncode:function(e,t){return void 0===e?t||null:e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},replaceTags:function(e,t){var i=e;return t&&L.each(t,function(e,t){"function"==typeof t&&(t=t()),i=i.split(e).join(t)}),i},cleanMemory:function(e){e=(e.is("img")?e:e.find("source")).attr("src");N.revokeObjectURL(e)},findFileName:function(e){var t=e.lastIndexOf("/");return-1===t&&(t=e.lastIndexOf("\\")),e.split(e.substring(t,t+1)).pop()},checkFullScreen:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement||document.msFullscreenElement},toggleFullScreen:function(e){var t=document,i=t.documentElement,a=N.checkFullScreen();i&&e&&!a?i.requestFullscreen?i.requestFullscreen():i.msRequestFullscreen?i.msRequestFullscreen():i.mozRequestFullScreen?i.mozRequestFullScreen():i.webkitRequestFullscreen&&i.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT):a&&(t.exitFullscreen?t.exitFullscreen():t.msExitFullscreen?t.msExitFullscreen():t.mozCancelFullScreen?t.mozCancelFullScreen():t.webkitExitFullscreen&&t.webkitExitFullscreen())},moveArray:function(e,t,i,a){var r=L.extend(!0,[],e);if(a&&r.reverse(),i>=r.length)for(var n=i-r.length;1+n--;)r.push(void 0);return r.splice(i,0,r.splice(t,1)[0]),a&&r.reverse(),r},closeButton:function(e){return'"},getRotation:function(e){switch(e){case 2:return"rotateY(180deg)";case 3:return"rotate(180deg)";case 4:return"rotate(180deg) rotateY(180deg)";case 5:return"rotate(270deg) rotateY(180deg)";case 6:return"rotate(90deg)";case 7:return"rotate(90deg) rotateY(180deg)";case 8:return"rotate(270deg)";default:return""}},setTransform:function(e,t){e&&(e.style.transform=t,e.style.webkitTransform=t,e.style["-moz-transform"]=t,e.style["-ms-transform"]=t,e.style["-o-transform"]=t)},getObjectKeys:function(e){var t=[];return e&&L.each(e,function(e){t.push(e)}),t},getObjectSize:function(e){return N.getObjectKeys(e).length},whenAll:function(e){for(var t,i,a,r=[].slice,n=1===arguments.length&&N.isArray(e)?e:r.call(arguments),o=L.Deferred(),s=0,l=n.length,d=l,c=i=a=Array(l),u=function(e,t,i){return function(){i!==n&&s++,o.notifyWith(t[e]=this,i[e]=r.call(arguments)),--d||o[(s?"reject":"resolve")+"With"](t,i)}},p=0;pg.file.size?g.file.size:e},getTotalChunks:function(){var e=parseFloat(g.chunkSize);return!isNaN(e)&&0h.maxRetries)return s(d.resumableMaxRetriesReached,{n:h.maxRetries}),void g.setProcessed("error");var c,u=t[t.slice?"slice":t.mozSlice?"mozSlice":t.webkitSlice?"webkitSlice":"slice"](e*r,e*(r+1)),p=new FormData,f=w.stack[l];m._setUploadData(p,{chunkCount:g.chunkCount,chunkIndex:r,chunkSize:e,chunkSizeStart:e*r,fileBlob:[u,g.fileName],fileId:l,fileName:g.fileName,fileRelativePath:f.relativePath,fileSize:t.size,retryCount:n}),g.$progress&&g.$progress.length&&g.$progress.show(),e=function(e){c=m._getOutData(p,e),m.showPreview&&(i.hasClass("file-preview-success")||(m._setThumbStatus(i,"Loading"),N.addCss(i,"file-uploading")),a.attr("disabled",!0)),m._raise("filechunkbeforesend",[l,r,n,w,g,c])},u=function(e,t,i){var a;m._isAborted()?s(d.resumableAborting):(c=m._getOutData(p,i,e),a=m.uploadParamNames.chunkIndex||"chunkIndex",i=[l,r,n,w,g,c],e.error?(h.showErrorLog&&m._log(v.retryStatus,{retry:n+1,filename:g.fileName,chunk:r}),m._raise("filechunkerror",i),g.pushAjax(r,n+1),g.error=e.error,s(e.error)):(g.logs[e[a]]=!0,g.chunksProcessed[l]||(g.chunksProcessed[l]={}),g.chunksProcessed[l][e[a]]=!0,g.chunksProcessed[l].data=e,o.resolve.call(null,e),m._raise("filechunksuccess",i),g.check()))},f=function(e,t,i){m._isAborted()?s(d.resumableAborting):(c=m._getOutData(p,e),g.setAjaxError(e,t,i),m._raise("filechunkajaxerror",[l,r,n,w,g,c]),g.pushAjax(r,n+1),s(d.resumableRetryError,{n:n-1}))},t=function(){m._isAborted()||m._raise("filechunkcomplete",[l,r,n,w,g,m._getOutData(p)])},m._ajaxSubmit(e,u,t,f,p,l,g.fileIndex)}}}).reset());h.fallback(m)}},_initTemplateDefaults:function(){var i=this,e=function(e,t){return'\n"+N.DEFAULT_PREVIEW+"\n\n"},t="btn btn-sm btn-kv "+N.defaultButtonCss(),a='{preview}\n
    \n
    \n
    \n {caption}\n\n'+(N.isBs(5)?"":'
    \n')+" {remove}\n {cancel}\n {pause}\n {upload}\n {browse}\n"+(N.isBs(5)?"":"
    \n")+"
    ",r=N.closeButton("fileinput-remove"),n=N.MODAL_ID+"Label",o='',s='\n',l=" {style}",d=e("html","text/html"),c=e("text","text/plain;charset=UTF-8"),u=e("pdf","application/pdf"),p='{alt}\n",f='",g='",m='\n",h='\x3c!--suppress ALL --\x3e\n",v='\n",n='\n\n'+N.OBJECT_PARAMS+" "+N.DEFAULT_PREVIEW+"\n\n",w='
    \n"+N.DEFAULT_PREVIEW+"\n
    \n",e={width:"100%",height:"100%","min-height":"480px"};i._isPdfRendered()&&(u=i.pdfRendererTemplate.replace("{renderer}",i._encodeURI(i.pdfRendererUrl))),i.defaults={layoutTemplates:{main1:a,main2:'{preview}\n
    \n
    \n{remove}\n{cancel}\n{upload}\n{browse}\n',preview:'
    \n {close}
    \n
    \n
    \n
    \n
    \n
    \n
    ',close:r,fileIcon:'',caption:'\n',modalMain:o,modal:s,descriptionClose:'',progress:'
    \n
    \n {status}\n
    \n
    {stats}',stats:'
    {pendingTime} {uploadSpeed}
    ',size:" ({sizeText})",footer:'',indicator:'
    {indicator}
    ',actions:'
    \n \n
    \n{drag}\n
    ',actionDelete:'\n',actionUpload:'',actionDownload:'{downloadIcon}',actionZoom:'',actionDrag:'{dragIcon}',btnDefault:'',btnLink:'{icon} {label}',btnBrowse:'
    {icon} {label}
    ',zoomCache:'
    {zoomContent}
    '},previewMarkupTags:{tagBefore1:'
    \n',tagBefore2:'
    \n',tagAfter:"
    {footer}\n{zoomCache}
    \n"},previewContentTemplates:{generic:"{content}\n",html:d,image:p,text:c,office:f,gdocs:g,video:m,audio:h,flash:v,object:n,pdf:u,other:w},allowedPreviewTypes:["image","html","text","video","audio","flash","pdf","object"],previewTemplates:{},previewSettings:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:{width:"213px",height:"160px"},text:{width:"213px",height:"160px"},office:{width:"213px",height:"160px"},gdocs:{width:"213px",height:"160px"},video:{width:"213px",height:"160px"},audio:{width:"100%",height:"30px"},flash:{width:"213px",height:"160px"},object:{width:"213px",height:"160px"},pdf:{width:"100%",height:"160px",position:"relative"},other:{width:"213px",height:"160px"}},previewSettingsSmall:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:{width:"100%",height:"160px"},text:{width:"100%",height:"160px"},office:{width:"100%",height:"160px"},gdocs:{width:"100%",height:"160px"},video:{width:"100%",height:"auto"},audio:{width:"100%",height:"30px"},flash:{width:"100%",height:"auto"},object:{width:"100%",height:"auto"},pdf:{width:"100%",height:"160px"},other:{width:"100%",height:"160px"}},previewZoomSettings:{image:{width:"auto",height:"auto","max-width":"100%","max-height":"100%"},html:e,text:e,office:{width:"100%",height:"100%","max-width":"100%","min-height":"480px"},gdocs:{width:"100%",height:"100%","max-width":"100%","min-height":"480px"},video:{width:"auto",height:"100%","max-width":"100%"},audio:{width:"100%",height:"30px"},flash:{width:"auto",height:"480px"},object:{width:"auto",height:"100%","max-width":"100%","min-height":"480px"},pdf:e,other:{width:"auto",height:"100%","min-height":"480px"}},mimeTypeAliases:{"video/quicktime":"video/mp4"},fileTypeSettings:{image:function(e,t){return N.compare(e,"image.*")&&!N.compare(e,/(tiff?|wmf)$/i)||N.compare(t,/\.(gif|png|jpe?g)$/i)},html:function(e,t){return N.compare(e,"text/html")||N.compare(t,/\.(htm|html)$/i)},office:function(e,t){return N.compare(e,/(word|excel|powerpoint|office)$/i)||N.compare(t,/\.(docx?|xlsx?|pptx?|pps|potx?)$/i)},gdocs:function(e,t){return N.compare(e,/(word|excel|powerpoint|office|iwork-pages|tiff?)$/i)||N.compare(t,/\.(docx?|xlsx?|pptx?|pps|potx?|rtf|ods|odt|pages|ai|dxf|ttf|tiff?|wmf|e?ps)$/i)},text:function(e,t){return N.compare(e,"text.*")||N.compare(t,/\.(xml|javascript)$/i)||N.compare(t,/\.(txt|md|nfo|ini|json|php|js|css)$/i)},video:function(e,t){return N.compare(e,"video.*")&&(N.compare(e,/(ogg|mp4|mp?g|mov|webm|3gp)$/i)||N.compare(t,/\.(og?|mp4|webm|mp?g|mov|3gp)$/i))},audio:function(e,t){return N.compare(e,"audio.*")&&(N.compare(t,/(ogg|mp3|mp?g|wav)$/i)||N.compare(t,/\.(og?|mp3|mp?g|wav)$/i))},flash:function(e,t){return N.compare(e,"application/x-shockwave-flash",!0)||N.compare(t,/\.(swf)$/i)},pdf:function(e,t){return N.compare(e,"application/pdf",!0)||N.compare(t,/\.(pdf)$/i)},object:function(){return!0},other:function(){return!0}},fileActionSettings:{showRemove:!0,showUpload:!0,showDownload:!0,showZoom:!0,showDrag:!0,removeIcon:'',removeClass:t,removeErrorClass:"btn btn-sm btn-kv btn-danger",removeTitle:"Remove file",uploadIcon:'',uploadClass:t,uploadTitle:"Upload file",uploadRetryIcon:'',uploadRetryTitle:"Retry upload",downloadIcon:'',downloadClass:t,downloadTitle:"Download file",zoomIcon:'',zoomClass:t,zoomTitle:"View Details",dragIcon:'',dragClass:"text-primary",dragTitle:"Move / Rearrange",dragSettings:{},indicatorNew:'',indicatorSuccess:'',indicatorError:'',indicatorLoading:'',indicatorPaused:'',indicatorNewTitle:"Not uploaded yet",indicatorSuccessTitle:"Uploaded",indicatorErrorTitle:"Upload Error",indicatorLoadingTitle:"Uploading …",indicatorPausedTitle:"Upload Paused"}},L.each(i.defaults,function(e,t){"allowedPreviewTypes"!==e?i[e]=L.extend(!0,{},t,i[e]):void 0===i.allowedPreviewTypes&&(i.allowedPreviewTypes=t)}),i._initPreviewTemplates()},_initPreviewTemplates:function(){var i,a=this,r=a.previewMarkupTags,n=r.tagAfter;L.each(a.previewContentTemplates,function(e,t){N.isEmpty(a.previewTemplates[e])&&(i=r.tagBefore2,"generic"!==e&&"image"!==e||(i=r.tagBefore1),a._isPdfRendered()&&"pdf"===e&&(i=i.replace("kv-file-content","kv-file-content kv-pdf-rendered")),a.previewTemplates[e]=i+t+n)})},_initPreviewCache:function(){var f=this;f.previewCache={data:{},init:function(){var e=f.initialPreview;0'+e+"":"
  • "+e+"
  • ";return 0===r.find("ul").length?a._addError("
      "+i+"
    "):r.find("ul").append(i),r.fadeIn(a.fadeDelay),a._raise(n,[t,e]),a._setValidationError("file-input-new"),!0},_showError:function(e,t,i){var a=this,r=a.$errorContainer,i=i||"fileerror";return(t=t||{}).reader=a.reader,a._addError(e),r.fadeIn(a.fadeDelay),a._raise(i,[t,e]),a.isAjaxUpload||a._clearFileInput(),a._setValidationError("file-input-new"),a.$btnUpload.attr("disabled",!0),!0},_noFilesError:function(e){var t=this,i=1"+a+"";0===i.find("ul").length?t._addError("
      "+a+"
    "):i.find("ul").append(a),t.isError=!0,t._updateFileDetails(0),i.fadeIn(t.fadeDelay),t._raise("fileerror",[e,a]),t._clearFileInput(),t._setValidationError()},_parseError:function(e,t,i,a){var r=this,n=L.trim(i+""),i=t.responseJSON&&t.responseJSON.error?t.responseJSON.error.toString():"",t=i||t.responseText;return r.cancelling&&r.msgUploadAborted&&(n=r.msgUploadAborted),r.showAjaxErrorDetails&&t&&(i?n=L.trim(i+""):(i=(t=L.trim(t.replace(/\n\s*\n/g,"\n"))).length?"
    "+t+"
    ":"",n+=n?i:t)),n=n||r.msgAjaxError.replace("{operation}",e),r.cancelling=!1,a?""+a+": "+n:n},_parseFileType:function(e,t){var i,a,r=this.allowedPreviewTypes||[];if("application/text-plain"===e)return"text";for(a=0;a.kv-file-content img"),t=r._getZoom(t," >.kv-file-content img"),o?e.css("image-orientation",r.autoOrientImageInitial?"from-image":"none"):r.setImageOrientation(e,t,a.exif.Orientation,i)),n++})},_initPreview:function(e){var t,i=this,a=i.initialCaption||"";if(!i.previewCache.count(!0))return i._clearPreview(),void(e?i._setCaption(a):i._initCaption());t=i.previewCache.out(),a=e&&i.initialCaption?i.initialCaption:t.caption,i._setPreviewContent(t.content),i._setInitThumbAttr(),i._setCaption(a),i._initSortable(),N.isEmpty(t.content)||i.$container.removeClass("file-input-new"),i._initPreviewImageOrientations()},_getZoomButton:function(e){var t=this.previewZoomButtonIcons[e],i=this.previewZoomButtonClasses[e],a=' title="'+(this.previewZoomButtonTitles[e]||"")+'" ',r=N.isBs(5)?"bs-":"",r=a+("close"===e?" data-"+r+'dismiss="modal" aria-hidden="true"':"");return"fullscreen"!==e&&"borderless"!==e&&"toggleheader"!==e||(r+=' data-toggle="button" aria-pressed="false" autocomplete="off"'),'"},_getModalContent:function(){var e=this;return e._getLayoutTemplate("modal").setTokens({rtl:e.rtl?" kv-rtl":"",zoomFrameClass:e.frameClass,prev:e._getZoomButton("prev"),next:e._getZoomButton("next"),toggleheader:e._getZoomButton("toggleheader"),fullscreen:e._getZoomButton("fullscreen"),borderless:e._getZoomButton("borderless"),close:e._getZoomButton("close")})},_listenModalEvent:function(a){var r=this,n=r.$modal;n.on(a+".bs.modal",function(e){var t,i;"bs.modal"===e.namespace&&(t=n.find(".btn-fullscreen"),i=n.find(".btn-borderless"),n.data("fileinputPluginId")===r.$element.attr("id")&&r._raise("filezoom"+a,{sourceEvent:e,previewId:n.data("previewId"),modal:n}),"shown"===a&&(i.removeClass("active").attr("aria-pressed","false"),t.removeClass("active").attr("aria-pressed","false"),n.hasClass("file-zoom-fullscreen")&&(r._maximizeZoomDialog(),(N.checkFullScreen()?t:i).addClass("active").attr("aria-pressed","true"))))})},_initZoom:function(){var i=this,e=i._getLayoutTemplate("modalMain"),t="#"+N.MODAL_ID,e=i._setTabIndex("modal",e);i.showPreview&&(i.$modal=L(t),i.$modal&&i.$modal.length||(e=N.createElement(N.cspBuffer.stash(e)).insertAfter(i.$container),i.$modal=L(t).insertBefore(e),N.cspBuffer.apply(i.$modal),e.remove()),N.initModal(i.$modal),i.$modal.html(N.cspBuffer.stash(i._getModalContent())),N.cspBuffer.apply(i.$modal),L.each(N.MODAL_EVENTS,function(e,t){i._listenModalEvent(t)}))},_initZoomButtons:function(){var e,t=this,i=t.$modal.data("previewId")||"",a=t.getFrames().toArray(),r=a.length,n=t.$modal.find(".btn-kv-prev"),o=t.$modal.find(".btn-kv-next");if(a.length<2)return n.hide(),void o.hide();n.show(),o.show(),r&&(e=L(a[0]),r=L(a[r-1]),n.removeAttr("disabled"),o.removeAttr("disabled"),t.reversePreviewOrder&&([n,o]=[o,n]),e.length&&e.attr("id")===i&&n.attr("disabled",!0),r.length&&r.attr("id")===i&&o.attr("disabled",!0))},_maximizeZoomDialog:function(){var e=this.$modal,t=e.find(".modal-header:visible"),i=e.find(".modal-footer:visible"),a=e.find(".kv-zoom-body"),r=L(window).height();e.addClass("file-zoom-fullscreen"),t&&t.length&&(r-=t.outerHeight(!0)),i&&i.length&&(r-=i.outerHeight(!0)),a&&a.length&&(r-=a.outerHeight(!0)-a.height()),e.find(".kv-zoom-body").height(r)},_resizeZoomDialog:function(e){var t=this,i=t.$modal,a=i.find(".btn-kv-fullscreen"),r=i.find(".btn-kv-borderless");if(i.hasClass("file-zoom-fullscreen"))N.toggleFullScreen(!1),e?a.hasClass("active")||(i.removeClass("file-zoom-fullscreen"),t._resizeZoomDialog(!0),r.hasClass("active")&&r.removeClass("active").attr("aria-pressed","false")):a.hasClass("active")?a.removeClass("active").attr("aria-pressed","false"):(i.removeClass("file-zoom-fullscreen"),t.$modal.find(".kv-zoom-body").css("height",t.zoomModalHeight));else{if(!e)return void t._maximizeZoomDialog();N.toggleFullScreen(!0)}i.focus()},_setZoomContent:function(e,t){var i,a,r,n,o,s=this,l=e.attr("id"),d=s._getZoom(l),c=s.$modal,u=c.find(".btn-kv-fullscreen"),p=c.find(".btn-kv-borderless"),f=c.find(".btn-kv-toggleheader"),g=e.data("zoom");g&&(g=decodeURIComponent(g),o=d.html().replace(N.ZOOM_VAR,"").setTokens({zoomData:g}),d.html(o),e.data("zoom",""),d.attr("data-zoom",g)),n=d.attr("data-template")||"generic",g=(o=d.find(".kv-file-content")).length?'\n'+o.html():"",d=e.data("caption")||s.msgZoomModalHeading,o=e.data("size")||"",e=e.data("description")||"",c.find(".kv-zoom-caption").attr("title",d).html(d),c.find(".kv-zoom-size").html(o),o=c.find(".kv-zoom-description").hide(),e&&(s.showDescriptionClose&&(e=s._getLayoutTemplate("descriptionClose").setTokens({closeIcon:s.previewZoomButtonIcons.close})+""+e),o.show().html(e),s.showDescriptionClose&&s._handler(c.find(".kv-desc-hide"),"click",function(){L(this).parent().fadeOut("fast",function(){c.focus()})})),i=c.find(".kv-zoom-body"),c.removeClass("kv-single-content"),t?(r=i.addClass("file-thumb-loading").clone().insertAfter(i),N.setHtml(i,g).hide(),r.fadeOut("fast",function(){i.fadeIn("fast",function(){i.removeClass("file-thumb-loading")}),r.remove()})):N.setHtml(i,g),(n=s.previewZoomSettings[n])&&(a=i.find(".kv-preview-data"),N.addCss(a,"file-zoom-detail"),L.each(n,function(e,t){a.css(e,t),(a.attr("width")&&"width"===e||a.attr("height")&&"height"===e)&&a.removeAttr(e)})),c.data("previewId",l),s._handler(c.find(".btn-kv-prev"),"click",function(){s._zoomSlideShow("prev",l)}),s._handler(c.find(".btn-kv-next"),"click",function(){s._zoomSlideShow("next",l)}),s._handler(u,"click",function(){s._resizeZoomDialog(!0)}),s._handler(p,"click",function(){s._resizeZoomDialog(!1)}),s._handler(f,"click",function(){function e(e){var t=s.$modal.find(".kv-zoom-body"),i=s.zoomModalHeight;c.hasClass("file-zoom-fullscreen")&&(i=t.outerHeight(!0),e||(i-=a.outerHeight(!0))),t.css("height",e?i+e:i)}var t,a=c.find(".modal-header"),i=c.find(".floating-buttons"),r=a.find(".kv-zoom-actions");a.is(":visible")?(t=a.outerHeight(!0),a.slideUp("slow",function(){r.find(".btn").appendTo(i),e(t)})):(i.find(".btn").appendTo(r),a.slideDown("slow",function(){e()})),c.focus()}),s._handler(c,"keydown",function(e){var t,a=e.which||e.keyCode,r=s.processDelay+1,i=L(this).find(".btn-kv-prev"),n=L(this).find(".btn-kv-next"),o=L(this).data("previewId");[t,e]=s.rtl?[39,37]:[37,39],L.each({prev:[i,t],next:[n,e]},function(e,t){var i=t[0],t=t[1];a===t&&i.length&&(c.focus(),i.attr("disabled")||(i.focus(),s._zoomSlideShow(e,o),setTimeout(function(){i.attr("disabled")&&c.focus()},r)))})})},_showModal:function(e){var t=this.$modal;e&&e.length&&(N.initModal(t),N.setHtml(t,this._getModalContent()),this._setZoomContent(e),t.data({backdrop:!1}),t.modal("show"),this._initZoomButtons())},_zoomPreview:function(e){if(!e.length)throw"Cannot zoom to detailed preview!";e=e.closest(N.FRAMES),this._showModal(e)},_zoomSlideShow:function(e,t){var i,a,r,n=this,o=n.$modal.find(".kv-zoom-actions .btn-kv-"+e),s=n.getFrames().toArray(),l=[],d=s.length;if(n.reversePreviewOrder&&(e="prev"===e?"next":"prev"),!o.attr("disabled")){for(i=0;i'+e.defaultPreviewContent+"
    "),e.$container.removeClass("file-input-new"),e._initClickable())},_resetPreviewThumbs:function(e){var t=this;if(e)return t._clearPreview(),void t.clearFileStack();t._hasInitialPreview()?(e=t.previewCache.out(),t._setPreviewContent(e.content),t._setInitThumbAttr(),t._setCaption(e.caption),t._initPreviewActions()):t._clearPreview()},_getLayoutTemplate:function(e){e=this.layoutTemplates[e];return N.isEmpty(this.customLayoutTags)?e:N.replaceTags(e,this.customLayoutTags)},_getPreviewTemplate:function(e){var t=this.previewTemplates,t=t[e]||t.other;return N.isEmpty(this.customPreviewTags)?t:N.replaceTags(t,this.customPreviewTags)},_getOutData:function(e,t,i,a){var r=this;return t=t||{},i=i||{},{formdata:e,files:a=a||r.fileManager.list(),filenames:r.filenames,filescount:r.getFilesCount(),extra:r._getExtraData(),response:i,reader:r.reader,jqXHR:t}},_getMsgSelected:function(e,t){var i=this,a=1===e?i.fileSingle:i.filePlural;return 0 .file-preview-frame");e&&e.length&&e.insertBefore(t).fadeIn("slow").css("display:inline-block"),l._initPreviewActions(),l._clearFileInput(),t.remove(),a.remove(),l._initSortable()})):(l.previewCache.set(r,n,o,e),l._initPreview(),l._initPreviewActions())),l._resetCaption()},_getUploadCacheIndex:function(e){for(var t=this.uploadCache.length,i=0;i&"']/g,"_")},_updateFileDetails:function(e){var t=this,i=t.$element,a=N.isIE(9)&&N.findFileName(i.val())||i[0].files[0]&&i[0].files[0].name,r=!a&&0'+a+"
    "),t.$container.removeClass("file-input-new"),N.addCss(t.$container,"file-input-ajax-new"))},_getStats:function(e){var t,i;return this.showUploadStats&&e&&e.bitrate?(i=this._getLayoutTemplate("stats"),t=e.elapsed&&e.bps?this.msgPendingTime.setTokens({time:N.getElapsed(Math.ceil(e.pendingBytes/e.bps))}):this.msgCalculatingTime,i.setTokens({uploadSpeed:e.bitrate,pendingTime:t})):""},_setResumableProgress:function(e,t,i){var a=this.resumableManager,a=i?a:this,i=i?i.find(".file-thumb-progress"):null;0===a.lastProgress&&(a.lastProgress=e),eo*a.bytesToKB&&a._getResizedImage(e,t,r,n),t.validated=!0)}))},_getResizedImage:function(e,t,i,a){var r,n,o=this,s=L(t.img)[0],l=s.naturalWidth,d=s.naturalHeight,c=1,u=o.maxImageWidth||l,p=o.maxImageHeight||d,f=!(!l||!d),g=o.imageCanvas,m=o.imageCanvasContext,h=t.typ,v=t.pid,w=t.ind,b=t.thumb,_=t.exifObj,C=function(e,t,i){o.isAjaxUpload?o._showFileError(e,t,i):o._showError(e,t,i),o._setPreviewError(b)},t=o.fileManager.getFile(e),y={id:v,index:w,fileId:e},x=[e,v,w];if(t&&f&&!(l<=u&&d<=p)||(f&&t&&o._raise("fileimageresized",x),i.val++,i.val===a&&o._raise("fileimagesresized"),f)){h=h||o.resizeDefaultImageType,t=u"+n.msgValidationError+"
    ").text(),r=(a=n.fileManager.count())?(r=n.fileManager.getFirstFile(),1===a&&r?r.nameFmt:n._getMsgSelected(a)):n._getMsgSelected(n.msgNo),a=N.isEmpty(e)?r:e,r=''+n.msgValidationErrorIcon+"";else{if(N.isEmpty(e))return void n.$caption.attr("title","");a=i=L("
    "+e+"
    ").text(),r=n._getLayoutTemplate("fileIcon")}n.$captionContainer.addClass("icon-visible"),n.$caption.attr("title",i).val(a),N.setHtml(n.$captionIcon,r)}},_createContainer:function(){var e=this,t={class:"file-input file-input-new"+(e.rtl?" kv-rtl":"")},i=N.createElement(N.cspBuffer.stash(e._renderMain()));return N.cspBuffer.apply(i),i.insertBefore(e.$element).attr(t),e._initBrowse(i),e.theme&&i.addClass("theme-"+e.theme),i},_refreshContainer:function(){var e=this,t=e.$container;e.$element.insertAfter(t),N.setHtml(t,e._renderMain()),e._initBrowse(t),e._validateDisabled()},_validateDisabled:function(){this.$caption.attr({readonly:this.isDisabled})},_setTabIndex:function(e,t){e=this.tabIndexConfig[e];return t.setTokens({tabIndexConfig:null==e?"":'tabindex="'+e+'"'})},_renderMain:function(){var e=this,t=e.dropZoneEnabled?" file-drop-zone":"file-drop-disabled",i=e.showClose?e._getLayoutTemplate("close"):"",a=e.showPreview?e._getLayoutTemplate("preview").setTokens({class:e.previewClass,dropClass:t}):"",t=e.isDisabled?e.captionClass+" file-caption-disabled":e.captionClass,t=e.captionTemplate.setTokens({class:t+" kv-fileinput-caption"}),t=e._setTabIndex("caption",t);return e.mainTemplate.setTokens({class:e.mainClass+(!e.showBrowse&&e.showCaption?" no-browse":""),inputGroupClass:e.inputGroupClass,preview:a,close:i,caption:t,upload:e._renderButton("upload"),remove:e._renderButton("remove"),cancel:e._renderButton("cancel"),pause:e._renderButton("pause"),browse:e._renderButton("browse")})},_renderButton:function(e){var t=this,i=t._getLayoutTemplate("btnDefault"),a=t[e+"Class"],r=t[e+"Title"],n=t[e+"Icon"],o=t[e+"Label"],s=t.isDisabled?" disabled":"",l="button";switch(e){case"remove":if(!t.showRemove)return"";break;case"cancel":if(!t.showCancel)return"";a+=" kv-hidden";break;case"pause":if(!t.showPause)return"";a+=" kv-hidden";break;case"upload":if(!t.showUpload)return"";t.isAjaxUpload&&!t.isDisabled?i=t._getLayoutTemplate("btnLink").replace("{href}",t.uploadUrl):l="submit";break;case"browse":if(!t.showBrowse)return"";i=t._getLayoutTemplate("btnBrowse");break;default:return""}return i=t._setTabIndex(e,i),a+="browse"===e?" btn-file":" fileinput-"+e+" fileinput-"+e+"-button",N.isEmpty(o)||(o=' '+o+""),i.setTokens({type:l,css:a,title:r,status:s,icon:n,label:o})},_renderThumbProgress:function(){return'
    '+this.progressInfoTemplate.setTokens({percent:101,status:this.msgUploadBegin,stats:""})+"
    "},_renderFileFooter:function(e,t,i,a,r){var n=this,o=n.fileActionSettings,s=o.showRemove,l=o.showDrag,d=o.showUpload,c=o.showZoom,u=n._getLayoutTemplate("footer"),p=n._getLayoutTemplate("indicator"),f=r?o.indicatorError:o.indicatorNew,o=r?o.indicatorErrorTitle:o.indicatorNewTitle,o=p.setTokens({indicator:f,indicatorTitle:o}),o={type:e,caption:t,size:i=n._getSize(i),width:a,progress:"",indicator:o};return n.isAjaxUpload?(o.progress=n._renderThumbProgress(),o.actions=n._renderFileActions(o,d,!1,s,c,l,!1,!1,!1)):o.actions=n._renderFileActions(o,!1,!1,!1,c,l,!1,!1,!1),o=u.setTokens(o),o=N.replaceTags(o,n.previewThumbTags)},_renderFileActions:function(e,t,i,a,r,n,o,s,l,d,c,u){var p=this;if(!e.type&&d&&(e.type="image"),p.enableResumableUpload?t=!1:"function"==typeof t&&(t=t(e)),"function"==typeof i&&(i=i(e)),"function"==typeof a&&(a=a(e)),"function"==typeof r&&(r=r(e)),"function"==typeof n&&(n=n(e)),!(t||i||a||r||n))return"";var f=!1===s?"":' data-url="'+s+'"',g="",m="",h=!1===l?"":' data-key="'+l+'"',v="",w="",b="",_=p._getLayoutTemplate("actions"),e=p.fileActionSettings,s=p.otherActionButtons.setTokens({dataKey:h,key:l}),o=o?e.removeClass+" disabled":e.removeClass;return a&&(v=p._getLayoutTemplate("actionDelete").setTokens({removeClass:o,removeIcon:e.removeIcon,removeTitle:e.removeTitle,dataUrl:f,dataKey:h,key:l})),t&&(w=p._getLayoutTemplate("actionUpload").setTokens({uploadClass:e.uploadClass,uploadIcon:e.uploadIcon,uploadTitle:e.uploadTitle})),i&&(b=(b=p._getLayoutTemplate("actionDownload").setTokens({downloadClass:e.downloadClass,downloadIcon:e.downloadIcon,downloadTitle:e.downloadTitle,downloadUrl:c||p.initialPreviewDownloadUrl})).setTokens({filename:u,key:l})),r&&(g=p._getLayoutTemplate("actionZoom").setTokens({zoomClass:e.zoomClass,zoomIcon:e.zoomIcon,zoomTitle:e.zoomTitle})),n&&d&&(d="drag-handle-init "+e.dragClass,m=p._getLayoutTemplate("actionDrag").setTokens({dragClass:d,dragTitle:e.dragTitle,dragIcon:e.dragIcon})),_.setTokens({delete:v,upload:w,download:b,zoom:g,drag:m,other:s})},_browse:function(e){var t=this;e&&e.isDefaultPrevented()||!t._raise("filebrowse")||(t.isError&&!t.isAjaxUpload&&t.clear(),t.focusCaptionOnBrowse&&t.$captionContainer.focus())},_change:function(e){var n=this;if(L(document.body).off("focusin.fileinput focusout.fileinput"),!n.changeTriggered){n._setLoading("show");var t=n.$element,i=1
  • ")+"
  • ",0===e.find("ul").length?N.setHtml(e,S.errorCloseButton+"
      "+x+"
    "):e.find("ul").append(x),e.fadeIn(S.fadeDelay),S._handler(e.find(".kv-error-close"),"click",function(){e.fadeOut(S.fadeDelay)}),S.duplicateErrors=[]),S.isAjaxUpload?(S._raise("filebatchselected",[i.stack]),0!==i.count()||S.isError||S.reset()):S._raise("filebatchselected",[P]),I.removeClass("file-thumb-loading"),S._initCapStatus("valid"),void A.html("");S.lock(!0);function c(){var e=!!i.loadedImages[s],t=D.setTokens({index:d+1,files:j,percent:50,name:m});setTimeout(function(){A.html(t),S._updateFileDetails(j),k(d+1)},S.processDelay),S._raise("fileloaded",[f,l,s,d,E])&&S.isAjaxUpload?e||i.add(f):e&&i.removeFile(s)}var t,u,a,r,n,o,p,f=P[d],s=S._getFileId(f),l=U+"-"+s,g=M.image,m=S._getFileName(f,""),h=(f&&f.size||0)/S.bytesToKB,v="",w=N.createObjectURL(f),b=0,_="",C=!1,y=0;if(f){if(r=i.getId(f),0S.maxFileSize)return T=S.msgSizeTooLarge.setTokens({name:m,size:t,maxSize:S.maxFileSize}),void F(T,f,l,d,r);if(null!==S.minFileSize&&h<=N.getNum(S.minFileSize))return T=S.msgSizeTooSmall.setTokens({name:m,size:t,minSize:S.minFileSize}),void F(T,f,l,d,r);if(!N.isEmpty($)&&N.isArray($)){for(u=0;u<$.length;u+=1)o=$[u],b+=(o=M[o])&&"function"==typeof o&&o(f.type,N.getFileName(f))?1:0;if(0===b)return T=S.msgInvalidFileType.setTokens({name:m,types:_}),void F(T,f,l,d,r)}return 0!==b||N.isEmpty(R)||!N.isArray(R)||N.isEmpty(v)||(v=N.compare(m,v),0!==(b+=N.isEmpty(v)?0:v.length))?S._canPreview(f)?(p=g(f.type,m),A.html(z.replace("{index}",d+1).replace("{files}",j)),I.addClass("file-thumb-loading"),S._initCapStatus("processing"),E.onerror=function(e){S._errorHandler(e,m)},E.onload=function(e){var t,i,a,r,n,o,s=[],l={name:m,type:f.type};if(L.each(M,function(e,t){"object"!==e&&"other"!==e&&"function"==typeof t&&t(f.type,m)&&y++}),0===y){for(i=new Uint8Array(e.target.result),u=0;u
    ',next:'',toggleheader:'',fullscreen:'',borderless:'',close:''},previewZoomButtonClasses:{prev:"btn btn-default btn-outline-secondary btn-navigate",next:"btn btn-default btn-outline-secondary btn-navigate",toggleheader:t,fullscreen:t,borderless:t,close:t},previewTemplates:{},previewContentTemplates:{},preferIconicPreview:!1,preferIconicZoomPreview:!1,allowedFileTypes:null,allowedFileExtensions:null,allowedPreviewTypes:void 0,allowedPreviewMimeTypes:null,allowedPreviewExtensions:null,disabledPreviewTypes:void 0,disabledPreviewExtensions:["msi","exe","com","zip","rar","app","vb","scr"],disabledPreviewMimeTypes:null,defaultPreviewContent:null,customLayoutTags:{},customPreviewTags:{},previewFileIcon:'',previewFileIconClass:"file-other-icon",previewFileIconSettings:{},previewFileExtSettings:{},buttonLabelClass:"hidden-xs",browseIcon:' ',browseClass:"btn btn-primary",removeIcon:'',removeClass:i,cancelIcon:'',cancelClass:i,pauseIcon:'',pauseClass:i,uploadIcon:'',uploadClass:i,uploadUrl:null,uploadUrlThumb:null,uploadAsync:!0,uploadParamNames:{chunkCount:"chunkCount",chunkIndex:"chunkIndex",chunkSize:"chunkSize",chunkSizeStart:"chunkSizeStart",chunksUploaded:"chunksUploaded",fileBlob:"fileBlob",fileId:"fileId",fileName:"fileName",fileRelativePath:"fileRelativePath",fileSize:"fileSize",retryCount:"retryCount"},maxAjaxThreads:5,fadeDelay:800,processDelay:100,bitrateUpdateDelay:500,queueDelay:10,progressDelay:0,enableResumableUpload:!1,resumableUploadOptions:{fallback:null,testUrl:null,chunkSize:2048,maxThreads:4,maxRetries:3,showErrorLog:!0,retainErrorHistory:!0,skipErrorsAndProceed:!1},uploadExtraData:{},zoomModalHeight:480,minImageWidth:null,minImageHeight:null,maxImageWidth:null,maxImageHeight:null,resizeImage:!1,resizePreference:"width",resizeQuality:.92,resizeDefaultImageType:"image/jpeg",resizeIfSizeMoreThan:0,minFileSize:-1,maxFileSize:0,maxFilePreviewSize:25600,minFileCount:0,maxFileCount:0,maxTotalFileCount:0,validateInitialCount:!1,msgValidationErrorClass:"text-danger",msgValidationErrorIcon:' ',msgErrorClass:"file-error-message",progressThumbClass:"progress-bar progress-bar-striped active progress-bar-animated",progressClass:"progress-bar bg-success progress-bar-success progress-bar-striped active progress-bar-animated",progressInfoClass:"progress-bar bg-info progress-bar-info progress-bar-striped active progress-bar-animated",progressCompleteClass:"progress-bar bg-success progress-bar-success",progressPauseClass:"progress-bar bg-primary progress-bar-primary progress-bar-striped active progress-bar-animated",progressErrorClass:"progress-bar bg-danger progress-bar-danger",progressUploadThreshold:99,previewFileType:"image",elCaptionContainer:null,elCaptionText:null,elPreviewContainer:null,elPreviewImage:null,elPreviewStatus:null,elErrorContainer:null,errorCloseButton:void 0,slugCallback:null,dropZoneEnabled:!0,dropZoneTitleClass:"file-drop-zone-title",fileActionSettings:{},otherActionButtons:"",textEncoding:"UTF-8",preProcessUpload:null,ajaxSettings:{},ajaxDeleteSettings:{},showAjaxErrorDetails:!0,mergeAjaxCallbacks:!1,mergeAjaxDeleteCallbacks:!1,retryErrorUploads:!0,reversePreviewOrder:!1,usePdfRenderer:function(){var e=!!window.MSInputMethodContext&&!!document.documentMode;return!!navigator.userAgent.match(/(iPod|iPhone|iPad|Android)/i)||e},pdfRendererUrl:"",pdfRendererTemplate:'',tabIndexConfig:{browse:500,remove:500,upload:500,cancel:null,pause:null,modal:-1}},L.fn.fileinputLocales.en={sizeUnits:["B","KB","MB","GB","TB","PB","EB","ZB","YB"],bitRateUnits:["B/s","KB/s","MB/s","GB/s","TB/s","PB/s","EB/s","ZB/s","YB/s"],fileSingle:"file",filePlural:"files",browseLabel:"Browse …",removeLabel:"Remove",removeTitle:"Clear all unprocessed files",cancelLabel:"Cancel",cancelTitle:"Abort ongoing upload",pauseLabel:"Pause",pauseTitle:"Pause ongoing upload",uploadLabel:"Upload",uploadTitle:"Upload selected files",msgNo:"No",msgNoFilesSelected:"No files selected",msgCancelled:"Cancelled",msgPaused:"Paused",msgPlaceholder:"Select {files} ...",msgZoomModalHeading:"Detailed Preview",msgFileRequired:"You must select a file to upload.",msgSizeTooSmall:'File "{name}" ({size} KB) is too small and must be larger than {minSize} KB.',msgSizeTooLarge:'File "{name}" ({size} KB) exceeds maximum allowed upload size of {maxSize} KB.',msgFilesTooLess:"You must select at least {n} {files} to upload.",msgFilesTooMany:"Number of files selected for upload ({n}) exceeds maximum allowed limit of {m}.",msgTotalFilesTooMany:"You can upload a maximum of {m} files ({n} files detected).",msgFileNotFound:'File "{name}" not found!',msgFileSecured:'Security restrictions prevent reading the file "{name}".',msgFileNotReadable:'File "{name}" is not readable.',msgFilePreviewAborted:'File preview aborted for "{name}".',msgFilePreviewError:'An error occurred while reading the file "{name}".',msgInvalidFileName:'Invalid or unsupported characters in file name "{name}".',msgInvalidFileType:'Invalid type for file "{name}". Only "{types}" files are supported.',msgInvalidFileExtension:'Invalid extension for file "{name}". Only "{extensions}" files are supported.',msgFileTypes:{image:"image",html:"HTML",text:"text",video:"video",audio:"audio",flash:"flash",pdf:"PDF",object:"object"},msgUploadAborted:"The file upload was aborted",msgUploadThreshold:"Processing …",msgUploadBegin:"Initializing …",msgUploadEnd:"Done",msgUploadResume:"Resuming upload …",msgUploadEmpty:"No valid data available for upload.",msgUploadError:"Upload Error",msgDeleteError:"Delete Error",msgProgressError:"Error",msgValidationError:"Validation Error",msgLoading:"Loading file {index} of {files} …",msgProgress:"Loading file {index} of {files} - {name} - {percent}% completed.",msgSelected:"{n} {files} selected",msgProcessing:"Processing ...",msgFoldersNotAllowed:"Drag & drop files only! {n} folder(s) dropped were skipped.",msgImageWidthSmall:'Width of image file "{name}" must be at least {size} px.',msgImageHeightSmall:'Height of image file "{name}" must be at least {size} px.',msgImageWidthLarge:'Width of image file "{name}" cannot exceed {size} px.',msgImageHeightLarge:'Height of image file "{name}" cannot exceed {size} px.',msgImageResizeError:"Could not get the image dimensions to resize.",msgImageResizeException:"Error while resizing the image.
    {errors}
    ",msgAjaxError:"Something went wrong with the {operation} operation. Please try again later!",msgAjaxProgressError:"{operation} failed",msgDuplicateFile:'File "{name}" of same size "{size} KB" has already been selected earlier. Skipping duplicate selection.',msgResumableUploadRetriesExceeded:"Upload aborted beyond {max} retries for file {file}! Error Details:
    {error}
    ",msgPendingTime:"{time} remaining",msgCalculatingTime:"calculating time remaining",ajaxOperations:{deleteThumb:"file delete",uploadThumb:"file upload",uploadBatch:"batch file upload",uploadExtra:"form data upload"},dropZoneTitle:"Drag & drop files here …",dropZoneClickTitle:"
    (or click to select {files})",previewZoomButtonTitles:{prev:"View previous file",next:"View next file",toggleheader:"Toggle header",fullscreen:"Toggle full screen",borderless:"Toggle borderless mode",close:"Close detailed preview"}},L.fn.fileinputLocales.zh={sizeUnits:["B","KB","MB","GB","TB","PB","EB","ZB","YB"],bitRateUnits:["B/s","KB/s","MB/s","GB/s","TB/s","PB/s","EB/s","ZB/s","YB/s"],fileSingle:"文件",filePlural:"个文件",browseLabel:"选择 …",removeLabel:"移除",removeTitle:"清除选中文件",cancelLabel:"取消",cancelTitle:"取消进行中的上传",pauseLabel:"暂停",pauseTitle:"暂停上传",uploadLabel:"上传",uploadTitle:"上传选中文件",msgNo:"没有",msgNoFilesSelected:"未选择文件",msgPaused:"已暂停",msgCancelled:"取消",msgPlaceholder:"选择 {files} ...",msgZoomModalHeading:"详细预览",msgFileRequired:"必须选择一个文件上传.",msgSizeTooSmall:'文件 "{name}" ({size} KB) 必须大于限定大小 {minSize} KB.',msgSizeTooLarge:'文件 "{name}" ({size} KB) 超过了允许大小 {maxSize} KB.',msgFilesTooLess:"你必须选择最少 {n} {files} 来上传. ",msgFilesTooMany:"选择的上传文件个数 ({n}) 超出最大文件的限制个数 {m}.",msgTotalFilesTooMany:"你最多可以上传 {m} 个文件 (当前有{n} 个文件).",msgFileNotFound:'文件 "{name}" 未找到!',msgFileSecured:'安全限制,为了防止读取文件 "{name}".',msgFileNotReadable:'文件 "{name}" 不可读.',msgFilePreviewAborted:'取消 "{name}" 的预览.',msgFilePreviewError:'读取 "{name}" 时出现了一个错误.',msgInvalidFileName:'文件名 "{name}" 包含非法字符.',msgInvalidFileType:'不正确的类型 "{name}". 只支持 "{types}" 类型的文件.',msgInvalidFileExtension:'不正确的文件扩展名 "{name}". 只支持 "{extensions}" 的文件扩展名.',msgFileTypes:{image:"image",html:"HTML",text:"text",video:"video",audio:"audio",flash:"flash",pdf:"PDF",object:"object"},msgUploadAborted:"该文件上传被中止",msgUploadThreshold:"处理中 …",msgUploadBegin:"正在初始化 …",msgUploadEnd:"完成",msgUploadResume:"继续上传 …",msgUploadEmpty:"无效的文件上传.",msgUploadError:"上传出错",msgDeleteError:"删除出错",msgProgressError:"上传出错",msgValidationError:"验证错误",msgLoading:"加载第 {index} 文件 共 {files} …",msgProgress:"加载第 {index} 文件 共 {files} - {name} - {percent}% 完成.",msgSelected:"{n} {files} 选中",msgProcessing:"处理中 ...",msgFoldersNotAllowed:"只支持拖拽文件! 跳过 {n} 拖拽的文件夹.",msgImageWidthSmall:'图像文件的"{name}"的宽度必须是至少{size}像素.',msgImageHeightSmall:'图像文件的"{name}"的高度必须至少为{size}像素.',msgImageWidthLarge:'图像文件"{name}"的宽度不能超过{size}像素.',msgImageHeightLarge:'图像文件"{name}"的高度不能超过{size}像素.',msgImageResizeError:"无法获取的图像尺寸调整。",msgImageResizeException:"调整图像大小时发生错误。
    {errors}
    ",msgAjaxError:"{operation} 发生错误. 请重试!",msgAjaxProgressError:"{operation} 失败",msgDuplicateFile:'文件 "{name}",大小 "{size} KB" 已经被选中.忽略相同的文件.',msgResumableUploadRetriesExceeded:"文件 {file} 上传失败超过 {max} 次重试 ! 错误详情:
    {error}
    ",msgPendingTime:"{time} 剩余",msgCalculatingTime:"计算剩余时间",ajaxOperations:{deleteThumb:"删除文件",uploadThumb:"上传文件",uploadBatch:"批量上传",uploadExtra:"表单数据上传"},dropZoneTitle:"拖拽文件到这里 …
    支持多文件同时上传",dropZoneClickTitle:"
    (或点击{files}按钮选择文件)",fileActionSettings:{removeTitle:"删除文件",uploadTitle:"上传文件",downloadTitle:"下载文件",uploadRetryTitle:"重试",zoomTitle:"查看详情",dragTitle:"移动 / 重置",indicatorNewTitle:"没有上传",indicatorSuccessTitle:"上传",indicatorErrorTitle:"上传错误",indicatorPausedTitle:"上传已暂停",indicatorLoadingTitle:"上传 …"},previewZoomButtonTitles:{prev:"预览上一个文件",next:"预览下一个文件",toggleheader:"缩放",fullscreen:"全屏",borderless:"无边界模式",close:"关闭当前预览"}},L.fn.fileinput.Constructor=c,L(document).ready(function(){var e=L("input.file[type=file]");e.length&&e.fileinput()})}); \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-fileinput/loading-sm.gif new file mode 100644 index 0000000000000000000000000000000000000000..44e3b7a0f702aa1d301468b1d6c1d74d45dfdfa4 GIT binary patch literal 2670 zcmb`Je@v5i9>LSr1(@@0hFth{;0&ijQR3npb})ArbBQ}PvxUrk9==i>-je&{`bYn0 zn)LJfykDR9({*{d^3^65#=>kEmYR~<(cUp}W8&ez9`;@Cv+TEYecW~T-rd+qu-ktq^cI?{N#Y-2bznz}@Wlou^?0COp;`YSDe?RQ|Tc54YcCq*3v~POu z=Q)qt<8AOhdGZ9Ce@UMNZ%`E#<|wqPl%!-T1wNGi6v$*^VoXMUfgA&)8H|&=avY{@ zJeN-^xjCUe&M)59EweXtoViM;a-1?pz|8ANLRhI=H=wp@r|+lJt@60`I1L>ikf9d z0~~r>SYAh`8ncKP#Y`em&991Ki+9$D<+Ah`h8ABLvp^+Tq&fmry95!A4*~{!r(W{r|twO<9E6hwX}% z)F~4zBCfrDD2L!G=moq=Ocm!kf(>!j#MWki`kE{G-BYoHbydNkr`YYfzkHJ}sdz&Z z8KyFYGObizP&mFNfL9$Pkl^BMW@H7Mj~&{~Y}&^@Em8az7i38?{{@hom-`@R{}EIl zuKr(+p!%I^SP+EozXRAQx&zv)Q;+jLkH^n1bF~-lxqi~zs6M>$2b`E?bDR1(oHROR zaB7GXUJ{zi)G5043^#qed;40J-ClCQog6(Hud5xphOP%&4#R>m7Bck%Y7iX-)s;GnT=AX8I6;x z*Ol?b-#BAm+c8m@;Zg6;uE=_2%jzUWr*x2ox8%paAn8qLY^bd(b;)ctlkU^fu=Vc3 zz;SN~k7AeP8RH2m;z z2CX1gkPsDhP~gugYVl&ptMm6Li~=Mu93%mmkyQ%qyHLgm8|ug3#{dSLkO}}pC4+2m z`Abd|+`DA@$4K%kR+rDRtj=pVseWU_SosF`XJ_(Mv(56PPTS5aAL87zteO7ON2zXW zXJVy1^(Mx0!G&0`_T@yc7N3_Iz0+VN*C^fuY4rdK8WyJhb56^W6%| zhv|@e@GJq}V9C%h00$|+q%bv<3=9s$WESlms9VW!FOl?MEbIgN3J@Vy2p1xL+O3%* z4%2yvY0~i3-n5pgHjU@SvC&L^4Rsa4mb2FHx-acsLminpiEGcb4^avWjB6bs?yxHv zFP>OoZm&@)|E$XG{cHFN;rjRP&k2G>fr0d>;EjE|0c(GfTT-1_oMa2pu0v=?C ziWR6(s{%i;LARh*1pqiF)TclTcn}}b?&(F5kHB?rd-LMljI3nO?V@)3zQ#dO-513t ztjcsEGqLW@n}vqVK-aY$rTULTyjJV(hyiVw^9O}%O%TO%-BuBoT7PVy_KKNUTkL36 z?~x1XsVjwnVnJz^Up>+9s|T|{G?2yf>OloQZy$sL`TErZnkDwpwn;{pv6^-mtgcw9 z_E@9A+pHJ039kOw(VR1!{Fzhc9qk-wO9+x3Qyrg@1UN60rpBE1jKy*kvzjY8GMB%rN zWSO@Pl7v*3SO+Q5wzobgsdpIf?Qr=duPeH-rgHWhu znosfxTsJ3QpXcCF1>~qGXs@ZJ zyw~IM73y!A^G>VZ8R)gNG&BU|KuYo)y+(NV^DdAFW5LeVJBBCMNfRtuR+y^ER&<(X zE7%B&e5#Z^`o7-@nEg_P~LI*N!rA^h{|;%@7gdIe0+9 zL6FPmK*NXRK=)=Qr!7yn1(?oIuvujqni9B8`-RfJ#pzQFR*0=zw6NbXTj0F1BLlZh zfVly?4JS*30beAWg%&SoyRsrS%M*Y;RQ^0c<0TpwHaFY zz6r{%O%_#7fe{VKyK@(naSJIeRCsx4aYAE48*ixFGRdMll6*@GUTc0%``>`o8j#V4 zg9*c-O~)LSJSTE&n6)s0!!ECt)zd(wL!wvC+k6wRhYtI}PTi7bt)^yIDG`AshjlL| qtmsHM!1PnVu#-b#!*qv!K4 select.bs-select-hidden, +select.selectpicker { + display: none !important; +} +.bootstrap-select { + width: 220px \0; + /*IE9 and below*/ + vertical-align: middle; +} +.bootstrap-select > .dropdown-toggle { + position: relative; + width: 100%; + text-align: right; + white-space: nowrap; + display: -webkit-inline-box; + display: -webkit-inline-flex; + display: -ms-inline-flexbox; + display: inline-flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-box-pack: justify; + -webkit-justify-content: space-between; + -ms-flex-pack: justify; + justify-content: space-between; +} +.bootstrap-select > .dropdown-toggle:after { + margin-top: -1px; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder, +.bootstrap-select > .dropdown-toggle.bs-placeholder:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder:active { + color: #999; +} +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:hover, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:focus, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-primary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-secondary:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-success:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-danger:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-info:active, +.bootstrap-select > .dropdown-toggle.bs-placeholder.btn-dark:active { + color: rgba(255, 255, 255, 0.5); +} +.bootstrap-select > select { + position: absolute !important; + bottom: 0; + left: 50%; + display: block !important; + width: 0.5px !important; + height: 100% !important; + padding: 0 !important; + opacity: 0 !important; + border: none; + z-index: 0 !important; +} +.bootstrap-select > select.mobile-device { + top: 0; + left: 0; + display: block !important; + width: 100% !important; + z-index: 2 !important; +} +.has-error .bootstrap-select .dropdown-toggle, +.error .bootstrap-select .dropdown-toggle, +.bootstrap-select.is-invalid .dropdown-toggle, +.was-validated .bootstrap-select select:invalid + .dropdown-toggle { + border-color: #b94a48; +} +.bootstrap-select.is-valid .dropdown-toggle, +.was-validated .bootstrap-select select:valid + .dropdown-toggle { + border-color: #28a745; +} +.bootstrap-select.fit-width { + width: auto !important; +} +.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) { + width: 220px; +} +.bootstrap-select > select.mobile-device:focus + .dropdown-toggle, +.bootstrap-select .dropdown-toggle:focus { + outline: thin dotted #333333 !important; + outline: 5px auto -webkit-focus-ring-color !important; + outline-offset: -2px; +} +.bootstrap-select.form-control { + margin-bottom: 0; + padding: 0; + border: none; + height: auto; +} +:not(.input-group) > .bootstrap-select.form-control:not([class*="col-"]) { + width: 100%; +} +.bootstrap-select.form-control.input-group-btn { + float: none; + z-index: auto; +} +.form-inline .bootstrap-select, +.form-inline .bootstrap-select.form-control:not([class*="col-"]) { + width: auto; +} +.bootstrap-select:not(.input-group-btn), +.bootstrap-select[class*="col-"] { + float: none; + display: inline-block; + margin-left: 0; +} +.bootstrap-select.dropdown-menu-right, +.bootstrap-select[class*="col-"].dropdown-menu-right, +.row .bootstrap-select[class*="col-"].dropdown-menu-right { + float: right; +} +.form-inline .bootstrap-select, +.form-horizontal .bootstrap-select, +.form-group .bootstrap-select { + margin-bottom: 0; +} +.form-group-lg .bootstrap-select.form-control, +.form-group-sm .bootstrap-select.form-control { + padding: 0; +} +.form-group-lg .bootstrap-select.form-control .dropdown-toggle, +.form-group-sm .bootstrap-select.form-control .dropdown-toggle { + height: 100%; + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle, +.bootstrap-select.form-control-lg .dropdown-toggle { + font-size: inherit; + line-height: inherit; + border-radius: inherit; +} +.bootstrap-select.form-control-sm .dropdown-toggle { + padding: 0.25rem 0.5rem; +} +.bootstrap-select.form-control-lg .dropdown-toggle { + padding: 0.5rem 1rem; +} +.form-inline .bootstrap-select .form-control { + width: 100%; +} +.bootstrap-select.disabled, +.bootstrap-select > .disabled { + cursor: not-allowed; +} +.bootstrap-select.disabled:focus, +.bootstrap-select > .disabled:focus { + outline: none !important; +} +.bootstrap-select.bs-container { + position: absolute; + top: 0; + left: 0; + height: 0 !important; + padding: 0 !important; +} +.bootstrap-select.bs-container .dropdown-menu { + z-index: 1060; +} +.bootstrap-select .dropdown-toggle .filter-option { + position: static; + top: 0; + left: 0; + float: left; + height: 100%; + width: 100%; + text-align: left; + overflow: hidden; + -webkit-box-flex: 0; + -webkit-flex: 0 1 auto; + -ms-flex: 0 1 auto; + flex: 0 1 auto; +} +.bs3.bootstrap-select .dropdown-toggle .filter-option { + padding-right: inherit; +} +.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option { + position: absolute; + padding-top: inherit; + padding-bottom: inherit; + padding-left: inherit; + float: none; +} +.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner { + padding-right: inherit; +} +.bootstrap-select .dropdown-toggle .filter-option-inner-inner { + overflow: hidden; +} +.bootstrap-select .dropdown-toggle .filter-expand { + width: 0 !important; + float: left; + opacity: 0 !important; + overflow: hidden; +} +.bootstrap-select .dropdown-toggle .caret { + position: absolute; + top: 50%; + right: 12px; + margin-top: -2px; + vertical-align: middle; +} +.input-group .bootstrap-select.form-control .dropdown-toggle { + border-radius: inherit; +} +.bootstrap-select[class*="col-"] .dropdown-toggle { + width: 100%; +} +.bootstrap-select .dropdown-menu { + min-width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .dropdown-menu > .inner:focus { + outline: none !important; +} +.bootstrap-select .dropdown-menu.inner { + position: static; + float: none; + border: 0; + padding: 0; + margin: 0; + border-radius: 0; + -webkit-box-shadow: none; + box-shadow: none; +} +.bootstrap-select .dropdown-menu li { + position: relative; +} +.bootstrap-select .dropdown-menu li.active small { + color: rgba(255, 255, 255, 0.5) !important; +} +.bootstrap-select .dropdown-menu li.disabled a { + cursor: not-allowed; +} +.bootstrap-select .dropdown-menu li a { + cursor: pointer; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.bootstrap-select .dropdown-menu li a.opt { + position: relative; + padding-left: 2.25em; +} +.bootstrap-select .dropdown-menu li a span.check-mark { + display: none; +} +.bootstrap-select .dropdown-menu li a span.text { + display: inline-block; +} +.bootstrap-select .dropdown-menu li small { + padding-left: 0.5em; +} +.bootstrap-select .dropdown-menu .notify { + position: absolute; + bottom: 5px; + width: 96%; + margin: 0 2%; + min-height: 26px; + padding: 3px 5px; + background: #f5f5f5; + border: 1px solid #e3e3e3; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05); + pointer-events: none; + opacity: 0.9; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bootstrap-select .dropdown-menu .notify.fadeOut { + -webkit-animation: 300ms linear 750ms forwards bs-notify-fadeOut; + -o-animation: 300ms linear 750ms forwards bs-notify-fadeOut; + animation: 300ms linear 750ms forwards bs-notify-fadeOut; +} +.bootstrap-select .no-results { + padding: 3px; + background: #f5f5f5; + margin: 0 5px; + white-space: nowrap; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option { + position: static; + display: inline; + padding: 0; +} +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner, +.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner { + display: inline; +} +.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before { + content: '\00a0'; +} +.bootstrap-select.fit-width .dropdown-toggle .caret { + position: static; + top: auto; + margin-top: -1px; +} +.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark { + position: absolute; + display: inline-block; + right: 15px; + top: 5px; +} +.bootstrap-select.show-tick .dropdown-menu li a span.text { + margin-right: 34px; +} +.bootstrap-select .bs-ok-default:after { + content: ''; + display: block; + width: 0.5em; + height: 1em; + border-style: solid; + border-width: 0 0.26em 0.26em 0; + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; + -webkit-transform: rotate(45deg); + -ms-transform: rotate(45deg); + -o-transform: rotate(45deg); + transform: rotate(45deg); +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle { + z-index: 1061; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before { + content: ''; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid rgba(204, 204, 204, 0.2); + position: absolute; + bottom: -4px; + left: 9px; + display: none; +} +.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after { + content: ''; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid white; + position: absolute; + bottom: -4px; + left: 10px; + display: none; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before { + bottom: auto; + top: -4px; + border-top: 7px solid rgba(204, 204, 204, 0.2); + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after { + bottom: auto; + top: -4px; + border-top: 6px solid white; + border-bottom: 0; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before { + right: 12px; + left: auto; +} +.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after { + right: 13px; + left: auto; +} +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:before, +.bootstrap-select.show-menu-arrow.open > .dropdown-toggle .filter-option:after, +.bootstrap-select.show-menu-arrow.show > .dropdown-toggle .filter-option:after { + display: block; +} +.bs-searchbox, +.bs-actionsbox, +.bs-donebutton { + padding: 4px 8px; +} +.bs-actionsbox { + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-actionsbox .btn-group button { + width: 50%; +} +.bs-donebutton { + float: left; + width: 100%; + -webkit-box-sizing: border-box; + -moz-box-sizing: border-box; + box-sizing: border-box; +} +.bs-donebutton .btn-group button { + width: 100%; +} +.bs-searchbox + .bs-actionsbox { + padding: 0 8px 4px; +} +.bs-searchbox .form-control { + margin-bottom: 0; + width: 100%; + float: none; +} diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js new file mode 100644 index 00000000..d25d751d --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.js @@ -0,0 +1,3247 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +(function (root, factory) { + if (root === undefined && window !== undefined) root = window; + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module unless amdModuleId is set + define(["jquery"], function (a0) { + return (factory(a0)); + }); + } else if (typeof module === 'object' && module.exports) { + // Node. Does not work with strict CommonJS, but + // only CommonJS-like environments that support module.exports, + // like Node. + module.exports = factory(require("jquery")); + } else { + factory(root["jQuery"]); + } +}(this, function (jQuery) { + +(function ($) { + 'use strict'; + + var DISALLOWED_ATTRIBUTES = ['sanitize', 'whiteList', 'sanitizeFn']; + + var uriAttrs = [ + 'background', + 'cite', + 'href', + 'itemtype', + 'longdesc', + 'poster', + 'src', + 'xlink:href' + ]; + + var ARIA_ATTRIBUTE_PATTERN = /^aria-[\w-]*$/i; + + var DefaultWhitelist = { + // Global attributes allowed on any supplied element below. + '*': ['class', 'dir', 'id', 'lang', 'role', 'tabindex', 'style', ARIA_ATTRIBUTE_PATTERN], + a: ['target', 'href', 'title', 'rel'], + area: [], + b: [], + br: [], + col: [], + code: [], + div: [], + em: [], + hr: [], + h1: [], + h2: [], + h3: [], + h4: [], + h5: [], + h6: [], + i: [], + img: ['src', 'alt', 'title', 'width', 'height'], + li: [], + ol: [], + p: [], + pre: [], + s: [], + small: [], + span: [], + sub: [], + sup: [], + strong: [], + u: [], + ul: [] + } + + /** + * A pattern that recognizes a commonly useful subset of URLs that are safe. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var SAFE_URL_PATTERN = /^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi; + + /** + * A pattern that matches safe data URLs. Only matches image, video and audio types. + * + * Shoutout to Angular 7 https://github.com/angular/angular/blob/7.2.4/packages/core/src/sanitization/url_sanitizer.ts + */ + var DATA_URL_PATTERN = /^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i; + + function allowedAttribute (attr, allowedAttributeList) { + var attrName = attr.nodeName.toLowerCase() + + if ($.inArray(attrName, allowedAttributeList) !== -1) { + if ($.inArray(attrName, uriAttrs) !== -1) { + return Boolean(attr.nodeValue.match(SAFE_URL_PATTERN) || attr.nodeValue.match(DATA_URL_PATTERN)) + } + + return true + } + + var regExp = $(allowedAttributeList).filter(function (index, value) { + return value instanceof RegExp + }) + + // Check if a regular expression validates the attribute. + for (var i = 0, l = regExp.length; i < l; i++) { + if (attrName.match(regExp[i])) { + return true + } + } + + return false + } + + function sanitizeHtml (unsafeElements, whiteList, sanitizeFn) { + if (sanitizeFn && typeof sanitizeFn === 'function') { + return sanitizeFn(unsafeElements); + } + + var whitelistKeys = Object.keys(whiteList); + + for (var i = 0, len = unsafeElements.length; i < len; i++) { + var elements = unsafeElements[i].querySelectorAll('*'); + + for (var j = 0, len2 = elements.length; j < len2; j++) { + var el = elements[j]; + var elName = el.nodeName.toLowerCase(); + + if (whitelistKeys.indexOf(elName) === -1) { + el.parentNode.removeChild(el); + + continue; + } + + var attributeList = [].slice.call(el.attributes); + var whitelistedAttributes = [].concat(whiteList['*'] || [], whiteList[elName] || []); + + for (var k = 0, len3 = attributeList.length; k < len3; k++) { + var attr = attributeList[k]; + + if (!allowedAttribute(attr, whitelistedAttributes)) { + el.removeAttribute(attr.nodeName); + } + } + } + } + } + + // Polyfill for browsers with no classList support + // Remove in v2 + if (!('classList' in document.createElement('_'))) { + (function (view) { + if (!('Element' in view)) return; + + var classListProp = 'classList', + protoProp = 'prototype', + elemCtrProto = view.Element[protoProp], + objCtr = Object, + classListGetter = function () { + var $elem = $(this); + + return { + add: function (classes) { + classes = Array.prototype.slice.call(arguments).join(' '); + return $elem.addClass(classes); + }, + remove: function (classes) { + classes = Array.prototype.slice.call(arguments).join(' '); + return $elem.removeClass(classes); + }, + toggle: function (classes, force) { + return $elem.toggleClass(classes, force); + }, + contains: function (classes) { + return $elem.hasClass(classes); + } + } + }; + + if (objCtr.defineProperty) { + var classListPropDesc = { + get: classListGetter, + enumerable: true, + configurable: true + }; + try { + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } catch (ex) { // IE 8 doesn't support enumerable:true + // adding undefined to fight this issue https://github.com/eligrey/classList.js/issues/36 + // modernie IE8-MSW7 machine has IE8 8.0.6001.18702 and is affected + if (ex.number === undefined || ex.number === -0x7FF5EC54) { + classListPropDesc.enumerable = false; + objCtr.defineProperty(elemCtrProto, classListProp, classListPropDesc); + } + } + } else if (objCtr[protoProp].__defineGetter__) { + elemCtrProto.__defineGetter__(classListProp, classListGetter); + } + }(window)); + } + + var testElement = document.createElement('_'); + + testElement.classList.add('c1', 'c2'); + + if (!testElement.classList.contains('c2')) { + var _add = DOMTokenList.prototype.add, + _remove = DOMTokenList.prototype.remove; + + DOMTokenList.prototype.add = function () { + Array.prototype.forEach.call(arguments, _add.bind(this)); + } + + DOMTokenList.prototype.remove = function () { + Array.prototype.forEach.call(arguments, _remove.bind(this)); + } + } + + testElement.classList.toggle('c3', false); + + // Polyfill for IE 10 and Firefox <24, where classList.toggle does not + // support the second argument. + if (testElement.classList.contains('c3')) { + var _toggle = DOMTokenList.prototype.toggle; + + DOMTokenList.prototype.toggle = function (token, force) { + if (1 in arguments && !this.contains(token) === !force) { + return force; + } else { + return _toggle.call(this, token); + } + }; + } + + testElement = null; + + // shallow array comparison + function isEqual (array1, array2) { + return array1.length === array2.length && array1.every(function (element, index) { + return element === array2[index]; + }); + }; + + // + if (!String.prototype.startsWith) { + (function () { + 'use strict'; // needed to support `apply`/`call` with `undefined`/`null` + var defineProperty = (function () { + // IE 8 only supports `Object.defineProperty` on DOM elements + try { + var object = {}; + var $defineProperty = Object.defineProperty; + var result = $defineProperty(object, object, object) && $defineProperty; + } catch (error) { + } + return result; + }()); + var toString = {}.toString; + var startsWith = function (search) { + if (this == null) { + throw new TypeError(); + } + var string = String(this); + if (search && toString.call(search) == '[object RegExp]') { + throw new TypeError(); + } + var stringLength = string.length; + var searchString = String(search); + var searchLength = searchString.length; + var position = arguments.length > 1 ? arguments[1] : undefined; + // `ToInteger` + var pos = position ? Number(position) : 0; + if (pos != pos) { // better `isNaN` + pos = 0; + } + var start = Math.min(Math.max(pos, 0), stringLength); + // Avoid the `indexOf` call if no match is possible + if (searchLength + start > stringLength) { + return false; + } + var index = -1; + while (++index < searchLength) { + if (string.charCodeAt(start + index) != searchString.charCodeAt(index)) { + return false; + } + } + return true; + }; + if (defineProperty) { + defineProperty(String.prototype, 'startsWith', { + 'value': startsWith, + 'configurable': true, + 'writable': true + }); + } else { + String.prototype.startsWith = startsWith; + } + }()); + } + + if (!Object.keys) { + Object.keys = function ( + o, // object + k, // key + r // result array + ) { + // initialize object and result + r = []; + // iterate over object keys + for (k in o) { + // fill result array with non-prototypical keys + r.hasOwnProperty.call(o, k) && r.push(k); + } + // return result + return r; + }; + } + + if (HTMLSelectElement && !HTMLSelectElement.prototype.hasOwnProperty('selectedOptions')) { + Object.defineProperty(HTMLSelectElement.prototype, 'selectedOptions', { + get: function () { + return this.querySelectorAll(':checked'); + } + }); + } + + function getSelectedOptions (select, ignoreDisabled) { + var selectedOptions = select.selectedOptions, + options = [], + opt; + + if (ignoreDisabled) { + for (var i = 0, len = selectedOptions.length; i < len; i++) { + opt = selectedOptions[i]; + + if (!(opt.disabled || opt.parentNode.tagName === 'OPTGROUP' && opt.parentNode.disabled)) { + options.push(opt); + } + } + + return options; + } + + return selectedOptions; + } + + // much faster than $.val() + function getSelectValues (select, selectedOptions) { + var value = [], + options = selectedOptions || select.selectedOptions, + opt; + + for (var i = 0, len = options.length; i < len; i++) { + opt = options[i]; + + if (!(opt.disabled || opt.parentNode.tagName === 'OPTGROUP' && opt.parentNode.disabled)) { + value.push(opt.value); + } + } + + if (!select.multiple) { + return !value.length ? null : value[0]; + } + + return value; + } + + // set data-selected on select element if the value has been programmatically selected + // prior to initialization of bootstrap-select + // * consider removing or replacing an alternative method * + var valHooks = { + useDefault: false, + _set: $.valHooks.select.set + }; + + $.valHooks.select.set = function (elem, value) { + if (value && !valHooks.useDefault) $(elem).data('selected', true); + + return valHooks._set.apply(this, arguments); + }; + + var changedArguments = null; + + var EventIsSupported = (function () { + try { + new Event('change'); + return true; + } catch (e) { + return false; + } + })(); + + $.fn.triggerNative = function (eventName) { + var el = this[0], + event; + + if (el.dispatchEvent) { // for modern browsers & IE9+ + if (EventIsSupported) { + // For modern browsers + event = new Event(eventName, { + bubbles: true + }); + } else { + // For IE since it doesn't support Event constructor + event = document.createEvent('Event'); + event.initEvent(eventName, true, false); + } + + el.dispatchEvent(event); + } else if (el.fireEvent) { // for IE8 + event = document.createEventObject(); + event.eventType = eventName; + el.fireEvent('on' + eventName, event); + } else { + // fall back to jQuery.trigger + this.trigger(eventName); + } + }; + // + + function stringSearch (li, searchString, method, normalize) { + var stringTypes = [ + 'display', + 'subtext', + 'tokens' + ], + searchSuccess = false; + + for (var i = 0; i < stringTypes.length; i++) { + var stringType = stringTypes[i], + string = li[stringType]; + + if (string) { + string = string.toString(); + + // Strip HTML tags. This isn't perfect, but it's much faster than any other method + if (stringType === 'display') { + string = string.replace(/<[^>]+>/g, ''); + } + + if (normalize) string = normalizeToBase(string); + string = string.toUpperCase(); + + if (method === 'contains') { + searchSuccess = string.indexOf(searchString) >= 0; + } else { + searchSuccess = string.startsWith(searchString); + } + + if (searchSuccess) break; + } + } + + return searchSuccess; + } + + function toInteger (value) { + return parseInt(value, 10) || 0; + } + + // Borrowed from Lodash (_.deburr) + /** Used to map Latin Unicode letters to basic Latin letters. */ + var deburredLetters = { + // Latin-1 Supplement block. + '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A', + '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a', + '\xc7': 'C', '\xe7': 'c', + '\xd0': 'D', '\xf0': 'd', + '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E', + '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e', + '\xcc': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I', + '\xec': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i', + '\xd1': 'N', '\xf1': 'n', + '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O', + '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o', + '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U', + '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u', + '\xdd': 'Y', '\xfd': 'y', '\xff': 'y', + '\xc6': 'Ae', '\xe6': 'ae', + '\xde': 'Th', '\xfe': 'th', + '\xdf': 'ss', + // Latin Extended-A block. + '\u0100': 'A', '\u0102': 'A', '\u0104': 'A', + '\u0101': 'a', '\u0103': 'a', '\u0105': 'a', + '\u0106': 'C', '\u0108': 'C', '\u010a': 'C', '\u010c': 'C', + '\u0107': 'c', '\u0109': 'c', '\u010b': 'c', '\u010d': 'c', + '\u010e': 'D', '\u0110': 'D', '\u010f': 'd', '\u0111': 'd', + '\u0112': 'E', '\u0114': 'E', '\u0116': 'E', '\u0118': 'E', '\u011a': 'E', + '\u0113': 'e', '\u0115': 'e', '\u0117': 'e', '\u0119': 'e', '\u011b': 'e', + '\u011c': 'G', '\u011e': 'G', '\u0120': 'G', '\u0122': 'G', + '\u011d': 'g', '\u011f': 'g', '\u0121': 'g', '\u0123': 'g', + '\u0124': 'H', '\u0126': 'H', '\u0125': 'h', '\u0127': 'h', + '\u0128': 'I', '\u012a': 'I', '\u012c': 'I', '\u012e': 'I', '\u0130': 'I', + '\u0129': 'i', '\u012b': 'i', '\u012d': 'i', '\u012f': 'i', '\u0131': 'i', + '\u0134': 'J', '\u0135': 'j', + '\u0136': 'K', '\u0137': 'k', '\u0138': 'k', + '\u0139': 'L', '\u013b': 'L', '\u013d': 'L', '\u013f': 'L', '\u0141': 'L', + '\u013a': 'l', '\u013c': 'l', '\u013e': 'l', '\u0140': 'l', '\u0142': 'l', + '\u0143': 'N', '\u0145': 'N', '\u0147': 'N', '\u014a': 'N', + '\u0144': 'n', '\u0146': 'n', '\u0148': 'n', '\u014b': 'n', + '\u014c': 'O', '\u014e': 'O', '\u0150': 'O', + '\u014d': 'o', '\u014f': 'o', '\u0151': 'o', + '\u0154': 'R', '\u0156': 'R', '\u0158': 'R', + '\u0155': 'r', '\u0157': 'r', '\u0159': 'r', + '\u015a': 'S', '\u015c': 'S', '\u015e': 'S', '\u0160': 'S', + '\u015b': 's', '\u015d': 's', '\u015f': 's', '\u0161': 's', + '\u0162': 'T', '\u0164': 'T', '\u0166': 'T', + '\u0163': 't', '\u0165': 't', '\u0167': 't', + '\u0168': 'U', '\u016a': 'U', '\u016c': 'U', '\u016e': 'U', '\u0170': 'U', '\u0172': 'U', + '\u0169': 'u', '\u016b': 'u', '\u016d': 'u', '\u016f': 'u', '\u0171': 'u', '\u0173': 'u', + '\u0174': 'W', '\u0175': 'w', + '\u0176': 'Y', '\u0177': 'y', '\u0178': 'Y', + '\u0179': 'Z', '\u017b': 'Z', '\u017d': 'Z', + '\u017a': 'z', '\u017c': 'z', '\u017e': 'z', + '\u0132': 'IJ', '\u0133': 'ij', + '\u0152': 'Oe', '\u0153': 'oe', + '\u0149': "'n", '\u017f': 's' + }; + + /** Used to match Latin Unicode letters (excluding mathematical operators). */ + var reLatin = /[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g; + + /** Used to compose unicode character classes. */ + var rsComboMarksRange = '\\u0300-\\u036f', + reComboHalfMarksRange = '\\ufe20-\\ufe2f', + rsComboSymbolsRange = '\\u20d0-\\u20ff', + rsComboMarksExtendedRange = '\\u1ab0-\\u1aff', + rsComboMarksSupplementRange = '\\u1dc0-\\u1dff', + rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange + rsComboMarksExtendedRange + rsComboMarksSupplementRange; + + /** Used to compose unicode capture groups. */ + var rsCombo = '[' + rsComboRange + ']'; + + /** + * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and + * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols). + */ + var reComboMark = RegExp(rsCombo, 'g'); + + function deburrLetter (key) { + return deburredLetters[key]; + }; + + function normalizeToBase (string) { + string = string.toString(); + return string && string.replace(reLatin, deburrLetter).replace(reComboMark, ''); + } + + // List of HTML entities for escaping. + var escapeMap = { + '&': '&', + '<': '<', + '>': '>', + '"': '"', + "'": ''', + '`': '`' + }; + + // Functions for escaping and unescaping strings to/from HTML interpolation. + var createEscaper = function (map) { + var escaper = function (match) { + return map[match]; + }; + // Regexes for identifying a key that needs to be escaped. + var source = '(?:' + Object.keys(map).join('|') + ')'; + var testRegexp = RegExp(source); + var replaceRegexp = RegExp(source, 'g'); + return function (string) { + string = string == null ? '' : '' + string; + return testRegexp.test(string) ? string.replace(replaceRegexp, escaper) : string; + }; + }; + + var htmlEscape = createEscaper(escapeMap); + + /** + * ------------------------------------------------------------------------ + * Constants + * ------------------------------------------------------------------------ + */ + + var keyCodeMap = { + 32: ' ', + 48: '0', + 49: '1', + 50: '2', + 51: '3', + 52: '4', + 53: '5', + 54: '6', + 55: '7', + 56: '8', + 57: '9', + 59: ';', + 65: 'A', + 66: 'B', + 67: 'C', + 68: 'D', + 69: 'E', + 70: 'F', + 71: 'G', + 72: 'H', + 73: 'I', + 74: 'J', + 75: 'K', + 76: 'L', + 77: 'M', + 78: 'N', + 79: 'O', + 80: 'P', + 81: 'Q', + 82: 'R', + 83: 'S', + 84: 'T', + 85: 'U', + 86: 'V', + 87: 'W', + 88: 'X', + 89: 'Y', + 90: 'Z', + 96: '0', + 97: '1', + 98: '2', + 99: '3', + 100: '4', + 101: '5', + 102: '6', + 103: '7', + 104: '8', + 105: '9' + }; + + var keyCodes = { + ESCAPE: 27, // KeyboardEvent.which value for Escape (Esc) key + ENTER: 13, // KeyboardEvent.which value for Enter key + SPACE: 32, // KeyboardEvent.which value for space key + TAB: 9, // KeyboardEvent.which value for tab key + ARROW_UP: 38, // KeyboardEvent.which value for up arrow key + ARROW_DOWN: 40 // KeyboardEvent.which value for down arrow key + } + + var version = { + success: false, + major: '3' + }; + + try { + version.full = ($.fn.dropdown.Constructor.VERSION || '').split(' ')[0].split('.'); + version.major = version.full[0]; + version.success = true; + } catch (err) { + // do nothing + } + + var selectId = 0; + + var EVENT_KEY = '.bs.select'; + + var classNames = { + DISABLED: 'disabled', + DIVIDER: 'divider', + SHOW: 'open', + DROPUP: 'dropup', + MENU: 'dropdown-menu', + MENURIGHT: 'dropdown-menu-right', + MENULEFT: 'dropdown-menu-left', + // to-do: replace with more advanced template/customization options + BUTTONCLASS: 'btn-default', + POPOVERHEADER: 'popover-title', + ICONBASE: 'glyphicon', + TICKICON: 'glyphicon-ok' + } + + var Selector = { + MENU: '.' + classNames.MENU + } + + var elementTemplates = { + div: document.createElement('div'), + span: document.createElement('span'), + i: document.createElement('i'), + subtext: document.createElement('small'), + a: document.createElement('a'), + li: document.createElement('li'), + whitespace: document.createTextNode('\u00A0'), + fragment: document.createDocumentFragment() + } + + elementTemplates.noResults = elementTemplates.li.cloneNode(false); + elementTemplates.noResults.className = 'no-results'; + + elementTemplates.a.setAttribute('role', 'option'); + elementTemplates.a.className = 'dropdown-item'; + + elementTemplates.subtext.className = 'text-muted'; + + elementTemplates.text = elementTemplates.span.cloneNode(false); + elementTemplates.text.className = 'text'; + + elementTemplates.checkMark = elementTemplates.span.cloneNode(false); + + var REGEXP_ARROW = new RegExp(keyCodes.ARROW_UP + '|' + keyCodes.ARROW_DOWN); + var REGEXP_TAB_OR_ESCAPE = new RegExp('^' + keyCodes.TAB + '$|' + keyCodes.ESCAPE); + + var generateOption = { + li: function (content, classes, optgroup) { + var li = elementTemplates.li.cloneNode(false); + + if (content) { + if (content.nodeType === 1 || content.nodeType === 11) { + li.appendChild(content); + } else { + li.innerHTML = content; + } + } + + if (typeof classes !== 'undefined' && classes !== '') li.className = classes; + if (typeof optgroup !== 'undefined' && optgroup !== null) li.classList.add('optgroup-' + optgroup); + + return li; + }, + + a: function (text, classes, inline) { + var a = elementTemplates.a.cloneNode(true); + + if (text) { + if (text.nodeType === 11) { + a.appendChild(text); + } else { + a.insertAdjacentHTML('beforeend', text); + } + } + + if (typeof classes !== 'undefined' && classes !== '') a.classList.add.apply(a.classList, classes.split(/\s+/)); + if (inline) a.setAttribute('style', inline); + + return a; + }, + + text: function (options, useFragment) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + if (options.content) { + textElement.innerHTML = options.content; + } else { + textElement.textContent = options.text; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + // need to use for icons in the button to prevent a breaking change + // note: switch to span in next major release + iconElement = (useFragment === true ? elementTemplates.i : elementTemplates.span).cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + } + + if (useFragment === true) { + while (textElement.childNodes.length > 0) { + elementTemplates.fragment.appendChild(textElement.childNodes[0]); + } + } else { + elementTemplates.fragment.appendChild(textElement); + } + + return elementTemplates.fragment; + }, + + label: function (options) { + var textElement = elementTemplates.text.cloneNode(false), + subtextElement, + iconElement; + + textElement.innerHTML = options.display; + + if (options.icon) { + var whitespace = elementTemplates.whitespace.cloneNode(false); + + iconElement = elementTemplates.span.cloneNode(false); + iconElement.className = this.options.iconBase + ' ' + options.icon; + + elementTemplates.fragment.appendChild(iconElement); + elementTemplates.fragment.appendChild(whitespace); + } + + if (options.subtext) { + subtextElement = elementTemplates.subtext.cloneNode(false); + subtextElement.textContent = options.subtext; + textElement.appendChild(subtextElement); + } + + elementTemplates.fragment.appendChild(textElement); + + return elementTemplates.fragment; + } + } + + function showNoResults (searchMatch, searchValue) { + if (!searchMatch.length) { + elementTemplates.noResults.innerHTML = this.options.noneResultsText.replace('{0}', '"' + htmlEscape(searchValue) + '"'); + this.$menuInner[0].firstChild.appendChild(elementTemplates.noResults); + } + } + + var Selectpicker = function (element, options) { + var that = this; + + // bootstrap-select has been initialized - revert valHooks.select.set back to its original function + if (!valHooks.useDefault) { + $.valHooks.select.set = valHooks._set; + valHooks.useDefault = true; + } + + this.$element = $(element); + this.$newElement = null; + this.$button = null; + this.$menu = null; + this.options = options; + this.selectpicker = { + main: {}, + search: {}, + current: {}, // current changes if a search is in progress + view: {}, + isSearching: false, + keydown: { + keyHistory: '', + resetKeyHistory: { + start: function () { + return setTimeout(function () { + that.selectpicker.keydown.keyHistory = ''; + }, 800); + } + } + } + }; + + this.sizeInfo = {}; + + // If we have no title yet, try to pull it from the html title attribute (jQuery doesnt' pick it up as it's not a + // data-attribute) + if (this.options.title === null) { + this.options.title = this.$element.attr('title'); + } + + // Format window padding + var winPad = this.options.windowPadding; + if (typeof winPad === 'number') { + this.options.windowPadding = [winPad, winPad, winPad, winPad]; + } + + // Expose public methods + this.val = Selectpicker.prototype.val; + this.render = Selectpicker.prototype.render; + this.refresh = Selectpicker.prototype.refresh; + this.setStyle = Selectpicker.prototype.setStyle; + this.selectAll = Selectpicker.prototype.selectAll; + this.deselectAll = Selectpicker.prototype.deselectAll; + this.destroy = Selectpicker.prototype.destroy; + this.remove = Selectpicker.prototype.remove; + this.show = Selectpicker.prototype.show; + this.hide = Selectpicker.prototype.hide; + + this.init(); + }; + + Selectpicker.VERSION = '1.13.18'; + + // part of this is duplicated in i18n/defaults-en_US.js. Make sure to update both. + Selectpicker.DEFAULTS = { + noneSelectedText: 'Nothing selected', + noneResultsText: 'No results matched {0}', + countSelectedText: function (numSelected, numTotal) { + return (numSelected == 1) ? '{0} item selected' : '{0} items selected'; + }, + maxOptionsText: function (numAll, numGroup) { + return [ + (numAll == 1) ? 'Limit reached ({n} item max)' : 'Limit reached ({n} items max)', + (numGroup == 1) ? 'Group limit reached ({n} item max)' : 'Group limit reached ({n} items max)' + ]; + }, + selectAllText: 'Select All', + deselectAllText: 'Deselect All', + doneButton: false, + doneButtonText: 'Close', + multipleSeparator: ', ', + styleBase: 'btn', + style: classNames.BUTTONCLASS, + size: 'auto', + title: null, + selectedTextFormat: 'values', + width: false, + container: false, + hideDisabled: false, + showSubtext: false, + showIcon: true, + showContent: true, + dropupAuto: true, + header: false, + liveSearch: false, + liveSearchPlaceholder: null, + liveSearchNormalize: false, + liveSearchStyle: 'contains', + actionsBox: false, + iconBase: classNames.ICONBASE, + tickIcon: classNames.TICKICON, + showTick: false, + template: { + caret: '' + }, + maxOptions: false, + mobile: false, + selectOnTab: false, + dropdownAlignRight: false, + windowPadding: 0, + virtualScroll: 600, + display: false, + sanitize: true, + sanitizeFn: null, + whiteList: DefaultWhitelist + }; + + Selectpicker.prototype = { + + constructor: Selectpicker, + + init: function () { + var that = this, + id = this.$element.attr('id'), + element = this.$element[0], + form = element.form; + + selectId++; + this.selectId = 'bs-select-' + selectId; + + element.classList.add('bs-select-hidden'); + + this.multiple = this.$element.prop('multiple'); + this.autofocus = this.$element.prop('autofocus'); + + if (element.classList.contains('show-tick')) { + this.options.showTick = true; + } + + this.$newElement = this.createDropdown(); + this.buildData(); + this.$element + .after(this.$newElement) + .prependTo(this.$newElement); + + // ensure select is associated with form element if it got unlinked after moving it inside newElement + if (form && element.form === null) { + if (!form.id) form.id = 'form-' + this.selectId; + element.setAttribute('form', form.id); + } + + this.$button = this.$newElement.children('button'); + this.$menu = this.$newElement.children(Selector.MENU); + this.$menuInner = this.$menu.children('.inner'); + this.$searchbox = this.$menu.find('input'); + + element.classList.remove('bs-select-hidden'); + + if (this.options.dropdownAlignRight === true) this.$menu[0].classList.add(classNames.MENURIGHT); + + if (typeof id !== 'undefined') { + this.$button.attr('data-id', id); + } + + this.checkDisabled(); + this.clickListener(); + + if (this.options.liveSearch) { + this.liveSearchListener(); + this.focusedParent = this.$searchbox[0]; + } else { + this.focusedParent = this.$menuInner[0]; + } + + this.setStyle(); + this.render(); + this.setWidth(); + if (this.options.container) { + this.selectPosition(); + } else { + this.$element.on('hide' + EVENT_KEY, function () { + if (that.isVirtual()) { + // empty menu on close + var menuInner = that.$menuInner[0], + emptyMenu = menuInner.firstChild.cloneNode(false); + + // replace the existing UL with an empty one - this is faster than $.empty() or innerHTML = '' + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + menuInner.scrollTop = 0; + } + }); + } + this.$menu.data('this', this); + this.$newElement.data('this', this); + if (this.options.mobile) this.mobile(); + + this.$newElement.on({ + 'hide.bs.dropdown': function (e) { + that.$element.trigger('hide' + EVENT_KEY, e); + }, + 'hidden.bs.dropdown': function (e) { + that.$element.trigger('hidden' + EVENT_KEY, e); + }, + 'show.bs.dropdown': function (e) { + that.$element.trigger('show' + EVENT_KEY, e); + }, + 'shown.bs.dropdown': function (e) { + that.$element.trigger('shown' + EVENT_KEY, e); + } + }); + + if (element.hasAttribute('required')) { + this.$element.on('invalid' + EVENT_KEY, function () { + that.$button[0].classList.add('bs-invalid'); + + that.$element + .on('shown' + EVENT_KEY + '.invalid', function () { + that.$element + .val(that.$element.val()) // set the value to hide the validation message in Chrome when menu is opened + .off('shown' + EVENT_KEY + '.invalid'); + }) + .on('rendered' + EVENT_KEY, function () { + // if select is no longer invalid, remove the bs-invalid class + if (this.validity.valid) that.$button[0].classList.remove('bs-invalid'); + that.$element.off('rendered' + EVENT_KEY); + }); + + that.$button.on('blur' + EVENT_KEY, function () { + that.$element.trigger('focus').trigger('blur'); + that.$button.off('blur' + EVENT_KEY); + }); + }); + } + + setTimeout(function () { + that.buildList(); + that.$element.trigger('loaded' + EVENT_KEY); + }); + }, + + createDropdown: function () { + // Options + // If we are multiple or showTick option is set, then add the show-tick class + var showTick = (this.multiple || this.options.showTick) ? ' show-tick' : '', + multiselectable = this.multiple ? ' aria-multiselectable="true"' : '', + inputGroup = '', + autofocus = this.autofocus ? ' autofocus' : ''; + + if (version.major < 4 && this.$element.parent().hasClass('input-group')) { + inputGroup = ' input-group-btn'; + } + + // Elements + var drop, + header = '', + searchbox = '', + actionsbox = '', + donebutton = ''; + + if (this.options.header) { + header = + '
    ' + + '' + + this.options.header + + '
    '; + } + + if (this.options.liveSearch) { + searchbox = + ''; + } + + if (this.multiple && this.options.actionsBox) { + actionsbox = + '
    ' + + '
    ' + + '' + + '' + + '
    ' + + '
    '; + } + + if (this.multiple && this.options.doneButton) { + donebutton = + '
    ' + + '
    ' + + '' + + '
    ' + + '
    '; + } + + drop = + ''; + + return $(drop); + }, + + setPositionData: function () { + this.selectpicker.view.canHighlight = []; + this.selectpicker.view.size = 0; + this.selectpicker.view.firstHighlightIndex = false; + + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var li = this.selectpicker.current.data[i], + canHighlight = true; + + if (li.type === 'divider') { + canHighlight = false; + li.height = this.sizeInfo.dividerHeight; + } else if (li.type === 'optgroup-label') { + canHighlight = false; + li.height = this.sizeInfo.dropdownHeaderHeight; + } else { + li.height = this.sizeInfo.liHeight; + } + + if (li.disabled) canHighlight = false; + + this.selectpicker.view.canHighlight.push(canHighlight); + + if (canHighlight) { + this.selectpicker.view.size++; + li.posinset = this.selectpicker.view.size; + if (this.selectpicker.view.firstHighlightIndex === false) this.selectpicker.view.firstHighlightIndex = i; + } + + li.position = (i === 0 ? 0 : this.selectpicker.current.data[i - 1].position) + li.height; + } + }, + + isVirtual: function () { + return (this.options.virtualScroll !== false) && (this.selectpicker.main.elements.length >= this.options.virtualScroll) || this.options.virtualScroll === true; + }, + + createView: function (isSearching, setSize, refresh) { + var that = this, + scrollTop = 0, + active = [], + selected, + prevActive; + + this.selectpicker.isSearching = isSearching; + this.selectpicker.current = isSearching ? this.selectpicker.search : this.selectpicker.main; + + this.setPositionData(); + + if (setSize) { + if (refresh) { + scrollTop = this.$menuInner[0].scrollTop; + } else if (!that.multiple) { + var element = that.$element[0], + selectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof selectedIndex === 'number' && that.options.size !== false) { + var selectedData = that.selectpicker.main.data[selectedIndex], + position = selectedData && selectedData.position; + + if (position) { + scrollTop = position - ((that.sizeInfo.menuInnerHeight + that.sizeInfo.liHeight) / 2); + } + } + } + } + + scroll(scrollTop, true); + + this.$menuInner.off('scroll.createView').on('scroll.createView', function (e, updateValue) { + if (!that.noScroll) scroll(this.scrollTop, updateValue); + that.noScroll = false; + }); + + function scroll (scrollTop, init) { + var size = that.selectpicker.current.elements.length, + chunks = [], + chunkSize, + chunkCount, + firstChunk, + lastChunk, + currentChunk, + prevPositions, + positionIsDifferent, + previousElements, + menuIsDifferent = true, + isVirtual = that.isVirtual(); + + that.selectpicker.view.scrollTop = scrollTop; + + chunkSize = Math.ceil(that.sizeInfo.menuInnerHeight / that.sizeInfo.liHeight * 1.5); // number of options in a chunk + chunkCount = Math.round(size / chunkSize) || 1; // number of chunks + + for (var i = 0; i < chunkCount; i++) { + var endOfChunk = (i + 1) * chunkSize; + + if (i === chunkCount - 1) { + endOfChunk = size; + } + + chunks[i] = [ + (i) * chunkSize + (!i ? 0 : 1), + endOfChunk + ]; + + if (!size) break; + + if (currentChunk === undefined && scrollTop - 1 <= that.selectpicker.current.data[endOfChunk - 1].position - that.sizeInfo.menuInnerHeight) { + currentChunk = i; + } + } + + if (currentChunk === undefined) currentChunk = 0; + + prevPositions = [that.selectpicker.view.position0, that.selectpicker.view.position1]; + + // always display previous, current, and next chunks + firstChunk = Math.max(0, currentChunk - 1); + lastChunk = Math.min(chunkCount - 1, currentChunk + 1); + + that.selectpicker.view.position0 = isVirtual === false ? 0 : (Math.max(0, chunks[firstChunk][0]) || 0); + that.selectpicker.view.position1 = isVirtual === false ? size : (Math.min(size, chunks[lastChunk][1]) || 0); + + positionIsDifferent = prevPositions[0] !== that.selectpicker.view.position0 || prevPositions[1] !== that.selectpicker.view.position1; + + if (that.activeIndex !== undefined) { + prevActive = that.selectpicker.main.elements[that.prevActiveIndex]; + active = that.selectpicker.main.elements[that.activeIndex]; + selected = that.selectpicker.main.elements[that.selectedIndex]; + + if (init) { + if (that.activeIndex !== that.selectedIndex) { + that.defocusItem(active); + } + that.activeIndex = undefined; + } + + if (that.activeIndex && that.activeIndex !== that.selectedIndex) { + that.defocusItem(selected); + } + } + + if (that.prevActiveIndex !== undefined && that.prevActiveIndex !== that.activeIndex && that.prevActiveIndex !== that.selectedIndex) { + that.defocusItem(prevActive); + } + + if (init || positionIsDifferent) { + previousElements = that.selectpicker.view.visibleElements ? that.selectpicker.view.visibleElements.slice() : []; + + if (isVirtual === false) { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements; + } else { + that.selectpicker.view.visibleElements = that.selectpicker.current.elements.slice(that.selectpicker.view.position0, that.selectpicker.view.position1); + } + + that.setOptionStatus(); + + // if searching, check to make sure the list has actually been updated before updating DOM + // this prevents unnecessary repaints + if (isSearching || (isVirtual === false && init)) menuIsDifferent = !isEqual(previousElements, that.selectpicker.view.visibleElements); + + // if virtual scroll is disabled and not searching, + // menu should never need to be updated more than once + if ((init || isVirtual === true) && menuIsDifferent) { + var menuInner = that.$menuInner[0], + menuFragment = document.createDocumentFragment(), + emptyMenu = menuInner.firstChild.cloneNode(false), + marginTop, + marginBottom, + elements = that.selectpicker.view.visibleElements, + toSanitize = []; + + // replace the existing UL with an empty one - this is faster than $.empty() + menuInner.replaceChild(emptyMenu, menuInner.firstChild); + + for (var i = 0, visibleElementsLen = elements.length; i < visibleElementsLen; i++) { + var element = elements[i], + elText, + elementData; + + if (that.options.sanitize) { + elText = element.lastChild; + + if (elText) { + elementData = that.selectpicker.current.data[i + that.selectpicker.view.position0]; + + if (elementData && elementData.content && !elementData.sanitized) { + toSanitize.push(elText); + elementData.sanitized = true; + } + } + } + + menuFragment.appendChild(element); + } + + if (that.options.sanitize && toSanitize.length) { + sanitizeHtml(toSanitize, that.options.whiteList, that.options.sanitizeFn); + } + + if (isVirtual === true) { + marginTop = (that.selectpicker.view.position0 === 0 ? 0 : that.selectpicker.current.data[that.selectpicker.view.position0 - 1].position); + marginBottom = (that.selectpicker.view.position1 > size - 1 ? 0 : that.selectpicker.current.data[size - 1].position - that.selectpicker.current.data[that.selectpicker.view.position1 - 1].position); + + menuInner.firstChild.style.marginTop = marginTop + 'px'; + menuInner.firstChild.style.marginBottom = marginBottom + 'px'; + } else { + menuInner.firstChild.style.marginTop = 0; + menuInner.firstChild.style.marginBottom = 0; + } + + menuInner.firstChild.appendChild(menuFragment); + + // if an option is encountered that is wider than the current menu width, update the menu width accordingly + // switch to ResizeObserver with increased browser support + if (isVirtual === true && that.sizeInfo.hasScrollBar) { + var menuInnerInnerWidth = menuInner.firstChild.offsetWidth; + + if (init && menuInnerInnerWidth < that.sizeInfo.menuInnerInnerWidth && that.sizeInfo.totalMenuWidth > that.sizeInfo.selectWidth) { + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } else if (menuInnerInnerWidth > that.sizeInfo.menuInnerInnerWidth) { + // set to 0 to get actual width of menu + that.$menu[0].style.minWidth = 0; + + var actualMenuWidth = menuInner.firstChild.offsetWidth; + + if (actualMenuWidth > that.sizeInfo.menuInnerInnerWidth) { + that.sizeInfo.menuInnerInnerWidth = actualMenuWidth; + menuInner.firstChild.style.minWidth = that.sizeInfo.menuInnerInnerWidth + 'px'; + } + + // reset to default CSS styling + that.$menu[0].style.minWidth = ''; + } + } + } + } + + that.prevActiveIndex = that.activeIndex; + + if (!that.options.liveSearch) { + that.$menuInner.trigger('focus'); + } else if (isSearching && init) { + var index = 0, + newActive; + + if (!that.selectpicker.view.canHighlight[index]) { + index = 1 + that.selectpicker.view.canHighlight.slice(1).indexOf(true); + } + + newActive = that.selectpicker.view.visibleElements[index]; + + that.defocusItem(that.selectpicker.view.currentActive); + + that.activeIndex = (that.selectpicker.current.data[index] || {}).index; + + that.focusItem(newActive); + } + } + + $(window) + .off('resize' + EVENT_KEY + '.' + this.selectId + '.createView') + .on('resize' + EVENT_KEY + '.' + this.selectId + '.createView', function () { + var isActive = that.$newElement.hasClass(classNames.SHOW); + + if (isActive) scroll(that.$menuInner[0].scrollTop); + }); + }, + + focusItem: function (li, liData, noStyle) { + if (li) { + liData = liData || this.selectpicker.main.data[this.activeIndex]; + var a = li.firstChild; + + if (a) { + a.setAttribute('aria-setsize', this.selectpicker.view.size); + a.setAttribute('aria-posinset', liData.posinset); + + if (noStyle !== true) { + this.focusedParent.setAttribute('aria-activedescendant', a.id); + li.classList.add('active'); + a.classList.add('active'); + } + } + } + }, + + defocusItem: function (li) { + if (li) { + li.classList.remove('active'); + if (li.firstChild) li.firstChild.classList.remove('active'); + } + }, + + setPlaceholder: function () { + var that = this, + updateIndex = false; + + if (this.options.title && !this.multiple) { + if (!this.selectpicker.view.titleOption) this.selectpicker.view.titleOption = document.createElement('option'); + + // this option doesn't create a new
  • element, but does add a new option at the start, + // so startIndex should increase to prevent having to check every option for the bs-title-option class + updateIndex = true; + + var element = this.$element[0], + selectTitleOption = false, + titleNotAppended = !this.selectpicker.view.titleOption.parentNode, + selectedIndex = element.selectedIndex, + selectedOption = element.options[selectedIndex], + navigation = window.performance && window.performance.getEntriesByType('navigation'), + // Safari doesn't support getEntriesByType('navigation') - fall back to performance.navigation + isNotBackForward = (navigation && navigation.length) ? navigation[0].type !== 'back_forward' : window.performance.navigation.type !== 2; + + if (titleNotAppended) { + // Use native JS to prepend option (faster) + this.selectpicker.view.titleOption.className = 'bs-title-option'; + this.selectpicker.view.titleOption.value = ''; + + // Check if selected or data-selected attribute is already set on an option. If not, select the titleOption option. + // the selected item may have been changed by user or programmatically before the bootstrap select plugin runs, + // if so, the select will have the data-selected attribute + selectTitleOption = !selectedOption || (selectedIndex === 0 && selectedOption.defaultSelected === false && this.$element.data('selected') === undefined); + } + + if (titleNotAppended || this.selectpicker.view.titleOption.index !== 0) { + element.insertBefore(this.selectpicker.view.titleOption, element.firstChild); + } + + // Set selected *after* appending to select, + // otherwise the option doesn't get selected in IE + // set using selectedIndex, as setting the selected attr to true here doesn't work in IE11 + if (selectTitleOption && isNotBackForward) { + element.selectedIndex = 0; + } else if (document.readyState !== 'complete') { + // if navigation type is back_forward, there's a chance the select will have its value set by BFCache + // wait for that value to be set, then run render again + window.addEventListener('pageshow', function () { + if (that.selectpicker.view.displayedValue !== element.value) that.render(); + }); + } + } + + return updateIndex; + }, + + buildData: function () { + var optionSelector = ':not([hidden]):not([data-hidden="true"])', + mainData = [], + optID = 0, + startIndex = this.setPlaceholder() ? 1 : 0; // append the titleOption if necessary and skip the first option in the loop + + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + var selectOptions = this.$element[0].querySelectorAll('select > *' + optionSelector); + + function addDivider (config) { + var previousData = mainData[mainData.length - 1]; + + // ensure optgroup doesn't create back-to-back dividers + if ( + previousData && + previousData.type === 'divider' && + (previousData.optID || config.optID) + ) { + return; + } + + config = config || {}; + config.type = 'divider'; + + mainData.push(config); + } + + function addOption (option, config) { + config = config || {}; + + config.divider = option.getAttribute('data-divider') === 'true'; + + if (config.divider) { + addDivider({ + optID: config.optID + }); + } else { + var liIndex = mainData.length, + cssText = option.style.cssText, + inlineStyle = cssText ? htmlEscape(cssText) : '', + optionClass = (option.className || '') + (config.optgroupClass || ''); + + if (config.optID) optionClass = 'opt ' + optionClass; + + config.optionClass = optionClass.trim(); + config.inlineStyle = inlineStyle; + config.text = option.textContent; + + config.content = option.getAttribute('data-content'); + config.tokens = option.getAttribute('data-tokens'); + config.subtext = option.getAttribute('data-subtext'); + config.icon = option.getAttribute('data-icon'); + + option.liIndex = liIndex; + + config.display = config.content || config.text; + config.type = 'option'; + config.index = liIndex; + config.option = option; + config.selected = !!option.selected; + config.disabled = config.disabled || !!option.disabled; + + mainData.push(config); + } + } + + function addOptgroup (index, selectOptions) { + var optgroup = selectOptions[index], + // skip placeholder option + previous = index - 1 < startIndex ? false : selectOptions[index - 1], + next = selectOptions[index + 1], + options = optgroup.querySelectorAll('option' + optionSelector); + + if (!options.length) return; + + var config = { + display: htmlEscape(optgroup.label), + subtext: optgroup.getAttribute('data-subtext'), + icon: optgroup.getAttribute('data-icon'), + type: 'optgroup-label', + optgroupClass: ' ' + (optgroup.className || '') + }, + headerIndex, + lastIndex; + + optID++; + + if (previous) { + addDivider({ optID: optID }); + } + + config.optID = optID; + + mainData.push(config); + + for (var j = 0, len = options.length; j < len; j++) { + var option = options[j]; + + if (j === 0) { + headerIndex = mainData.length - 1; + lastIndex = headerIndex + len; + } + + addOption(option, { + headerIndex: headerIndex, + lastIndex: lastIndex, + optID: config.optID, + optgroupClass: config.optgroupClass, + disabled: optgroup.disabled + }); + } + + if (next) { + addDivider({ optID: optID }); + } + } + + for (var len = selectOptions.length, i = startIndex; i < len; i++) { + var item = selectOptions[i]; + + if (item.tagName !== 'OPTGROUP') { + addOption(item, {}); + } else { + addOptgroup(i, selectOptions); + } + } + + this.selectpicker.main.data = this.selectpicker.current.data = mainData; + }, + + buildList: function () { + var that = this, + selectData = this.selectpicker.main.data, + mainElements = [], + widestOptionLength = 0; + + if ((that.options.showTick || that.multiple) && !elementTemplates.checkMark.parentNode) { + elementTemplates.checkMark.className = this.options.iconBase + ' ' + that.options.tickIcon + ' check-mark'; + elementTemplates.a.appendChild(elementTemplates.checkMark); + } + + function buildElement (item) { + var liElement, + combinedLength = 0; + + switch (item.type) { + case 'divider': + liElement = generateOption.li( + false, + classNames.DIVIDER, + (item.optID ? item.optID + 'div' : undefined) + ); + + break; + + case 'option': + liElement = generateOption.li( + generateOption.a( + generateOption.text.call(that, item), + item.optionClass, + item.inlineStyle + ), + '', + item.optID + ); + + if (liElement.firstChild) { + liElement.firstChild.id = that.selectId + '-' + item.index; + } + + break; + + case 'optgroup-label': + liElement = generateOption.li( + generateOption.label.call(that, item), + 'dropdown-header' + item.optgroupClass, + item.optID + ); + + break; + } + + item.element = liElement; + mainElements.push(liElement); + + // count the number of characters in the option - not perfect, but should work in most cases + if (item.display) combinedLength += item.display.length; + if (item.subtext) combinedLength += item.subtext.length; + // if there is an icon, ensure this option's width is checked + if (item.icon) combinedLength += 1; + + if (combinedLength > widestOptionLength) { + widestOptionLength = combinedLength; + + // guess which option is the widest + // use this when calculating menu width + // not perfect, but it's fast, and the width will be updating accordingly when scrolling + that.selectpicker.view.widestOption = mainElements[mainElements.length - 1]; + } + } + + for (var len = selectData.length, i = 0; i < len; i++) { + var item = selectData[i]; + + buildElement(item); + } + + this.selectpicker.main.elements = this.selectpicker.current.elements = mainElements; + }, + + findLis: function () { + return this.$menuInner.find('.inner > li'); + }, + + render: function () { + var that = this, + element = this.$element[0], + // ensure titleOption is appended and selected (if necessary) before getting selectedOptions + placeholderSelected = this.setPlaceholder() && element.selectedIndex === 0, + selectedOptions = getSelectedOptions(element, this.options.hideDisabled), + selectedCount = selectedOptions.length, + button = this.$button[0], + buttonInner = button.querySelector('.filter-option-inner-inner'), + multipleSeparator = document.createTextNode(this.options.multipleSeparator), + titleFragment = elementTemplates.fragment.cloneNode(false), + showCount, + countMax, + hasContent = false; + + button.classList.toggle('bs-placeholder', that.multiple ? !selectedCount : !getSelectValues(element, selectedOptions)); + + if (!that.multiple && selectedOptions.length === 1) { + that.selectpicker.view.displayedValue = getSelectValues(element, selectedOptions); + } + + if (this.options.selectedTextFormat === 'static') { + titleFragment = generateOption.text.call(this, { text: this.options.title }, true); + } else { + showCount = this.multiple && this.options.selectedTextFormat.indexOf('count') !== -1 && selectedCount > 1; + + // determine if the number of selected options will be shown (showCount === true) + if (showCount) { + countMax = this.options.selectedTextFormat.split('>'); + showCount = (countMax.length > 1 && selectedCount > countMax[1]) || (countMax.length === 1 && selectedCount >= 2); + } + + // only loop through all selected options if the count won't be shown + if (showCount === false) { + if (!placeholderSelected) { + for (var selectedIndex = 0; selectedIndex < selectedCount; selectedIndex++) { + if (selectedIndex < 50) { + var option = selectedOptions[selectedIndex], + thisData = this.selectpicker.main.data[option.liIndex], + titleOptions = {}; + + if (this.multiple && selectedIndex > 0) { + titleFragment.appendChild(multipleSeparator.cloneNode(false)); + } + + if (option.title) { + titleOptions.text = option.title; + } else if (thisData) { + if (thisData.content && that.options.showContent) { + titleOptions.content = thisData.content.toString(); + hasContent = true; + } else { + if (that.options.showIcon) { + titleOptions.icon = thisData.icon; + } + if (that.options.showSubtext && !that.multiple && thisData.subtext) titleOptions.subtext = ' ' + thisData.subtext; + titleOptions.text = option.textContent.trim(); + } + } + + titleFragment.appendChild(generateOption.text.call(this, titleOptions, true)); + } else { + break; + } + } + + // add ellipsis + if (selectedCount > 49) { + titleFragment.appendChild(document.createTextNode('...')); + } + } + } else { + var optionSelector = ':not([hidden]):not([data-hidden="true"]):not([data-divider="true"])'; + if (this.options.hideDisabled) optionSelector += ':not(:disabled)'; + + // If this is a multiselect, and selectedTextFormat is count, then show 1 of 2 selected, etc. + var totalCount = this.$element[0].querySelectorAll('select > option' + optionSelector + ', optgroup' + optionSelector + ' option' + optionSelector).length, + tr8nText = (typeof this.options.countSelectedText === 'function') ? this.options.countSelectedText(selectedCount, totalCount) : this.options.countSelectedText; + + titleFragment = generateOption.text.call(this, { + text: tr8nText.replace('{0}', selectedCount.toString()).replace('{1}', totalCount.toString()) + }, true); + } + } + + if (this.options.title == undefined) { + // use .attr to ensure undefined is returned if title attribute is not set + this.options.title = this.$element.attr('title'); + } + + // If the select doesn't have a title, then use the default, or if nothing is set at all, use noneSelectedText + if (!titleFragment.childNodes.length) { + titleFragment = generateOption.text.call(this, { + text: typeof this.options.title !== 'undefined' ? this.options.title : this.options.noneSelectedText + }, true); + } + + // strip all HTML tags and trim the result, then unescape any escaped tags + button.title = titleFragment.textContent.replace(/<[^>]*>?/g, '').trim(); + + if (this.options.sanitize && hasContent) { + sanitizeHtml([titleFragment], that.options.whiteList, that.options.sanitizeFn); + } + + buttonInner.innerHTML = ''; + buttonInner.appendChild(titleFragment); + + if (version.major < 4 && this.$newElement[0].classList.contains('bs3-has-addon')) { + var filterExpand = button.querySelector('.filter-expand'), + clone = buttonInner.cloneNode(true); + + clone.className = 'filter-expand'; + + if (filterExpand) { + button.replaceChild(clone, filterExpand); + } else { + button.appendChild(clone); + } + } + + this.$element.trigger('rendered' + EVENT_KEY); + }, + + /** + * @param [style] + * @param [status] + */ + setStyle: function (newStyle, status) { + var button = this.$button[0], + newElement = this.$newElement[0], + style = this.options.style.trim(), + buttonClass; + + if (this.$element.attr('class')) { + this.$newElement.addClass(this.$element.attr('class').replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi, '')); + } + + if (version.major < 4) { + newElement.classList.add('bs3'); + + if (newElement.parentNode.classList && newElement.parentNode.classList.contains('input-group') && + (newElement.previousElementSibling || newElement.nextElementSibling) && + (newElement.previousElementSibling || newElement.nextElementSibling).classList.contains('input-group-addon') + ) { + newElement.classList.add('bs3-has-addon'); + } + } + + if (newStyle) { + buttonClass = newStyle.trim(); + } else { + buttonClass = style; + } + + if (status == 'add') { + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } else if (status == 'remove') { + if (buttonClass) button.classList.remove.apply(button.classList, buttonClass.split(' ')); + } else { + if (style) button.classList.remove.apply(button.classList, style.split(' ')); + if (buttonClass) button.classList.add.apply(button.classList, buttonClass.split(' ')); + } + }, + + liHeight: function (refresh) { + if (!refresh && (this.options.size === false || Object.keys(this.sizeInfo).length)) return; + + var newElement = elementTemplates.div.cloneNode(false), + menu = elementTemplates.div.cloneNode(false), + menuInner = elementTemplates.div.cloneNode(false), + menuInnerInner = document.createElement('ul'), + divider = elementTemplates.li.cloneNode(false), + dropdownHeader = elementTemplates.li.cloneNode(false), + li, + a = elementTemplates.a.cloneNode(false), + text = elementTemplates.span.cloneNode(false), + header = this.options.header && this.$menu.find('.' + classNames.POPOVERHEADER).length > 0 ? this.$menu.find('.' + classNames.POPOVERHEADER)[0].cloneNode(true) : null, + search = this.options.liveSearch ? elementTemplates.div.cloneNode(false) : null, + actions = this.options.actionsBox && this.multiple && this.$menu.find('.bs-actionsbox').length > 0 ? this.$menu.find('.bs-actionsbox')[0].cloneNode(true) : null, + doneButton = this.options.doneButton && this.multiple && this.$menu.find('.bs-donebutton').length > 0 ? this.$menu.find('.bs-donebutton')[0].cloneNode(true) : null, + firstOption = this.$element.find('option')[0]; + + this.sizeInfo.selectWidth = this.$newElement[0].offsetWidth; + + text.className = 'text'; + a.className = 'dropdown-item ' + (firstOption ? firstOption.className : ''); + newElement.className = this.$menu[0].parentNode.className + ' ' + classNames.SHOW; + newElement.style.width = 0; // ensure button width doesn't affect natural width of menu when calculating + if (this.options.width === 'auto') menu.style.minWidth = 0; + menu.className = classNames.MENU + ' ' + classNames.SHOW; + menuInner.className = 'inner ' + classNames.SHOW; + menuInnerInner.className = classNames.MENU + ' inner ' + (version.major === '4' ? classNames.SHOW : ''); + divider.className = classNames.DIVIDER; + dropdownHeader.className = 'dropdown-header'; + + text.appendChild(document.createTextNode('\u200b')); + + if (this.selectpicker.current.data.length) { + for (var i = 0; i < this.selectpicker.current.data.length; i++) { + var data = this.selectpicker.current.data[i]; + if (data.type === 'option') { + li = data.element; + break; + } + } + } else { + li = elementTemplates.li.cloneNode(false); + a.appendChild(text); + li.appendChild(a); + } + + dropdownHeader.appendChild(text.cloneNode(true)); + + if (this.selectpicker.view.widestOption) { + menuInnerInner.appendChild(this.selectpicker.view.widestOption.cloneNode(true)); + } + + menuInnerInner.appendChild(li); + menuInnerInner.appendChild(divider); + menuInnerInner.appendChild(dropdownHeader); + if (header) menu.appendChild(header); + if (search) { + var input = document.createElement('input'); + search.className = 'bs-searchbox'; + input.className = 'form-control'; + search.appendChild(input); + menu.appendChild(search); + } + if (actions) menu.appendChild(actions); + menuInner.appendChild(menuInnerInner); + menu.appendChild(menuInner); + if (doneButton) menu.appendChild(doneButton); + newElement.appendChild(menu); + + document.body.appendChild(newElement); + + var liHeight = li.offsetHeight, + dropdownHeaderHeight = dropdownHeader ? dropdownHeader.offsetHeight : 0, + headerHeight = header ? header.offsetHeight : 0, + searchHeight = search ? search.offsetHeight : 0, + actionsHeight = actions ? actions.offsetHeight : 0, + doneButtonHeight = doneButton ? doneButton.offsetHeight : 0, + dividerHeight = $(divider).outerHeight(true), + // fall back to jQuery if getComputedStyle is not supported + menuStyle = window.getComputedStyle ? window.getComputedStyle(menu) : false, + menuWidth = menu.offsetWidth, + $menu = menuStyle ? null : $(menu), + menuPadding = { + vert: toInteger(menuStyle ? menuStyle.paddingTop : $menu.css('paddingTop')) + + toInteger(menuStyle ? menuStyle.paddingBottom : $menu.css('paddingBottom')) + + toInteger(menuStyle ? menuStyle.borderTopWidth : $menu.css('borderTopWidth')) + + toInteger(menuStyle ? menuStyle.borderBottomWidth : $menu.css('borderBottomWidth')), + horiz: toInteger(menuStyle ? menuStyle.paddingLeft : $menu.css('paddingLeft')) + + toInteger(menuStyle ? menuStyle.paddingRight : $menu.css('paddingRight')) + + toInteger(menuStyle ? menuStyle.borderLeftWidth : $menu.css('borderLeftWidth')) + + toInteger(menuStyle ? menuStyle.borderRightWidth : $menu.css('borderRightWidth')) + }, + menuExtras = { + vert: menuPadding.vert + + toInteger(menuStyle ? menuStyle.marginTop : $menu.css('marginTop')) + + toInteger(menuStyle ? menuStyle.marginBottom : $menu.css('marginBottom')) + 2, + horiz: menuPadding.horiz + + toInteger(menuStyle ? menuStyle.marginLeft : $menu.css('marginLeft')) + + toInteger(menuStyle ? menuStyle.marginRight : $menu.css('marginRight')) + 2 + }, + scrollBarWidth; + + menuInner.style.overflowY = 'scroll'; + + scrollBarWidth = menu.offsetWidth - menuWidth; + + document.body.removeChild(newElement); + + this.sizeInfo.liHeight = liHeight; + this.sizeInfo.dropdownHeaderHeight = dropdownHeaderHeight; + this.sizeInfo.headerHeight = headerHeight; + this.sizeInfo.searchHeight = searchHeight; + this.sizeInfo.actionsHeight = actionsHeight; + this.sizeInfo.doneButtonHeight = doneButtonHeight; + this.sizeInfo.dividerHeight = dividerHeight; + this.sizeInfo.menuPadding = menuPadding; + this.sizeInfo.menuExtras = menuExtras; + this.sizeInfo.menuWidth = menuWidth; + this.sizeInfo.menuInnerInnerWidth = menuWidth - menuPadding.horiz; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth; + this.sizeInfo.scrollBarWidth = scrollBarWidth; + this.sizeInfo.selectHeight = this.$newElement[0].offsetHeight; + + this.setPositionData(); + }, + + getSelectPosition: function () { + var that = this, + $window = $(window), + pos = that.$newElement.offset(), + $container = $(that.options.container), + containerPos; + + if (that.options.container && $container.length && !$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')); + containerPos.left += parseInt($container.css('borderLeftWidth')); + } else { + containerPos = { top: 0, left: 0 }; + } + + var winPad = that.options.windowPadding; + + this.sizeInfo.selectOffsetTop = pos.top - containerPos.top - $window.scrollTop(); + this.sizeInfo.selectOffsetBot = $window.height() - this.sizeInfo.selectOffsetTop - this.sizeInfo.selectHeight - containerPos.top - winPad[2]; + this.sizeInfo.selectOffsetLeft = pos.left - containerPos.left - $window.scrollLeft(); + this.sizeInfo.selectOffsetRight = $window.width() - this.sizeInfo.selectOffsetLeft - this.sizeInfo.selectWidth - containerPos.left - winPad[1]; + this.sizeInfo.selectOffsetTop -= winPad[0]; + this.sizeInfo.selectOffsetLeft -= winPad[3]; + }, + + setMenuSize: function (isAuto) { + this.getSelectPosition(); + + var selectWidth = this.sizeInfo.selectWidth, + liHeight = this.sizeInfo.liHeight, + headerHeight = this.sizeInfo.headerHeight, + searchHeight = this.sizeInfo.searchHeight, + actionsHeight = this.sizeInfo.actionsHeight, + doneButtonHeight = this.sizeInfo.doneButtonHeight, + divHeight = this.sizeInfo.dividerHeight, + menuPadding = this.sizeInfo.menuPadding, + menuInnerHeight, + menuHeight, + divLength = 0, + minHeight, + _minHeight, + maxHeight, + menuInnerMinHeight, + estimate, + isDropup; + + if (this.options.dropupAuto) { + // Get the estimated height of the menu without scrollbars. + // This is useful for smaller menus, where there might be plenty of room + // below the button without setting dropup, but we can't know + // the exact height of the menu until createView is called later + estimate = liHeight * this.selectpicker.current.elements.length + menuPadding.vert; + + isDropup = this.sizeInfo.selectOffsetTop - this.sizeInfo.selectOffsetBot > this.sizeInfo.menuExtras.vert && estimate + this.sizeInfo.menuExtras.vert + 50 > this.sizeInfo.selectOffsetBot; + + // ensure dropup doesn't change while searching (so menu doesn't bounce back and forth) + if (this.selectpicker.isSearching === true) { + isDropup = this.selectpicker.dropup; + } + + this.$newElement.toggleClass(classNames.DROPUP, isDropup); + this.selectpicker.dropup = isDropup; + } + + if (this.options.size === 'auto') { + _minHeight = this.selectpicker.current.elements.length > 3 ? this.sizeInfo.liHeight * 3 + this.sizeInfo.menuExtras.vert - 2 : 0; + menuHeight = this.sizeInfo.selectOffsetBot - this.sizeInfo.menuExtras.vert; + minHeight = _minHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + menuInnerMinHeight = Math.max(_minHeight - menuPadding.vert, 0); + + if (this.$newElement.hasClass(classNames.DROPUP)) { + menuHeight = this.sizeInfo.selectOffsetTop - this.sizeInfo.menuExtras.vert; + } + + maxHeight = menuHeight; + menuInnerHeight = menuHeight - headerHeight - searchHeight - actionsHeight - doneButtonHeight - menuPadding.vert; + } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { + for (var i = 0; i < this.options.size; i++) { + if (this.selectpicker.current.data[i].type === 'divider') divLength++; + } + + menuHeight = liHeight * this.options.size + divLength * divHeight + menuPadding.vert; + menuInnerHeight = menuHeight - menuPadding.vert; + maxHeight = menuHeight + headerHeight + searchHeight + actionsHeight + doneButtonHeight; + minHeight = menuInnerMinHeight = ''; + } + + this.$menu.css({ + 'max-height': maxHeight + 'px', + 'overflow': 'hidden', + 'min-height': minHeight + 'px' + }); + + this.$menuInner.css({ + 'max-height': menuInnerHeight + 'px', + 'overflow-y': 'auto', + 'min-height': menuInnerMinHeight + 'px' + }); + + // ensure menuInnerHeight is always a positive number to prevent issues calculating chunkSize in createView + this.sizeInfo.menuInnerHeight = Math.max(menuInnerHeight, 1); + + if (this.selectpicker.current.data.length && this.selectpicker.current.data[this.selectpicker.current.data.length - 1].position > this.sizeInfo.menuInnerHeight) { + this.sizeInfo.hasScrollBar = true; + this.sizeInfo.totalMenuWidth = this.sizeInfo.menuWidth + this.sizeInfo.scrollBarWidth; + } + + if (this.options.dropdownAlignRight === 'auto') { + this.$menu.toggleClass(classNames.MENURIGHT, this.sizeInfo.selectOffsetLeft > this.sizeInfo.selectOffsetRight && this.sizeInfo.selectOffsetRight < (this.sizeInfo.totalMenuWidth - selectWidth)); + } + + if (this.dropdown && this.dropdown._popper) this.dropdown._popper.update(); + }, + + setSize: function (refresh) { + this.liHeight(refresh); + + if (this.options.header) this.$menu.css('padding-top', 0); + + if (this.options.size !== false) { + var that = this, + $window = $(window); + + this.setMenuSize(); + + if (this.options.liveSearch) { + this.$searchbox + .off('input.setMenuSize propertychange.setMenuSize') + .on('input.setMenuSize propertychange.setMenuSize', function () { + return that.setMenuSize(); + }); + } + + if (this.options.size === 'auto') { + $window + .off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize') + .on('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize', function () { + return that.setMenuSize(); + }); + } else if (this.options.size && this.options.size != 'auto' && this.selectpicker.current.elements.length > this.options.size) { + $window.off('resize' + EVENT_KEY + '.' + this.selectId + '.setMenuSize' + ' scroll' + EVENT_KEY + '.' + this.selectId + '.setMenuSize'); + } + } + + this.createView(false, true, refresh); + }, + + setWidth: function () { + var that = this; + + if (this.options.width === 'auto') { + requestAnimationFrame(function () { + that.$menu.css('min-width', '0'); + + that.$element.on('loaded' + EVENT_KEY, function () { + that.liHeight(); + that.setMenuSize(); + + // Get correct width if element is hidden + var $selectClone = that.$newElement.clone().appendTo('body'), + btnWidth = $selectClone.css('width', 'auto').children('button').outerWidth(); + + $selectClone.remove(); + + // Set width to whatever's larger, button title or longest option + that.sizeInfo.selectWidth = Math.max(that.sizeInfo.totalMenuWidth, btnWidth); + that.$newElement.css('width', that.sizeInfo.selectWidth + 'px'); + }); + }); + } else if (this.options.width === 'fit') { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', '').addClass('fit-width'); + } else if (this.options.width) { + // Remove inline min-width so width can be changed from 'auto' + this.$menu.css('min-width', ''); + this.$newElement.css('width', this.options.width); + } else { + // Remove inline min-width/width so width can be changed + this.$menu.css('min-width', ''); + this.$newElement.css('width', ''); + } + // Remove fit-width class if width is changed programmatically + if (this.$newElement.hasClass('fit-width') && this.options.width !== 'fit') { + this.$newElement[0].classList.remove('fit-width'); + } + }, + + selectPosition: function () { + this.$bsContainer = $('
    '); + + var that = this, + $container = $(this.options.container), + pos, + containerPos, + actualHeight, + getPlacement = function ($element) { + var containerPosition = {}, + // fall back to dropdown's default display setting if display is not manually set + display = that.options.display || ( + // Bootstrap 3 doesn't have $.fn.dropdown.Constructor.Default + $.fn.dropdown.Constructor.Default ? $.fn.dropdown.Constructor.Default.display + : false + ); + + that.$bsContainer.addClass($element.attr('class').replace(/form-control|fit-width/gi, '')).toggleClass(classNames.DROPUP, $element.hasClass(classNames.DROPUP)); + pos = $element.offset(); + + if (!$container.is('body')) { + containerPos = $container.offset(); + containerPos.top += parseInt($container.css('borderTopWidth')) - $container.scrollTop(); + containerPos.left += parseInt($container.css('borderLeftWidth')) - $container.scrollLeft(); + } else { + containerPos = { top: 0, left: 0 }; + } + + actualHeight = $element.hasClass(classNames.DROPUP) ? 0 : $element[0].offsetHeight; + + // Bootstrap 4+ uses Popper for menu positioning + if (version.major < 4 || display === 'static') { + containerPosition.top = pos.top - containerPos.top + actualHeight; + containerPosition.left = pos.left - containerPos.left; + } + + containerPosition.width = $element[0].offsetWidth; + + that.$bsContainer.css(containerPosition); + }; + + this.$button.on('click.bs.dropdown.data-api', function () { + if (that.isDisabled()) { + return; + } + + getPlacement(that.$newElement); + + that.$bsContainer + .appendTo(that.options.container) + .toggleClass(classNames.SHOW, !that.$button.hasClass(classNames.SHOW)) + .append(that.$menu); + }); + + $(window) + .off('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId) + .on('resize' + EVENT_KEY + '.' + this.selectId + ' scroll' + EVENT_KEY + '.' + this.selectId, function () { + var isActive = that.$newElement.hasClass(classNames.SHOW); + + if (isActive) getPlacement(that.$newElement); + }); + + this.$element.on('hide' + EVENT_KEY, function () { + that.$menu.data('height', that.$menu.height()); + that.$bsContainer.detach(); + }); + }, + + setOptionStatus: function (selectedOnly) { + var that = this; + + that.noScroll = false; + + if (that.selectpicker.view.visibleElements && that.selectpicker.view.visibleElements.length) { + for (var i = 0; i < that.selectpicker.view.visibleElements.length; i++) { + var liData = that.selectpicker.current.data[i + that.selectpicker.view.position0], + option = liData.option; + + if (option) { + if (selectedOnly !== true) { + that.setDisabled( + liData.index, + liData.disabled + ); + } + + that.setSelected( + liData.index, + option.selected + ); + } + } + } + }, + + /** + * @param {number} index - the index of the option that is being changed + * @param {boolean} selected - true if the option is being selected, false if being deselected + */ + setSelected: function (index, selected) { + var li = this.selectpicker.main.elements[index], + liData = this.selectpicker.main.data[index], + activeIndexIsSet = this.activeIndex !== undefined, + thisIsActive = this.activeIndex === index, + prevActive, + a, + // if current option is already active + // OR + // if the current option is being selected, it's NOT multiple, and + // activeIndex is undefined: + // - when the menu is first being opened, OR + // - after a search has been performed, OR + // - when retainActive is false when selecting a new option (i.e. index of the newly selected option is not the same as the current activeIndex) + keepActive = thisIsActive || (selected && !this.multiple && !activeIndexIsSet); + + liData.selected = selected; + + a = li.firstChild; + + if (selected) { + this.selectedIndex = index; + } + + li.classList.toggle('selected', selected); + + if (keepActive) { + this.focusItem(li, liData); + this.selectpicker.view.currentActive = li; + this.activeIndex = index; + } else { + this.defocusItem(li); + } + + if (a) { + a.classList.toggle('selected', selected); + + if (selected) { + a.setAttribute('aria-selected', true); + } else { + if (this.multiple) { + a.setAttribute('aria-selected', false); + } else { + a.removeAttribute('aria-selected'); + } + } + } + + if (!keepActive && !activeIndexIsSet && selected && this.prevActiveIndex !== undefined) { + prevActive = this.selectpicker.main.elements[this.prevActiveIndex]; + + this.defocusItem(prevActive); + } + }, + + /** + * @param {number} index - the index of the option that is being disabled + * @param {boolean} disabled - true if the option is being disabled, false if being enabled + */ + setDisabled: function (index, disabled) { + var li = this.selectpicker.main.elements[index], + a; + + this.selectpicker.main.data[index].disabled = disabled; + + a = li.firstChild; + + li.classList.toggle(classNames.DISABLED, disabled); + + if (a) { + if (version.major === '4') a.classList.toggle(classNames.DISABLED, disabled); + + if (disabled) { + a.setAttribute('aria-disabled', disabled); + a.setAttribute('tabindex', -1); + } else { + a.removeAttribute('aria-disabled'); + a.setAttribute('tabindex', 0); + } + } + }, + + isDisabled: function () { + return this.$element[0].disabled; + }, + + checkDisabled: function () { + if (this.isDisabled()) { + this.$newElement[0].classList.add(classNames.DISABLED); + this.$button.addClass(classNames.DISABLED).attr('aria-disabled', true); + } else { + if (this.$button[0].classList.contains(classNames.DISABLED)) { + this.$newElement[0].classList.remove(classNames.DISABLED); + this.$button.removeClass(classNames.DISABLED).attr('aria-disabled', false); + } + } + }, + + clickListener: function () { + var that = this, + $document = $(document); + + $document.data('spaceSelect', false); + + this.$button.on('keyup', function (e) { + if (/(32)/.test(e.keyCode.toString(10)) && $document.data('spaceSelect')) { + e.preventDefault(); + $document.data('spaceSelect', false); + } + }); + + this.$newElement.on('show.bs.dropdown', function () { + if (version.major > 3 && !that.dropdown) { + that.dropdown = that.$button.data('bs.dropdown'); + that.dropdown._menu = that.$menu[0]; + } + }); + + this.$button.on('click.bs.dropdown.data-api', function () { + if (!that.$newElement.hasClass(classNames.SHOW)) { + that.setSize(); + } + }); + + function setFocus () { + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$menuInner.trigger('focus'); + } + } + + function checkPopperExists () { + if (that.dropdown && that.dropdown._popper && that.dropdown._popper.state.isCreated) { + setFocus(); + } else { + requestAnimationFrame(checkPopperExists); + } + } + + this.$element.on('shown' + EVENT_KEY, function () { + if (that.$menuInner[0].scrollTop !== that.selectpicker.view.scrollTop) { + that.$menuInner[0].scrollTop = that.selectpicker.view.scrollTop; + } + + if (version.major > 3) { + requestAnimationFrame(checkPopperExists); + } else { + setFocus(); + } + }); + + // ensure posinset and setsize are correct before selecting an option via a click + this.$menuInner.on('mouseenter', 'li a', function (e) { + var hoverLi = this.parentElement, + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + index = Array.prototype.indexOf.call(hoverLi.parentElement.children, hoverLi), + hoverData = that.selectpicker.current.data[index + position0]; + + that.focusItem(hoverLi, hoverData, true); + }); + + this.$menuInner.on('click', 'li a', function (e, retainActive) { + var $this = $(this), + element = that.$element[0], + position0 = that.isVirtual() ? that.selectpicker.view.position0 : 0, + clickedData = that.selectpicker.current.data[$this.parent().index() + position0], + clickedIndex = clickedData.index, + prevValue = getSelectValues(element), + prevIndex = element.selectedIndex, + prevOption = element.options[prevIndex], + triggerChange = true; + + // Don't close on multi choice menu + if (that.multiple && that.options.maxOptions !== 1) { + e.stopPropagation(); + } + + e.preventDefault(); + + // Don't run if the select is disabled + if (!that.isDisabled() && !$this.parent().hasClass(classNames.DISABLED)) { + var option = clickedData.option, + $option = $(option), + state = option.selected, + $optgroup = $option.parent('optgroup'), + $optgroupOptions = $optgroup.find('option'), + maxOptions = that.options.maxOptions, + maxOptionsGrp = $optgroup.data('maxOptions') || false; + + if (clickedIndex === that.activeIndex) retainActive = true; + + if (!retainActive) { + that.prevActiveIndex = that.activeIndex; + that.activeIndex = undefined; + } + + if (!that.multiple) { // Deselect all others if not multi select box + if (prevOption) prevOption.selected = false; + option.selected = true; + that.setSelected(clickedIndex, true); + } else { // Toggle the one we have chosen if we are multi select. + option.selected = !state; + + that.setSelected(clickedIndex, !state); + that.focusedParent.focus(); + + if (maxOptions !== false || maxOptionsGrp !== false) { + var maxReached = maxOptions < getSelectedOptions(element).length, + maxReachedGrp = maxOptionsGrp < $optgroup.find('option:selected').length; + + if ((maxOptions && maxReached) || (maxOptionsGrp && maxReachedGrp)) { + if (maxOptions && maxOptions == 1) { + element.selectedIndex = -1; + option.selected = true; + that.setOptionStatus(true); + } else if (maxOptionsGrp && maxOptionsGrp == 1) { + for (var i = 0; i < $optgroupOptions.length; i++) { + var _option = $optgroupOptions[i]; + _option.selected = false; + that.setSelected(_option.liIndex, false); + } + + option.selected = true; + that.setSelected(clickedIndex, true); + } else { + var maxOptionsText = typeof that.options.maxOptionsText === 'string' ? [that.options.maxOptionsText, that.options.maxOptionsText] : that.options.maxOptionsText, + maxOptionsArr = typeof maxOptionsText === 'function' ? maxOptionsText(maxOptions, maxOptionsGrp) : maxOptionsText, + maxTxt = maxOptionsArr[0].replace('{n}', maxOptions), + maxTxtGrp = maxOptionsArr[1].replace('{n}', maxOptionsGrp), + $notify = $('
    '); + // If {var} is set in array, replace it + /** @deprecated */ + if (maxOptionsArr[2]) { + maxTxt = maxTxt.replace('{var}', maxOptionsArr[2][maxOptions > 1 ? 0 : 1]); + maxTxtGrp = maxTxtGrp.replace('{var}', maxOptionsArr[2][maxOptionsGrp > 1 ? 0 : 1]); + } + + option.selected = false; + + that.$menu.append($notify); + + if (maxOptions && maxReached) { + $notify.append($('
    ' + maxTxt + '
    ')); + triggerChange = false; + that.$element.trigger('maxReached' + EVENT_KEY); + } + + if (maxOptionsGrp && maxReachedGrp) { + $notify.append($('
    ' + maxTxtGrp + '
    ')); + triggerChange = false; + that.$element.trigger('maxReachedGrp' + EVENT_KEY); + } + + setTimeout(function () { + that.setSelected(clickedIndex, false); + }, 10); + + $notify[0].classList.add('fadeOut'); + + setTimeout(function () { + $notify.remove(); + }, 1050); + } + } + } + } + + if (!that.multiple || (that.multiple && that.options.maxOptions === 1)) { + that.$button.trigger('focus'); + } else if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } + + // Trigger select 'change' + if (triggerChange) { + if (that.multiple || prevIndex !== element.selectedIndex) { + // $option.prop('selected') is current option state (selected/unselected). prevValue is the value of the select prior to being changed. + changedArguments = [option.index, $option.prop('selected'), prevValue]; + that.$element + .triggerNative('change'); + } + } + } + }); + + this.$menu.on('click', 'li.' + classNames.DISABLED + ' a, .' + classNames.POPOVERHEADER + ', .' + classNames.POPOVERHEADER + ' :not(.close)', function (e) { + if (e.currentTarget == this) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch && !$(e.target).hasClass('close')) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + } + }); + + this.$menuInner.on('click', '.divider, .dropdown-header', function (e) { + e.preventDefault(); + e.stopPropagation(); + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + }); + + this.$menu.on('click', '.' + classNames.POPOVERHEADER + ' .close', function () { + that.$button.trigger('click'); + }); + + this.$searchbox.on('click', function (e) { + e.stopPropagation(); + }); + + this.$menu.on('click', '.actions-btn', function (e) { + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + that.$button.trigger('focus'); + } + + e.preventDefault(); + e.stopPropagation(); + + if ($(this).hasClass('bs-select-all')) { + that.selectAll(); + } else { + that.deselectAll(); + } + }); + + this.$button + .on('focus' + EVENT_KEY, function (e) { + var tabindex = that.$element[0].getAttribute('tabindex'); + + // only change when button is actually focused + if (tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { + // apply select element's tabindex to ensure correct order is followed when tabbing to the next element + this.setAttribute('tabindex', tabindex); + // set element's tabindex to -1 to allow for reverse tabbing + that.$element[0].setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = tabindex; + } + }) + .on('blur' + EVENT_KEY, function (e) { + // revert everything to original tabindex + if (that.selectpicker.view.tabindex !== undefined && e.originalEvent && e.originalEvent.isTrusted) { + that.$element[0].setAttribute('tabindex', that.selectpicker.view.tabindex); + this.setAttribute('tabindex', -1); + that.selectpicker.view.tabindex = undefined; + } + }); + + this.$element + .on('change' + EVENT_KEY, function () { + that.render(); + that.$element.trigger('changed' + EVENT_KEY, changedArguments); + changedArguments = null; + }) + .on('focus' + EVENT_KEY, function () { + if (!that.options.mobile) that.$button[0].focus(); + }); + }, + + liveSearchListener: function () { + var that = this; + + this.$button.on('click.bs.dropdown.data-api', function () { + if (!!that.$searchbox.val()) { + that.$searchbox.val(''); + that.selectpicker.search.previousValue = undefined; + } + }); + + this.$searchbox.on('click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api', function (e) { + e.stopPropagation(); + }); + + this.$searchbox.on('input propertychange', function () { + var searchValue = that.$searchbox[0].value; + + that.selectpicker.search.elements = []; + that.selectpicker.search.data = []; + + if (searchValue) { + var i, + searchMatch = [], + q = searchValue.toUpperCase(), + cache = {}, + cacheArr = [], + searchStyle = that._searchStyle(), + normalizeSearch = that.options.liveSearchNormalize; + + if (normalizeSearch) q = normalizeToBase(q); + + for (var i = 0; i < that.selectpicker.main.data.length; i++) { + var li = that.selectpicker.main.data[i]; + + if (!cache[i]) { + cache[i] = stringSearch(li, q, searchStyle, normalizeSearch); + } + + if (cache[i] && li.headerIndex !== undefined && cacheArr.indexOf(li.headerIndex) === -1) { + if (li.headerIndex > 0) { + cache[li.headerIndex - 1] = true; + cacheArr.push(li.headerIndex - 1); + } + + cache[li.headerIndex] = true; + cacheArr.push(li.headerIndex); + + cache[li.lastIndex + 1] = true; + } + + if (cache[i] && li.type !== 'optgroup-label') cacheArr.push(i); + } + + for (var i = 0, cacheLen = cacheArr.length; i < cacheLen; i++) { + var index = cacheArr[i], + prevIndex = cacheArr[i - 1], + li = that.selectpicker.main.data[index], + liPrev = that.selectpicker.main.data[prevIndex]; + + if (li.type !== 'divider' || (li.type === 'divider' && liPrev && liPrev.type !== 'divider' && cacheLen - 1 !== i)) { + that.selectpicker.search.data.push(li); + searchMatch.push(that.selectpicker.main.elements[index]); + } + } + + that.activeIndex = undefined; + that.noScroll = true; + that.$menuInner.scrollTop(0); + that.selectpicker.search.elements = searchMatch; + that.createView(true); + showNoResults.call(that, searchMatch, searchValue); + } else if (that.selectpicker.search.previousValue) { // for IE11 (#2402) + that.$menuInner.scrollTop(0); + that.createView(false); + } + + that.selectpicker.search.previousValue = searchValue; + }); + }, + + _searchStyle: function () { + return this.options.liveSearchStyle || 'contains'; + }, + + val: function (value) { + var element = this.$element[0]; + + if (typeof value !== 'undefined') { + var prevValue = getSelectValues(element); + + changedArguments = [null, null, prevValue]; + + this.$element + .val(value) + .trigger('changed' + EVENT_KEY, changedArguments); + + if (this.$newElement.hasClass(classNames.SHOW)) { + if (this.multiple) { + this.setOptionStatus(true); + } else { + var liSelectedIndex = (element.options[element.selectedIndex] || {}).liIndex; + + if (typeof liSelectedIndex === 'number') { + this.setSelected(this.selectedIndex, false); + this.setSelected(liSelectedIndex, true); + } + } + } + + this.render(); + + changedArguments = null; + + return this.$element; + } else { + return this.$element.val(); + } + }, + + changeAll: function (status) { + if (!this.multiple) return; + if (typeof status === 'undefined') status = true; + + var element = this.$element[0], + previousSelected = 0, + currentSelected = 0, + prevValue = getSelectValues(element); + + element.classList.add('bs-select-hidden'); + + for (var i = 0, data = this.selectpicker.current.data, len = data.length; i < len; i++) { + var liData = data[i], + option = liData.option; + + if (option && !liData.disabled && liData.type !== 'divider') { + if (liData.selected) previousSelected++; + option.selected = status; + if (status === true) currentSelected++; + } + } + + element.classList.remove('bs-select-hidden'); + + if (previousSelected === currentSelected) return; + + this.setOptionStatus(); + + changedArguments = [null, null, prevValue]; + + this.$element + .triggerNative('change'); + }, + + selectAll: function () { + return this.changeAll(true); + }, + + deselectAll: function () { + return this.changeAll(false); + }, + + toggle: function (e) { + e = e || window.event; + + if (e) e.stopPropagation(); + + this.$button.trigger('click.bs.dropdown.data-api'); + }, + + keydown: function (e) { + var $this = $(this), + isToggle = $this.hasClass('dropdown-toggle'), + $parent = isToggle ? $this.closest('.dropdown') : $this.closest(Selector.MENU), + that = $parent.data('this'), + $items = that.findLis(), + index, + isActive, + liActive, + activeLi, + offset, + updateScroll = false, + downOnTab = e.which === keyCodes.TAB && !isToggle && !that.options.selectOnTab, + isArrowKey = REGEXP_ARROW.test(e.which) || downOnTab, + scrollTop = that.$menuInner[0].scrollTop, + isVirtual = that.isVirtual(), + position0 = isVirtual === true ? that.selectpicker.view.position0 : 0; + + // do nothing if a function key is pressed + if (e.which >= 112 && e.which <= 123) return; + + isActive = that.$newElement.hasClass(classNames.SHOW); + + if ( + !isActive && + ( + isArrowKey || + (e.which >= 48 && e.which <= 57) || + (e.which >= 96 && e.which <= 105) || + (e.which >= 65 && e.which <= 90) + ) + ) { + that.$button.trigger('click.bs.dropdown.data-api'); + + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + return; + } + } + + if (e.which === keyCodes.ESCAPE && isActive) { + e.preventDefault(); + that.$button.trigger('click.bs.dropdown.data-api').trigger('focus'); + } + + if (isArrowKey) { // if up or down + if (!$items.length) return; + + liActive = that.selectpicker.main.elements[that.activeIndex]; + index = liActive ? Array.prototype.indexOf.call(liActive.parentElement.children, liActive) : -1; + + if (index !== -1) { + that.defocusItem(liActive); + } + + if (e.which === keyCodes.ARROW_UP) { // up + if (index !== -1) index--; + if (index + position0 < 0) index += $items.length; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = that.selectpicker.view.canHighlight.slice(0, index + position0).lastIndexOf(true) - position0; + if (index === -1) index = $items.length - 1; + } + } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down + index++; + if (index + position0 >= that.selectpicker.view.canHighlight.length) index = that.selectpicker.view.firstHighlightIndex; + + if (!that.selectpicker.view.canHighlight[index + position0]) { + index = index + 1 + that.selectpicker.view.canHighlight.slice(index + position0 + 1).indexOf(true); + } + } + + e.preventDefault(); + + var liActiveIndex = position0 + index; + + if (e.which === keyCodes.ARROW_UP) { // up + // scroll to bottom and highlight last option + if (position0 === 0 && index === $items.length - 1) { + that.$menuInner[0].scrollTop = that.$menuInner[0].scrollHeight; + + liActiveIndex = that.selectpicker.current.elements.length - 1; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + offset = activeLi.position - activeLi.height; + + updateScroll = offset < scrollTop; + } + } else if (e.which === keyCodes.ARROW_DOWN || downOnTab) { // down + // scroll to top and highlight first option + if (index === that.selectpicker.view.firstHighlightIndex) { + that.$menuInner[0].scrollTop = 0; + + liActiveIndex = that.selectpicker.view.firstHighlightIndex; + } else { + activeLi = that.selectpicker.current.data[liActiveIndex]; + offset = activeLi.position - that.sizeInfo.menuInnerHeight; + + updateScroll = offset > scrollTop; + } + } + + liActive = that.selectpicker.current.elements[liActiveIndex]; + + that.activeIndex = that.selectpicker.current.data[liActiveIndex].index; + + that.focusItem(liActive); + + that.selectpicker.view.currentActive = liActive; + + if (updateScroll) that.$menuInner[0].scrollTop = offset; + + if (that.options.liveSearch) { + that.$searchbox.trigger('focus'); + } else { + $this.trigger('focus'); + } + } else if ( + (!$this.is('input') && !REGEXP_TAB_OR_ESCAPE.test(e.which)) || + (e.which === keyCodes.SPACE && that.selectpicker.keydown.keyHistory) + ) { + var searchMatch, + matches = [], + keyHistory; + + e.preventDefault(); + + that.selectpicker.keydown.keyHistory += keyCodeMap[e.which]; + + if (that.selectpicker.keydown.resetKeyHistory.cancel) clearTimeout(that.selectpicker.keydown.resetKeyHistory.cancel); + that.selectpicker.keydown.resetKeyHistory.cancel = that.selectpicker.keydown.resetKeyHistory.start(); + + keyHistory = that.selectpicker.keydown.keyHistory; + + // if all letters are the same, set keyHistory to just the first character when searching + if (/^(.)\1+$/.test(keyHistory)) { + keyHistory = keyHistory.charAt(0); + } + + // find matches + for (var i = 0; i < that.selectpicker.current.data.length; i++) { + var li = that.selectpicker.current.data[i], + hasMatch; + + hasMatch = stringSearch(li, keyHistory, 'startsWith', true); + + if (hasMatch && that.selectpicker.view.canHighlight[i]) { + matches.push(li.index); + } + } + + if (matches.length) { + var matchIndex = 0; + + $items.removeClass('active').find('a').removeClass('active'); + + // either only one key has been pressed or they are all the same key + if (keyHistory.length === 1) { + matchIndex = matches.indexOf(that.activeIndex); + + if (matchIndex === -1 || matchIndex === matches.length - 1) { + matchIndex = 0; + } else { + matchIndex++; + } + } + + searchMatch = matches[matchIndex]; + + activeLi = that.selectpicker.main.data[searchMatch]; + + if (scrollTop - activeLi.position > 0) { + offset = activeLi.position - activeLi.height; + updateScroll = true; + } else { + offset = activeLi.position - that.sizeInfo.menuInnerHeight; + // if the option is already visible at the current scroll position, just keep it the same + updateScroll = activeLi.position > scrollTop + that.sizeInfo.menuInnerHeight; + } + + liActive = that.selectpicker.main.elements[searchMatch]; + + that.activeIndex = matches[matchIndex]; + + that.focusItem(liActive); + + if (liActive) liActive.firstChild.focus(); + + if (updateScroll) that.$menuInner[0].scrollTop = offset; + + $this.trigger('focus'); + } + } + + // Select focused option if "Enter", "Spacebar" or "Tab" (when selectOnTab is true) are pressed inside the menu. + if ( + isActive && + ( + (e.which === keyCodes.SPACE && !that.selectpicker.keydown.keyHistory) || + e.which === keyCodes.ENTER || + (e.which === keyCodes.TAB && that.options.selectOnTab) + ) + ) { + if (e.which !== keyCodes.SPACE) e.preventDefault(); + + if (!that.options.liveSearch || e.which !== keyCodes.SPACE) { + that.$menuInner.find('.active a').trigger('click', true); // retain active class + $this.trigger('focus'); + + if (!that.options.liveSearch) { + // Prevent screen from scrolling if the user hits the spacebar + e.preventDefault(); + // Fixes spacebar selection of dropdown items in FF & IE + $(document).data('spaceSelect', true); + } + } + } + }, + + mobile: function () { + // ensure mobile is set to true if mobile function is called after init + this.options.mobile = true; + this.$element[0].classList.add('mobile-device'); + }, + + refresh: function () { + // update options if data attributes have been changed + var config = $.extend({}, this.options, this.$element.data()); + this.options = config; + + this.checkDisabled(); + this.buildData(); + this.setStyle(); + this.render(); + this.buildList(); + this.setWidth(); + + this.setSize(true); + + this.$element.trigger('refreshed' + EVENT_KEY); + }, + + hide: function () { + this.$newElement.hide(); + }, + + show: function () { + this.$newElement.show(); + }, + + remove: function () { + this.$newElement.remove(); + this.$element.remove(); + }, + + destroy: function () { + this.$newElement.before(this.$element).remove(); + + if (this.$bsContainer) { + this.$bsContainer.remove(); + } else { + this.$menu.remove(); + } + + if (this.selectpicker.view.titleOption && this.selectpicker.view.titleOption.parentNode) { + this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption); + } + + this.$element + .off(EVENT_KEY) + .removeData('selectpicker') + .removeClass('bs-select-hidden selectpicker'); + + $(window).off(EVENT_KEY + '.' + this.selectId); + } + }; + + // SELECTPICKER PLUGIN DEFINITION + // ============================== + function Plugin (option) { + // get the args of the outer function.. + var args = arguments; + // The arguments of the function are explicitly re-defined from the argument list, because the shift causes them + // to get lost/corrupted in android 2.3 and IE9 #715 #775 + var _option = option; + + [].shift.apply(args); + + // if the version was not set successfully + if (!version.success) { + // try to retreive it again + try { + version.full = ($.fn.dropdown.Constructor.VERSION || '').split(' ')[0].split('.'); + } catch (err) { + // fall back to use BootstrapVersion if set + if (Selectpicker.BootstrapVersion) { + version.full = Selectpicker.BootstrapVersion.split(' ')[0].split('.'); + } else { + version.full = [version.major, '0', '0']; + + console.warn( + 'There was an issue retrieving Bootstrap\'s version. ' + + 'Ensure Bootstrap is being loaded before bootstrap-select and there is no namespace collision. ' + + 'If loading Bootstrap asynchronously, the version may need to be manually specified via $.fn.selectpicker.Constructor.BootstrapVersion.', + err + ); + } + } + + version.major = version.full[0]; + version.success = true; + } + + if (version.major === '4') { + // some defaults need to be changed if using Bootstrap 4 + // check to see if they have already been manually changed before forcing them to update + var toUpdate = []; + + if (Selectpicker.DEFAULTS.style === classNames.BUTTONCLASS) toUpdate.push({ name: 'style', className: 'BUTTONCLASS' }); + if (Selectpicker.DEFAULTS.iconBase === classNames.ICONBASE) toUpdate.push({ name: 'iconBase', className: 'ICONBASE' }); + if (Selectpicker.DEFAULTS.tickIcon === classNames.TICKICON) toUpdate.push({ name: 'tickIcon', className: 'TICKICON' }); + + classNames.DIVIDER = 'dropdown-divider'; + classNames.SHOW = 'show'; + classNames.BUTTONCLASS = 'btn-light'; + classNames.POPOVERHEADER = 'popover-header'; + classNames.ICONBASE = ''; + classNames.TICKICON = 'bs-ok-default'; + + for (var i = 0; i < toUpdate.length; i++) { + var option = toUpdate[i]; + Selectpicker.DEFAULTS[option.name] = classNames[option.className]; + } + } + + var value; + var chain = this.each(function () { + var $this = $(this); + if ($this.is('select')) { + var data = $this.data('selectpicker'), + options = typeof _option == 'object' && _option; + + if (!data) { + var dataAttributes = $this.data(); + + for (var dataAttr in dataAttributes) { + if (Object.prototype.hasOwnProperty.call(dataAttributes, dataAttr) && $.inArray(dataAttr, DISALLOWED_ATTRIBUTES) !== -1) { + delete dataAttributes[dataAttr]; + } + } + + var config = $.extend({}, Selectpicker.DEFAULTS, $.fn.selectpicker.defaults || {}, dataAttributes, options); + config.template = $.extend({}, Selectpicker.DEFAULTS.template, ($.fn.selectpicker.defaults ? $.fn.selectpicker.defaults.template : {}), dataAttributes.template, options.template); + $this.data('selectpicker', (data = new Selectpicker(this, config))); + } else if (options) { + for (var i in options) { + if (Object.prototype.hasOwnProperty.call(options, i)) { + data.options[i] = options[i]; + } + } + } + + if (typeof _option == 'string') { + if (data[_option] instanceof Function) { + value = data[_option].apply(data, args); + } else { + value = data.options[_option]; + } + } + } + }); + + if (typeof value !== 'undefined') { + // noinspection JSUnusedAssignment + return value; + } else { + return chain; + } + } + + var old = $.fn.selectpicker; + $.fn.selectpicker = Plugin; + $.fn.selectpicker.Constructor = Selectpicker; + + // SELECTPICKER NO CONFLICT + // ======================== + $.fn.selectpicker.noConflict = function () { + $.fn.selectpicker = old; + return this; + }; + + // get Bootstrap's keydown event handler for either Bootstrap 4 or Bootstrap 3 + function keydownHandler () { + if ($.fn.dropdown) { + // wait to define until function is called in case Bootstrap isn't loaded yet + var bootstrapKeydown = $.fn.dropdown.Constructor._dataApiKeydownHandler || $.fn.dropdown.Constructor.prototype.keydown; + return bootstrapKeydown.apply(this, arguments); + } + } + + $(document) + .off('keydown.bs.dropdown.data-api') + .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > [data-toggle="dropdown"]', keydownHandler) + .on('keydown.bs.dropdown.data-api', ':not(.bootstrap-select) > .dropdown-menu', keydownHandler) + .on('keydown' + EVENT_KEY, '.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', Selectpicker.prototype.keydown) + .on('focusin.modal', '.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input', function (e) { + e.stopPropagation(); + }); + + // SELECTPICKER DATA-API + // ===================== + $(window).on('load' + EVENT_KEY + '.data-api', function () { + $('.selectpicker').each(function () { + var $selectpicker = $(this); + Plugin.call($selectpicker, $selectpicker.data()); + }) + }); +})(jQuery); + + +})); diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css new file mode 100644 index 00000000..8d0f049c --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.css @@ -0,0 +1,6 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */@-webkit-keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}@-o-keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}@keyframes bs-notify-fadeOut{0%{opacity:.9}100%{opacity:0}}.bootstrap-select>select.bs-select-hidden,select.bs-select-hidden,select.selectpicker{display:none!important}.bootstrap-select{width:220px\0;vertical-align:middle}.bootstrap-select>.dropdown-toggle{position:relative;width:100%;text-align:right;white-space:nowrap;display:-webkit-inline-box;display:-webkit-inline-flex;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.bootstrap-select>.dropdown-toggle:after{margin-top:-1px}.bootstrap-select>.dropdown-toggle.bs-placeholder,.bootstrap-select>.dropdown-toggle.bs-placeholder:active,.bootstrap-select>.dropdown-toggle.bs-placeholder:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder:hover{color:#999}.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-danger:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-dark:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-info:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-primary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-secondary:hover,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:active,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:focus,.bootstrap-select>.dropdown-toggle.bs-placeholder.btn-success:hover{color:rgba(255,255,255,.5)}.bootstrap-select>select{position:absolute!important;bottom:0;left:50%;display:block!important;width:.5px!important;height:100%!important;padding:0!important;opacity:0!important;border:none;z-index:0!important}.bootstrap-select>select.mobile-device{top:0;left:0;display:block!important;width:100%!important;z-index:2!important}.bootstrap-select.is-invalid .dropdown-toggle,.error .bootstrap-select .dropdown-toggle,.has-error .bootstrap-select .dropdown-toggle,.was-validated .bootstrap-select select:invalid+.dropdown-toggle{border-color:#b94a48}.bootstrap-select.is-valid .dropdown-toggle,.was-validated .bootstrap-select select:valid+.dropdown-toggle{border-color:#28a745}.bootstrap-select.fit-width{width:auto!important}.bootstrap-select:not([class*=col-]):not([class*=form-control]):not(.input-group-btn){width:220px}.bootstrap-select .dropdown-toggle:focus,.bootstrap-select>select.mobile-device:focus+.dropdown-toggle{outline:thin dotted #333!important;outline:5px auto -webkit-focus-ring-color!important;outline-offset:-2px}.bootstrap-select.form-control{margin-bottom:0;padding:0;border:none;height:auto}:not(.input-group)>.bootstrap-select.form-control:not([class*=col-]){width:100%}.bootstrap-select.form-control.input-group-btn{float:none;z-index:auto}.form-inline .bootstrap-select,.form-inline .bootstrap-select.form-control:not([class*=col-]){width:auto}.bootstrap-select:not(.input-group-btn),.bootstrap-select[class*=col-]{float:none;display:inline-block;margin-left:0}.bootstrap-select.dropdown-menu-right,.bootstrap-select[class*=col-].dropdown-menu-right,.row .bootstrap-select[class*=col-].dropdown-menu-right{float:right}.form-group .bootstrap-select,.form-horizontal .bootstrap-select,.form-inline .bootstrap-select{margin-bottom:0}.form-group-lg .bootstrap-select.form-control,.form-group-sm .bootstrap-select.form-control{padding:0}.form-group-lg .bootstrap-select.form-control .dropdown-toggle,.form-group-sm .bootstrap-select.form-control .dropdown-toggle{height:100%;font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-lg .dropdown-toggle,.bootstrap-select.form-control-sm .dropdown-toggle{font-size:inherit;line-height:inherit;border-radius:inherit}.bootstrap-select.form-control-sm .dropdown-toggle{padding:.25rem .5rem}.bootstrap-select.form-control-lg .dropdown-toggle{padding:.5rem 1rem}.form-inline .bootstrap-select .form-control{width:100%}.bootstrap-select.disabled,.bootstrap-select>.disabled{cursor:not-allowed}.bootstrap-select.disabled:focus,.bootstrap-select>.disabled:focus{outline:0!important}.bootstrap-select.bs-container{position:absolute;top:0;left:0;height:0!important;padding:0!important}.bootstrap-select.bs-container .dropdown-menu{z-index:1060}.bootstrap-select .dropdown-toggle .filter-option{position:static;top:0;left:0;float:left;height:100%;width:100%;text-align:left;overflow:hidden;-webkit-box-flex:0;-webkit-flex:0 1 auto;-ms-flex:0 1 auto;flex:0 1 auto}.bs3.bootstrap-select .dropdown-toggle .filter-option{padding-right:inherit}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option{position:absolute;padding-top:inherit;padding-bottom:inherit;padding-left:inherit;float:none}.input-group .bs3-has-addon.bootstrap-select .dropdown-toggle .filter-option .filter-option-inner{padding-right:inherit}.bootstrap-select .dropdown-toggle .filter-option-inner-inner{overflow:hidden}.bootstrap-select .dropdown-toggle .filter-expand{width:0!important;float:left;opacity:0!important;overflow:hidden}.bootstrap-select .dropdown-toggle .caret{position:absolute;top:50%;right:12px;margin-top:-2px;vertical-align:middle}.input-group .bootstrap-select.form-control .dropdown-toggle{border-radius:inherit}.bootstrap-select[class*=col-] .dropdown-toggle{width:100%}.bootstrap-select .dropdown-menu{min-width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .dropdown-menu>.inner:focus{outline:0!important}.bootstrap-select .dropdown-menu.inner{position:static;float:none;border:0;padding:0;margin:0;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.bootstrap-select .dropdown-menu li{position:relative}.bootstrap-select .dropdown-menu li.active small{color:rgba(255,255,255,.5)!important}.bootstrap-select .dropdown-menu li.disabled a{cursor:not-allowed}.bootstrap-select .dropdown-menu li a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.bootstrap-select .dropdown-menu li a.opt{position:relative;padding-left:2.25em}.bootstrap-select .dropdown-menu li a span.check-mark{display:none}.bootstrap-select .dropdown-menu li a span.text{display:inline-block}.bootstrap-select .dropdown-menu li small{padding-left:.5em}.bootstrap-select .dropdown-menu .notify{position:absolute;bottom:5px;width:96%;margin:0 2%;min-height:26px;padding:3px 5px;background:#f5f5f5;border:1px solid #e3e3e3;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05);pointer-events:none;opacity:.9;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bootstrap-select .dropdown-menu .notify.fadeOut{-webkit-animation:.3s linear 750ms forwards bs-notify-fadeOut;-o-animation:.3s linear 750ms forwards bs-notify-fadeOut;animation:.3s linear 750ms forwards bs-notify-fadeOut}.bootstrap-select .no-results{padding:3px;background:#f5f5f5;margin:0 5px;white-space:nowrap}.bootstrap-select.fit-width .dropdown-toggle .filter-option{position:static;display:inline;padding:0}.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner,.bootstrap-select.fit-width .dropdown-toggle .filter-option-inner-inner{display:inline}.bootstrap-select.fit-width .dropdown-toggle .bs-caret:before{content:'\00a0'}.bootstrap-select.fit-width .dropdown-toggle .caret{position:static;top:auto;margin-top:-1px}.bootstrap-select.show-tick .dropdown-menu .selected span.check-mark{position:absolute;display:inline-block;right:15px;top:5px}.bootstrap-select.show-tick .dropdown-menu li a span.text{margin-right:34px}.bootstrap-select .bs-ok-default:after{content:'';display:block;width:.5em;height:1em;border-style:solid;border-width:0 .26em .26em 0;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transform:rotate(45deg);-ms-transform:rotate(45deg);-o-transform:rotate(45deg);transform:rotate(45deg)}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle{z-index:1061}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:before{content:'';border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid rgba(204,204,204,.2);position:absolute;bottom:-4px;left:9px;display:none}.bootstrap-select.show-menu-arrow .dropdown-toggle .filter-option:after{content:'';border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #fff;position:absolute;bottom:-4px;left:10px;display:none}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:before{bottom:auto;top:-4px;border-top:7px solid rgba(204,204,204,.2);border-bottom:0}.bootstrap-select.show-menu-arrow.dropup .dropdown-toggle .filter-option:after{bottom:auto;top:-4px;border-top:6px solid #fff;border-bottom:0}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:before{right:12px;left:auto}.bootstrap-select.show-menu-arrow.pull-right .dropdown-toggle .filter-option:after{right:13px;left:auto}.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.open>.dropdown-toggle .filter-option:before,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:after,.bootstrap-select.show-menu-arrow.show>.dropdown-toggle .filter-option:before{display:block}.bs-actionsbox,.bs-donebutton,.bs-searchbox{padding:4px 8px}.bs-actionsbox{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-actionsbox .btn-group button{width:50%}.bs-donebutton{float:left;width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.bs-donebutton .btn-group button{width:100%}.bs-searchbox+.bs-actionsbox{padding:0 8px 4px}.bs-searchbox .form-control{margin-bottom:0;width:100%;float:none} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js new file mode 100644 index 00000000..46cf10e9 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-select/bootstrap-select.min.js @@ -0,0 +1,8 @@ +/*! + * Bootstrap-select v1.13.18 (https://developer.snapappointments.com/bootstrap-select) + * + * Copyright 2012-2020 SnapAppointments, LLC + * Licensed under MIT (https://github.com/snapappointments/bootstrap-select/blob/master/LICENSE) + */ + +!function(e,t){void 0===e&&void 0!==window&&(e=window),"function"==typeof define&&define.amd?define(["jquery"],function(e){return t(e)}):"object"==typeof module&&module.exports?module.exports=t(require("jquery")):t(e.jQuery)}(this,function(e){!function(P){"use strict";var d=["sanitize","whiteList","sanitizeFn"],r=["background","cite","href","itemtype","longdesc","poster","src","xlink:href"],e={"*":["class","dir","id","lang","role","tabindex","style",/^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","alt","title","width","height"],li:[],ol:[],p:[],pre:[],s:[],small:[],span:[],sub:[],sup:[],strong:[],u:[],ul:[]},l=/^(?:(?:https?|mailto|ftp|tel|file):|[^&:/?#]*(?:[/?#]|$))/gi,a=/^data:(?:image\/(?:bmp|gif|jpeg|jpg|png|tiff|webp)|video\/(?:mpeg|mp4|ogg|webm)|audio\/(?:mp3|oga|ogg|opus));base64,[a-z0-9+/]+=*$/i;function v(e,t){var i=e.nodeName.toLowerCase();if(-1!==P.inArray(i,t))return-1===P.inArray(i,r)||Boolean(e.nodeValue.match(l)||e.nodeValue.match(a));for(var s=P(t).filter(function(e,t){return t instanceof RegExp}),n=0,o=s.length;n]+>/g,"")),s&&(a=w(a)),a=a.toUpperCase(),o="contains"===i?0<=a.indexOf(t):a.startsWith(t)))break}return o}function N(e){return parseInt(e,10)||0}P.fn.triggerNative=function(e){var t,i=this[0];i.dispatchEvent?(u?t=new Event(e,{bubbles:!0}):(t=document.createEvent("Event")).initEvent(e,!0,!1),i.dispatchEvent(t)):i.fireEvent?((t=document.createEventObject()).eventType=e,i.fireEvent("on"+e,t)):this.trigger(e)};var f={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C","\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i","\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r","\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij","\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"},m=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,g=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\u1ab0-\\u1aff\\u1dc0-\\u1dff]","g");function b(e){return f[e]}function w(e){return(e=e.toString())&&e.replace(m,b).replace(g,"")}var I,x,y,$,S=(I={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},x="(?:"+Object.keys(I).join("|")+")",y=RegExp(x),$=RegExp(x,"g"),function(e){return e=null==e?"":""+e,y.test(e)?e.replace($,E):e});function E(e){return I[e]}var C={32:" ",48:"0",49:"1",50:"2",51:"3",52:"4",53:"5",54:"6",55:"7",56:"8",57:"9",59:";",65:"A",66:"B",67:"C",68:"D",69:"E",70:"F",71:"G",72:"H",73:"I",74:"J",75:"K",76:"L",77:"M",78:"N",79:"O",80:"P",81:"Q",82:"R",83:"S",84:"T",85:"U",86:"V",87:"W",88:"X",89:"Y",90:"Z",96:"0",97:"1",98:"2",99:"3",100:"4",101:"5",102:"6",103:"7",104:"8",105:"9"},A=27,L=13,D=32,H=9,B=38,R=40,M={success:!1,major:"3"};try{M.full=(P.fn.dropdown.Constructor.VERSION||"").split(" ")[0].split("."),M.major=M.full[0],M.success=!0}catch(e){}var U=0,j=".bs.select",V={DISABLED:"disabled",DIVIDER:"divider",SHOW:"open",DROPUP:"dropup",MENU:"dropdown-menu",MENURIGHT:"dropdown-menu-right",MENULEFT:"dropdown-menu-left",BUTTONCLASS:"btn-default",POPOVERHEADER:"popover-title",ICONBASE:"glyphicon",TICKICON:"glyphicon-ok"},F={MENU:"."+V.MENU},_={div:document.createElement("div"),span:document.createElement("span"),i:document.createElement("i"),subtext:document.createElement("small"),a:document.createElement("a"),li:document.createElement("li"),whitespace:document.createTextNode("\xa0"),fragment:document.createDocumentFragment()};_.noResults=_.li.cloneNode(!1),_.noResults.className="no-results",_.a.setAttribute("role","option"),_.a.className="dropdown-item",_.subtext.className="text-muted",_.text=_.span.cloneNode(!1),_.text.className="text",_.checkMark=_.span.cloneNode(!1);var G=new RegExp(B+"|"+R),q=new RegExp("^"+H+"$|"+A),K={li:function(e,t,i){var s=_.li.cloneNode(!1);return e&&(1===e.nodeType||11===e.nodeType?s.appendChild(e):s.innerHTML=e),void 0!==t&&""!==t&&(s.className=t),null!=i&&s.classList.add("optgroup-"+i),s},a:function(e,t,i){var s=_.a.cloneNode(!0);return e&&(11===e.nodeType?s.appendChild(e):s.insertAdjacentHTML("beforeend",e)),void 0!==t&&""!==t&&s.classList.add.apply(s.classList,t.split(/\s+/)),i&&s.setAttribute("style",i),s},text:function(e,t){var i,s,n=_.text.cloneNode(!1);if(e.content)n.innerHTML=e.content;else{if(n.textContent=e.text,e.icon){var o=_.whitespace.cloneNode(!1);(s=(!0===t?_.i:_.span).cloneNode(!1)).className=this.options.iconBase+" "+e.icon,_.fragment.appendChild(s),_.fragment.appendChild(o)}e.subtext&&((i=_.subtext.cloneNode(!1)).textContent=e.subtext,n.appendChild(i))}if(!0===t)for(;0'},maxOptions:!1,mobile:!1,selectOnTab:!1,dropdownAlignRight:!1,windowPadding:0,virtualScroll:600,display:!1,sanitize:!0,sanitizeFn:null,whiteList:e},Y.prototype={constructor:Y,init:function(){var i=this,e=this.$element.attr("id"),t=this.$element[0],s=t.form;U++,this.selectId="bs-select-"+U,t.classList.add("bs-select-hidden"),this.multiple=this.$element.prop("multiple"),this.autofocus=this.$element.prop("autofocus"),t.classList.contains("show-tick")&&(this.options.showTick=!0),this.$newElement=this.createDropdown(),this.buildData(),this.$element.after(this.$newElement).prependTo(this.$newElement),s&&null===t.form&&(s.id||(s.id="form-"+this.selectId),t.setAttribute("form",s.id)),this.$button=this.$newElement.children("button"),this.$menu=this.$newElement.children(F.MENU),this.$menuInner=this.$menu.children(".inner"),this.$searchbox=this.$menu.find("input"),t.classList.remove("bs-select-hidden"),!0===this.options.dropdownAlignRight&&this.$menu[0].classList.add(V.MENURIGHT),void 0!==e&&this.$button.attr("data-id",e),this.checkDisabled(),this.clickListener(),this.options.liveSearch?(this.liveSearchListener(),this.focusedParent=this.$searchbox[0]):this.focusedParent=this.$menuInner[0],this.setStyle(),this.render(),this.setWidth(),this.options.container?this.selectPosition():this.$element.on("hide"+j,function(){if(i.isVirtual()){var e=i.$menuInner[0],t=e.firstChild.cloneNode(!1);e.replaceChild(t,e.firstChild),e.scrollTop=0}}),this.$menu.data("this",this),this.$newElement.data("this",this),this.options.mobile&&this.mobile(),this.$newElement.on({"hide.bs.dropdown":function(e){i.$element.trigger("hide"+j,e)},"hidden.bs.dropdown":function(e){i.$element.trigger("hidden"+j,e)},"show.bs.dropdown":function(e){i.$element.trigger("show"+j,e)},"shown.bs.dropdown":function(e){i.$element.trigger("shown"+j,e)}}),t.hasAttribute("required")&&this.$element.on("invalid"+j,function(){i.$button[0].classList.add("bs-invalid"),i.$element.on("shown"+j+".invalid",function(){i.$element.val(i.$element.val()).off("shown"+j+".invalid")}).on("rendered"+j,function(){this.validity.valid&&i.$button[0].classList.remove("bs-invalid"),i.$element.off("rendered"+j)}),i.$button.on("blur"+j,function(){i.$element.trigger("focus").trigger("blur"),i.$button.off("blur"+j)})}),setTimeout(function(){i.buildList(),i.$element.trigger("loaded"+j)})},createDropdown:function(){var e=this.multiple||this.options.showTick?" show-tick":"",t=this.multiple?' aria-multiselectable="true"':"",i="",s=this.autofocus?" autofocus":"";M.major<4&&this.$element.parent().hasClass("input-group")&&(i=" input-group-btn");var n,o="",r="",l="",a="";return this.options.header&&(o='
    '+this.options.header+"
    "),this.options.liveSearch&&(r=''),this.multiple&&this.options.actionsBox&&(l='
    "),this.multiple&&this.options.doneButton&&(a='
    "),n='",P(n)},setPositionData:function(){this.selectpicker.view.canHighlight=[],this.selectpicker.view.size=0,this.selectpicker.view.firstHighlightIndex=!1;for(var e=0;e=this.options.virtualScroll||!0===this.options.virtualScroll},createView:function(N,e,t){var A,L,D=this,i=0,H=[];if(this.selectpicker.isSearching=N,this.selectpicker.current=N?this.selectpicker.search:this.selectpicker.main,this.setPositionData(),e)if(t)i=this.$menuInner[0].scrollTop;else if(!D.multiple){var s=D.$element[0],n=(s.options[s.selectedIndex]||{}).liIndex;if("number"==typeof n&&!1!==D.options.size){var o=D.selectpicker.main.data[n],r=o&&o.position;r&&(i=r-(D.sizeInfo.menuInnerHeight+D.sizeInfo.liHeight)/2)}}function l(e,t){var i,s,n,o,r,l,a,c,d=D.selectpicker.current.elements.length,h=[],p=!0,u=D.isVirtual();D.selectpicker.view.scrollTop=e,i=Math.ceil(D.sizeInfo.menuInnerHeight/D.sizeInfo.liHeight*1.5),s=Math.round(d/i)||1;for(var f=0;fd-1?0:D.selectpicker.current.data[d-1].position-D.selectpicker.current.data[D.selectpicker.view.position1-1].position,b.firstChild.style.marginTop=v+"px",b.firstChild.style.marginBottom=g+"px"):(b.firstChild.style.marginTop=0,b.firstChild.style.marginBottom=0),b.firstChild.appendChild(w),!0===u&&D.sizeInfo.hasScrollBar){var C=b.firstChild.offsetWidth;if(t&&CD.sizeInfo.selectWidth)b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+"px";else if(C>D.sizeInfo.menuInnerInnerWidth){D.$menu[0].style.minWidth=0;var O=b.firstChild.offsetWidth;O>D.sizeInfo.menuInnerInnerWidth&&(D.sizeInfo.menuInnerInnerWidth=O,b.firstChild.style.minWidth=D.sizeInfo.menuInnerInnerWidth+"px"),D.$menu[0].style.minWidth=""}}}if(D.prevActiveIndex=D.activeIndex,D.options.liveSearch){if(N&&t){var z,T=0;D.selectpicker.view.canHighlight[T]||(T=1+D.selectpicker.view.canHighlight.slice(1).indexOf(!0)),z=D.selectpicker.view.visibleElements[T],D.defocusItem(D.selectpicker.view.currentActive),D.activeIndex=(D.selectpicker.current.data[T]||{}).index,D.focusItem(z)}}else D.$menuInner.trigger("focus")}l(i,!0),this.$menuInner.off("scroll.createView").on("scroll.createView",function(e,t){D.noScroll||l(this.scrollTop,t),D.noScroll=!1}),P(window).off("resize"+j+"."+this.selectId+".createView").on("resize"+j+"."+this.selectId+".createView",function(){D.$newElement.hasClass(V.SHOW)&&l(D.$menuInner[0].scrollTop)})},focusItem:function(e,t,i){if(e){t=t||this.selectpicker.main.data[this.activeIndex];var s=e.firstChild;s&&(s.setAttribute("aria-setsize",this.selectpicker.view.size),s.setAttribute("aria-posinset",t.posinset),!0!==i&&(this.focusedParent.setAttribute("aria-activedescendant",s.id),e.classList.add("active"),s.classList.add("active")))}},defocusItem:function(e){e&&(e.classList.remove("active"),e.firstChild&&e.firstChild.classList.remove("active"))},setPlaceholder:function(){var e=this,t=!1;if(this.options.title&&!this.multiple){this.selectpicker.view.titleOption||(this.selectpicker.view.titleOption=document.createElement("option")),t=!0;var i=this.$element[0],s=!1,n=!this.selectpicker.view.titleOption.parentNode,o=i.selectedIndex,r=i.options[o],l=window.performance&&window.performance.getEntriesByType("navigation"),a=l&&l.length?"back_forward"!==l[0].type:2!==window.performance.navigation.type;n&&(this.selectpicker.view.titleOption.className="bs-title-option",this.selectpicker.view.titleOption.value="",s=!r||0===o&&!1===r.defaultSelected&&void 0===this.$element.data("selected")),!n&&0===this.selectpicker.view.titleOption.index||i.insertBefore(this.selectpicker.view.titleOption,i.firstChild),s&&a?i.selectedIndex=0:"complete"!==document.readyState&&window.addEventListener("pageshow",function(){e.selectpicker.view.displayedValue!==i.value&&e.render()})}return t},buildData:function(){var p=':not([hidden]):not([data-hidden="true"])',u=[],f=0,m=this.setPlaceholder()?1:0;this.options.hideDisabled&&(p+=":not(:disabled)");var e=this.$element[0].querySelectorAll("select > *"+p);function v(e){var t=u[u.length-1];t&&"divider"===t.type&&(t.optID||e.optID)||((e=e||{}).type="divider",u.push(e))}function g(e,t){if((t=t||{}).divider="true"===e.getAttribute("data-divider"),t.divider)v({optID:t.optID});else{var i=u.length,s=e.style.cssText,n=s?S(s):"",o=(e.className||"")+(t.optgroupClass||"");t.optID&&(o="opt "+o),t.optionClass=o.trim(),t.inlineStyle=n,t.text=e.textContent,t.content=e.getAttribute("data-content"),t.tokens=e.getAttribute("data-tokens"),t.subtext=e.getAttribute("data-subtext"),t.icon=e.getAttribute("data-icon"),e.liIndex=i,t.display=t.content||t.text,t.type="option",t.index=i,t.option=e,t.selected=!!e.selected,t.disabled=t.disabled||!!e.disabled,u.push(t)}}function t(e,t){var i=t[e],s=!(e-1 li")},render:function(){var e,t=this,i=this.$element[0],s=this.setPlaceholder()&&0===i.selectedIndex,n=O(i,this.options.hideDisabled),o=n.length,r=this.$button[0],l=r.querySelector(".filter-option-inner-inner"),a=document.createTextNode(this.options.multipleSeparator),c=_.fragment.cloneNode(!1),d=!1;if(r.classList.toggle("bs-placeholder",t.multiple?!o:!z(i,n)),t.multiple||1!==n.length||(t.selectpicker.view.displayedValue=z(i,n)),"static"===this.options.selectedTextFormat)c=K.text.call(this,{text:this.options.title},!0);else if(!1===(this.multiple&&-1!==this.options.selectedTextFormat.indexOf("count")&&1")).length&&o>e[1]||1===e.length&&2<=o))){if(!s){for(var h=0;h option"+m+", optgroup"+m+" option"+m).length,g="function"==typeof this.options.countSelectedText?this.options.countSelectedText(o,v):this.options.countSelectedText;c=K.text.call(this,{text:g.replace("{0}",o.toString()).replace("{1}",v.toString())},!0)}if(null==this.options.title&&(this.options.title=this.$element.attr("title")),c.childNodes.length||(c=K.text.call(this,{text:void 0!==this.options.title?this.options.title:this.options.noneSelectedText},!0)),r.title=c.textContent.replace(/<[^>]*>?/g,"").trim(),this.options.sanitize&&d&&W([c],t.options.whiteList,t.options.sanitizeFn),l.innerHTML="",l.appendChild(c),M.major<4&&this.$newElement[0].classList.contains("bs3-has-addon")){var b=r.querySelector(".filter-expand"),w=l.cloneNode(!0);w.className="filter-expand",b?r.replaceChild(w,b):r.appendChild(w)}this.$element.trigger("rendered"+j)},setStyle:function(e,t){var i,s=this.$button[0],n=this.$newElement[0],o=this.options.style.trim();this.$element.attr("class")&&this.$newElement.addClass(this.$element.attr("class").replace(/selectpicker|mobile-device|bs-select-hidden|validate\[.*\]/gi,"")),M.major<4&&(n.classList.add("bs3"),n.parentNode.classList&&n.parentNode.classList.contains("input-group")&&(n.previousElementSibling||n.nextElementSibling)&&(n.previousElementSibling||n.nextElementSibling).classList.contains("input-group-addon")&&n.classList.add("bs3-has-addon")),i=e?e.trim():o,"add"==t?i&&s.classList.add.apply(s.classList,i.split(" ")):"remove"==t?i&&s.classList.remove.apply(s.classList,i.split(" ")):(o&&s.classList.remove.apply(s.classList,o.split(" ")),i&&s.classList.add.apply(s.classList,i.split(" ")))},liHeight:function(e){if(e||!1!==this.options.size&&!Object.keys(this.sizeInfo).length){var t,i=_.div.cloneNode(!1),s=_.div.cloneNode(!1),n=_.div.cloneNode(!1),o=document.createElement("ul"),r=_.li.cloneNode(!1),l=_.li.cloneNode(!1),a=_.a.cloneNode(!1),c=_.span.cloneNode(!1),d=this.options.header&&0this.sizeInfo.menuExtras.vert&&l+this.sizeInfo.menuExtras.vert+50>this.sizeInfo.selectOffsetBot,!0===this.selectpicker.isSearching&&(a=this.selectpicker.dropup),this.$newElement.toggleClass(V.DROPUP,a),this.selectpicker.dropup=a),"auto"===this.options.size)n=3this.options.size){for(var b=0;bthis.sizeInfo.menuInnerHeight&&(this.sizeInfo.hasScrollBar=!0,this.sizeInfo.totalMenuWidth=this.sizeInfo.menuWidth+this.sizeInfo.scrollBarWidth),"auto"===this.options.dropdownAlignRight&&this.$menu.toggleClass(V.MENURIGHT,this.sizeInfo.selectOffsetLeft>this.sizeInfo.selectOffsetRight&&this.sizeInfo.selectOffsetRightthis.options.size&&i.off("resize"+j+"."+this.selectId+".setMenuSize scroll"+j+"."+this.selectId+".setMenuSize")}this.createView(!1,!0,e)},setWidth:function(){var i=this;"auto"===this.options.width?requestAnimationFrame(function(){i.$menu.css("min-width","0"),i.$element.on("loaded"+j,function(){i.liHeight(),i.setMenuSize();var e=i.$newElement.clone().appendTo("body"),t=e.css("width","auto").children("button").outerWidth();e.remove(),i.sizeInfo.selectWidth=Math.max(i.sizeInfo.totalMenuWidth,t),i.$newElement.css("width",i.sizeInfo.selectWidth+"px")})}):"fit"===this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width","").addClass("fit-width")):this.options.width?(this.$menu.css("min-width",""),this.$newElement.css("width",this.options.width)):(this.$menu.css("min-width",""),this.$newElement.css("width","")),this.$newElement.hasClass("fit-width")&&"fit"!==this.options.width&&this.$newElement[0].classList.remove("fit-width")},selectPosition:function(){this.$bsContainer=P('
    ');function e(e){var t={},i=r.options.display||!!P.fn.dropdown.Constructor.Default&&P.fn.dropdown.Constructor.Default.display;r.$bsContainer.addClass(e.attr("class").replace(/form-control|fit-width/gi,"")).toggleClass(V.DROPUP,e.hasClass(V.DROPUP)),s=e.offset(),l.is("body")?n={top:0,left:0}:((n=l.offset()).top+=parseInt(l.css("borderTopWidth"))-l.scrollTop(),n.left+=parseInt(l.css("borderLeftWidth"))-l.scrollLeft()),o=e.hasClass(V.DROPUP)?0:e[0].offsetHeight,(M.major<4||"static"===i)&&(t.top=s.top-n.top+o,t.left=s.left-n.left),t.width=e[0].offsetWidth,r.$bsContainer.css(t)}var s,n,o,r=this,l=P(this.options.container);this.$button.on("click.bs.dropdown.data-api",function(){r.isDisabled()||(e(r.$newElement),r.$bsContainer.appendTo(r.options.container).toggleClass(V.SHOW,!r.$button.hasClass(V.SHOW)).append(r.$menu))}),P(window).off("resize"+j+"."+this.selectId+" scroll"+j+"."+this.selectId).on("resize"+j+"."+this.selectId+" scroll"+j+"."+this.selectId,function(){r.$newElement.hasClass(V.SHOW)&&e(r.$newElement)}),this.$element.on("hide"+j,function(){r.$menu.data("height",r.$menu.height()),r.$bsContainer.detach()})},setOptionStatus:function(e){var t=this;if(t.noScroll=!1,t.selectpicker.view.visibleElements&&t.selectpicker.view.visibleElements.length)for(var i=0;i
    ');y[2]&&($=$.replace("{var}",y[2][1"+$+"
    ")),d=!1,C.$element.trigger("maxReached"+j)),g&&w&&(E.append(P("
    "+S+"
    ")),d=!1,C.$element.trigger("maxReachedGrp"+j)),setTimeout(function(){C.setSelected(r,!1)},10),E[0].classList.add("fadeOut"),setTimeout(function(){E.remove()},1050)}}}else c&&(c.selected=!1),h.selected=!0,C.setSelected(r,!0);!C.multiple||C.multiple&&1===C.options.maxOptions?C.$button.trigger("focus"):C.options.liveSearch&&C.$searchbox.trigger("focus"),d&&(!C.multiple&&a===s.selectedIndex||(T=[h.index,p.prop("selected"),l],C.$element.triggerNative("change")))}}),this.$menu.on("click","li."+V.DISABLED+" a, ."+V.POPOVERHEADER+", ."+V.POPOVERHEADER+" :not(.close)",function(e){e.currentTarget==this&&(e.preventDefault(),e.stopPropagation(),C.options.liveSearch&&!P(e.target).hasClass("close")?C.$searchbox.trigger("focus"):C.$button.trigger("focus"))}),this.$menuInner.on("click",".divider, .dropdown-header",function(e){e.preventDefault(),e.stopPropagation(),C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus")}),this.$menu.on("click","."+V.POPOVERHEADER+" .close",function(){C.$button.trigger("click")}),this.$searchbox.on("click",function(e){e.stopPropagation()}),this.$menu.on("click",".actions-btn",function(e){C.options.liveSearch?C.$searchbox.trigger("focus"):C.$button.trigger("focus"),e.preventDefault(),e.stopPropagation(),P(this).hasClass("bs-select-all")?C.selectAll():C.deselectAll()}),this.$button.on("focus"+j,function(e){var t=C.$element[0].getAttribute("tabindex");void 0!==t&&e.originalEvent&&e.originalEvent.isTrusted&&(this.setAttribute("tabindex",t),C.$element[0].setAttribute("tabindex",-1),C.selectpicker.view.tabindex=t)}).on("blur"+j,function(e){void 0!==C.selectpicker.view.tabindex&&e.originalEvent&&e.originalEvent.isTrusted&&(C.$element[0].setAttribute("tabindex",C.selectpicker.view.tabindex),this.setAttribute("tabindex",-1),C.selectpicker.view.tabindex=void 0)}),this.$element.on("change"+j,function(){C.render(),C.$element.trigger("changed"+j,T),T=null}).on("focus"+j,function(){C.options.mobile||C.$button[0].focus()})},liveSearchListener:function(){var u=this;this.$button.on("click.bs.dropdown.data-api",function(){u.$searchbox.val()&&(u.$searchbox.val(""),u.selectpicker.search.previousValue=void 0)}),this.$searchbox.on("click.bs.dropdown.data-api focus.bs.dropdown.data-api touchend.bs.dropdown.data-api",function(e){e.stopPropagation()}),this.$searchbox.on("input propertychange",function(){var e=u.$searchbox[0].value;if(u.selectpicker.search.elements=[],u.selectpicker.search.data=[],e){var t=[],i=e.toUpperCase(),s={},n=[],o=u._searchStyle(),r=u.options.liveSearchNormalize;r&&(i=w(i));for(var l=0;l=a.selectpicker.view.canHighlight.length&&(t=a.selectpicker.view.firstHighlightIndex),a.selectpicker.view.canHighlight[t+f]||(t=t+1+a.selectpicker.view.canHighlight.slice(t+f+1).indexOf(!0))),e.preventDefault();var m=f+t;e.which===B?0===f&&t===c.length-1?(a.$menuInner[0].scrollTop=a.$menuInner[0].scrollHeight,m=a.selectpicker.current.elements.length-1):d=(o=(n=a.selectpicker.current.data[m]).position-n.height)u+a.sizeInfo.menuInnerHeight),s=a.selectpicker.main.elements[v],a.activeIndex=b[x],a.focusItem(s),s&&s.firstChild.focus(),d&&(a.$menuInner[0].scrollTop=o),r.trigger("focus")}}i&&(e.which===D&&!a.selectpicker.keydown.keyHistory||e.which===L||e.which===H&&a.options.selectOnTab)&&(e.which!==D&&e.preventDefault(),a.options.liveSearch&&e.which===D||(a.$menuInner.find(".active a").trigger("click",!0),r.trigger("focus"),a.options.liveSearch||(e.preventDefault(),P(document).data("spaceSelect",!0))))}},mobile:function(){this.options.mobile=!0,this.$element[0].classList.add("mobile-device")},refresh:function(){var e=P.extend({},this.options,this.$element.data());this.options=e,this.checkDisabled(),this.buildData(),this.setStyle(),this.render(),this.buildList(),this.setWidth(),this.setSize(!0),this.$element.trigger("refreshed"+j)},hide:function(){this.$newElement.hide()},show:function(){this.$newElement.show()},remove:function(){this.$newElement.remove(),this.$element.remove()},destroy:function(){this.$newElement.before(this.$element).remove(),this.$bsContainer?this.$bsContainer.remove():this.$menu.remove(),this.selectpicker.view.titleOption&&this.selectpicker.view.titleOption.parentNode&&this.selectpicker.view.titleOption.parentNode.removeChild(this.selectpicker.view.titleOption),this.$element.off(j).removeData("selectpicker").removeClass("bs-select-hidden selectpicker"),P(window).off(j+"."+this.selectId)}};var J=P.fn.selectpicker;function Q(){if(P.fn.dropdown)return(P.fn.dropdown.Constructor._dataApiKeydownHandler||P.fn.dropdown.Constructor.prototype.keydown).apply(this,arguments)}P.fn.selectpicker=Z,P.fn.selectpicker.Constructor=Y,P.fn.selectpicker.noConflict=function(){return P.fn.selectpicker=J,this},P(document).off("keydown.bs.dropdown.data-api").on("keydown.bs.dropdown.data-api",':not(.bootstrap-select) > [data-toggle="dropdown"]',Q).on("keydown.bs.dropdown.data-api",":not(.bootstrap-select) > .dropdown-menu",Q).on("keydown"+j,'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',Y.prototype.keydown).on("focusin.modal",'.bootstrap-select [data-toggle="dropdown"], .bootstrap-select [role="listbox"], .bootstrap-select .bs-searchbox input',function(e){e.stopPropagation()}),P(window).on("load"+j+".data-api",function(){P(".selectpicker").each(function(){var e=P(this);Z.call(e,e.data())})})}(e)}); \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css new file mode 100644 index 00000000..e6ff6bf6 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.css @@ -0,0 +1,6 @@ +/** + * @author zhixin wen + * version: 1.18.3 + * https://github.com/wenzhixin/bootstrap-table/ + */ +.bootstrap-table .fixed-table-toolbar::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-toolbar .bs-bars,.bootstrap-table .fixed-table-toolbar .columns,.bootstrap-table .fixed-table-toolbar .search{position:relative;margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group{display:inline-block;margin-left:-1px!important}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group>.btn{border-radius:0}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:first-child>.btn{border-top-left-radius:4px;border-bottom-left-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .btn-group>.btn-group:last-child>.btn{border-top-right-radius:4px;border-bottom-right-radius:4px}.bootstrap-table .fixed-table-toolbar .columns .dropdown-menu{text-align:left;max-height:300px;overflow:auto;-ms-overflow-style:scrollbar;z-index:1001}.bootstrap-table .fixed-table-toolbar .columns label{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.428571429}.bootstrap-table .fixed-table-toolbar .columns-left{margin-right:5px}.bootstrap-table .fixed-table-toolbar .columns-right{margin-left:5px}.bootstrap-table .fixed-table-toolbar .pull-right .dropdown-menu{right:0;left:auto}.bootstrap-table .fixed-table-container{position:relative;clear:both}.bootstrap-table .fixed-table-container .table{width:100%;margin-bottom:0!important}.bootstrap-table .fixed-table-container .table td,.bootstrap-table .fixed-table-container .table th{vertical-align:middle;box-sizing:border-box}.bootstrap-table .fixed-table-container .table thead th{vertical-align:bottom;padding:0;margin:0}.bootstrap-table .fixed-table-container .table thead th:focus{outline:0 solid transparent}.bootstrap-table .fixed-table-container .table thead th.detail{width:30px}.bootstrap-table .fixed-table-container .table thead th .th-inner{padding:.75rem;vertical-align:bottom;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.bootstrap-table .fixed-table-container .table thead th .sortable{cursor:pointer;background-position:right;background-repeat:no-repeat;padding-right:30px!important}.bootstrap-table .fixed-table-container .table thead th .both{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAQAAADYWf5HAAAAkElEQVQoz7X QMQ5AQBCF4dWQSJxC5wwax1Cq1e7BAdxD5SL+Tq/QCM1oNiJidwox0355mXnG/DrEtIQ6azioNZQxI0ykPhTQIwhCR+BmBYtlK7kLJYwWCcJA9M4qdrZrd8pPjZWPtOqdRQy320YSV17OatFC4euts6z39GYMKRPCTKY9UnPQ6P+GtMRfGtPnBCiqhAeJPmkqAAAAAElFTkSuQmCC")}.bootstrap-table .fixed-table-container .table thead th .asc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZ0lEQVQ4y2NgGLKgquEuFxBPAGI2ahhWCsS/gDibUoO0gPgxEP8H4ttArEyuQYxAPBdqEAxPBImTY5gjEL9DM+wTENuQahAvEO9DMwiGdwAxOymGJQLxTyD+jgWDxCMZRsEoGAVoAADeemwtPcZI2wAAAABJRU5ErkJggg==")}.bootstrap-table .fixed-table-container .table thead th .desc{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAZUlEQVQ4y2NgGAWjYBSggaqGu5FA/BOIv2PBIPFEUgxjB+IdQPwfC94HxLykus4GiD+hGfQOiB3J8SojEE9EM2wuSJzcsFMG4ttQgx4DsRalkZENxL+AuJQaMcsGxBOAmGvopk8AVz1sLZgg0bsAAAAASUVORK5CYII= ")}.bootstrap-table .fixed-table-container .table tbody tr.selected td{background-color:rgba(0,0,0,.075)}.bootstrap-table .fixed-table-container .table tbody tr.no-records-found td{text-align:center}.bootstrap-table .fixed-table-container .table tbody tr .card-view{display:flex}.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-title{font-weight:700;display:inline-block;min-width:30%;width:auto!important;text-align:left!important}.bootstrap-table .fixed-table-container .table tbody tr .card-view .card-view-value{width:100%!important}.bootstrap-table .fixed-table-container .table .bs-checkbox{text-align:center}.bootstrap-table .fixed-table-container .table .bs-checkbox label{margin-bottom:0}.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type=checkbox],.bootstrap-table .fixed-table-container .table .bs-checkbox label input[type=radio]{margin:0 auto!important}.bootstrap-table .fixed-table-container .table.table-sm .th-inner{padding:.3rem}.bootstrap-table .fixed-table-container.fixed-height:not(.has-footer){border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height.has-card-view{border-top:1px solid #dee2e6;border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .fixed-table-border{border-left:1px solid #dee2e6;border-right:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table thead th{border-bottom:1px solid #dee2e6}.bootstrap-table .fixed-table-container.fixed-height .table-dark thead th{border-bottom:1px solid #32383e}.bootstrap-table .fixed-table-container .fixed-table-header{overflow:hidden}.bootstrap-table .fixed-table-container .fixed-table-body{overflow-x:auto;overflow-y:auto;height:100%}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading{align-items:center;background:#fff;display:flex;justify-content:center;position:absolute;bottom:0;width:100%;z-index:1000;transition:visibility 0s,opacity .15s ease-in-out;opacity:0;visibility:hidden}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.open{visibility:visible;opacity:1}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap{align-items:baseline;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .loading-text{margin-right:6px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap{align-items:center;display:flex;justify-content:center}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::before{content:"";animation-duration:1.5s;animation-iteration-count:infinite;animation-name:LOADING;background:#212529;border-radius:50%;display:block;height:5px;margin:0 4px;opacity:0;width:5px}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-dot{animation-delay:.3s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading .loading-wrap .animation-wrap::after{animation-delay:.6s}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark{background:#212529}.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-dot,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::after,.bootstrap-table .fixed-table-container .fixed-table-body .fixed-table-loading.table-dark .animation-wrap::before{background:#fff}.bootstrap-table .fixed-table-container .fixed-table-footer{overflow:hidden}.bootstrap-table .fixed-table-pagination::after{content:"";display:block;clear:both}.bootstrap-table .fixed-table-pagination>.pagination,.bootstrap-table .fixed-table-pagination>.pagination-detail{margin-top:10px;margin-bottom:10px}.bootstrap-table .fixed-table-pagination>.pagination-detail .pagination-info{line-height:34px;margin-right:5px}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list{display:inline-block}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group{position:relative;display:inline-block;vertical-align:middle}.bootstrap-table .fixed-table-pagination>.pagination-detail .page-list .btn-group .dropdown-menu{margin-bottom:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination{margin:0}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a{color:#c8c8c8}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::before{content:'\2B05'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.page-intermediate a::after{content:'\27A1'}.bootstrap-table .fixed-table-pagination>.pagination ul.pagination li.disabled a{pointer-events:none;cursor:default}.bootstrap-table.fullscreen{position:fixed;top:0;left:0;z-index:1050;width:100%!important;background:#fff;height:calc(100vh);overflow-y:scroll}.bootstrap-table.bootstrap4 .pagination-lg .page-link,.bootstrap-table.bootstrap5 .pagination-lg .page-link{padding:.5rem 1rem}.bootstrap-table.bootstrap5 .float-left{float:left}.bootstrap-table.bootstrap5 .float-right{float:right}div.fixed-table-scroll-inner{width:100%;height:200px}div.fixed-table-scroll-outer{top:0;left:0;visibility:hidden;width:200px;height:150px;overflow:hidden}@keyframes LOADING{0%{opacity:0}50%{opacity:1}to{opacity:0}} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js new file mode 100644 index 00000000..89c3b450 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/bootstrap-table.min.js @@ -0,0 +1,6 @@ +/** + * @author zhixin wen + * version: 1.18.3 + * https://github.com/wenzhixin/bootstrap-table/ + */ +function getRememberRowIds(a,b){return $.isArray(a)?props=$.map(a,function(c){return c[b]}):props=[a[b]],props}function addRememberRow(b,c){var a=null==table.options.uniqueId?table.options.columns[1].field:table.options.uniqueId,d=getRememberRowIds(b,a);-1==$.inArray(c[a],d)&&(b[b.length]=c)}function removeRememberRow(b,c){var a=null==table.options.uniqueId?table.options.columns[1].field:table.options.uniqueId,f=getRememberRowIds(b,a),d=$.inArray(c[a],f);-1!=d&&b.splice(d,1)}!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b(require("jquery")):"function"==typeof define&&define.amd?define(["jquery"],b):(a="undefined"!=typeof globalThis?globalThis:a||self,a.BootstrapTable=b(a.jQuery))}(this,function(fl){function fK(a){return a&&"object"==typeof a&&"default" in a?a:{"default":a}}function fD(a){return(fD="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(b){return typeof b}:function(b){return b&&"function"==typeof Symbol&&b.constructor===Symbol&&b!==Symbol.prototype?"symbol":typeof b})(a)}function fw(a,b){if(!(a instanceof b)){throw new TypeError("Cannot call a class as a function")}}function fu(b,c){for(var a=0;ab.length)&&(c=b.length);for(var a=0,d=Array(c);c>a;a++){d[a]=b[a]}return d}function fr(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function fG(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function fg(d,h){var c;if("undefined"==typeof Symbol||null==d[Symbol.iterator]){if(Array.isArray(d)||(c=fL(d))||h&&d&&"number"==typeof d.length){c&&(d=c);var k=0,j=function(){};return{s:j,n:function(){return k>=d.length?{done:!0}:{done:!1,value:d[k++]}},e:function(a){throw a},f:j}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var b,f=!0,g=!1;return{s:function(){c=d[Symbol.iterator]()},n:function(){var a=c.next();return f=a.done,a},e:function(a){g=!0,b=a},f:function(){try{f||null==c["return"]||c["return"]()}finally{if(g){throw b}}}}}function fO(a,b){return b={exports:{}},a(b,b.exports),b.exports}function fx(a,b){return RegExp(a,b)}var fc=fK(fl),ff="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},f2=function(a){return a&&a.Math==Math&&a},fd=f2("object"==typeof globalThis&&globalThis)||f2("object"==typeof window&&window)||f2("object"==typeof self&&self)||f2("object"==typeof ff&&ff)||function(){return this}()||Function("return this")(),fA=function(a){try{return !!a()}catch(b){return !0}},f8=!fA(function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}),f1={}.propertyIsEnumerable,gw=Object.getOwnPropertyDescriptor,f6=gw&&!f1.call({1:2},1),gk=f6?function(a){var b=gw(this,a);return !!b&&b.enumerable}:f1,gz={f:gk},gS=function(a,b){return{enumerable:!(1&a),configurable:!(2&a),writable:!(4&a),value:b}},f3={}.toString,gs=function(a){return f3.call(a).slice(8,-1)},fB="".split,fR=fA(function(){return !Object("z").propertyIsEnumerable(0)})?function(a){return"String"==gs(a)?fB.call(a,""):Object(a)}:Object,f9=function(a){if(void 0==a){throw TypeError("Can't call method on "+a)}return a},gr=function(a){return fR(f9(a))},gu=function(a){return"object"==typeof a?null!==a:"function"==typeof a},fY=function(b,c){if(!gu(b)){return b}var a,d;if(c&&"function"==typeof(a=b.toString)&&!gu(d=a.call(b))){return d}if("function"==typeof(a=b.valueOf)&&!gu(d=a.call(b))){return d}if(!c&&"function"==typeof(a=b.toString)&&!gu(d=a.call(b))){return d}throw TypeError("Can't convert object to primitive value")},gy={}.hasOwnProperty,gd=function(a,b){return gy.call(a,b)},gl=fd.document,gc=gu(gl)&&gu(gl.createElement),f0=function(a){return gc?gl.createElement(a):{}},e9=!f8&&!fA(function(){return 7!=Object.defineProperty(f0("div"),"a",{get:function(){return 7}}).a}),fq=Object.getOwnPropertyDescriptor,fX=f8?fq:function(b,c){if(b=gr(b),c=fY(c,!0),e9){try{return fq(b,c)}catch(a){}}return gd(b,c)?gS(!gz.f.call(b,c),b[c]):void 0},gp={f:fX},gf=function(a){if(!gu(a)){throw TypeError(a+" is not an object")}return a},fV=Object.defineProperty,fW=f8?fV:function(b,c,a){if(gf(b),c=fY(c,!0),gf(a),e9){try{return fV(b,c,a)}catch(d){}}if("get" in a||"set" in a){throw TypeError("Accessors not supported")}return"value" in a&&(b[c]=a.value),b},gh={f:fW},f4=f8?function(b,c,a){return gh.f(b,c,gS(1,a))}:function(b,c,a){return b[c]=a,b},fU=function(b,c){try{f4(fd,b,c)}catch(a){fd[b]=c}return c},a8="__core-js_shared__",eM=fd[a8]||fU(a8,{}),dS=eM,cJ=Function.toString;"function"!=typeof dS.inspectSource&&(dS.inspectSource=function(a){return cJ.call(a)});var cr,gF,bq,bK=dS.inspectSource,dc=fd.WeakMap,fj="function"==typeof dc&&/native code/.test(bK(dc)),d4=fO(function(a){(a.exports=function(b,c){return dS[b]||(dS[b]=void 0!==c?c:{})})("versions",[]).push({version:"3.9.1",mode:"global",copyright:"© 2021 Denis Pushkarev (zloirock.ru)"})}),aW=0,eZ=Math.random(),eA=function(a){return"Symbol("+((void 0===a?"":a)+"")+")_"+(++aW+eZ).toString(36)},cb=d4("keys"),ek=function(a){return cb[a]||(cb[a]=eA(a))},aK={},fZ=fd.WeakMap,cZ=function(a){return bq(a)?gF(a):cr(a,{})},gV=function(a){return function(c){var b;if(!gu(c)||(b=gF(c)).type!==a){throw TypeError("Incompatible receiver, "+a+" required")}return b}};if(fj){var ay=dS.state||(dS.state=new fZ),dh=ay.get,g7=ay.has,du=ay.set;cr=function(a,b){return b.facade=a,du.call(ay,a,b),b},gF=function(a){return dh.call(ay,a)||{}},bq=function(a){return g7.call(ay,a)}}else{var d8=ek("state");aK[d8]=!0,cr=function(a,b){return b.facade=a,f4(a,d8,b),b},gF=function(a){return gd(a,d8)?a[d8]:{}},bq=function(a){return gd(a,d8)}}var c2={set:cr,get:gF,has:bq,enforce:cZ,getterFor:gV},a2=fO(function(b){var c=c2.get,a=c2.enforce,d=(String+"").split("String");(b.exports=function(h,k,m,g){var i,j=g?!!g.unsafe:!1,f=g?!!g.enumerable:!1,n=g?!!g.noTargetGet:!1;return"function"==typeof m&&("string"!=typeof k||gd(m,"name")||f4(m,"name",k),i=a(m),i.source||(i.source=d.join("string"==typeof k?k:""))),h===fd?void (f?h[k]=m:fU(k,m)):(j?!n&&h[k]&&(f=!0):delete h[k],void (f?h[k]=m:f4(h,k,m)))})(Function.prototype,"toString",function(){return"function"==typeof this&&c(this).source||bK(this)})}),dV=fd,gb=function(a){return"function"==typeof a?a:void 0},bB=function(a,b){return arguments.length<2?gb(dV[a])||gb(fd[a]):dV[a]&&dV[a][b]||fd[a]&&fd[a][b]},cF=Math.ceil,dx=Math.floor,aE=function(a){return isNaN(a=+a)?0:(a>0?dx:cF)(a)},dG=Math.min,af=function(a){return a>0?dG(aE(a),9007199254740991):0},ep=Math.max,al=Math.min,aQ=function(b,c){var a=aE(b);return 0>a?ep(a+c,0):al(a,c)},cx=function(a){return function(g,c,j){var h,b=gr(g),d=af(b.length),f=aQ(j,d);if(a&&c!=c){for(;d>f;){if(h=b[f++],h!=h){return !0}}}else{for(;d>f;f++){if((a||f in b)&&b[f]===c){return a||f||0}}}return !a&&-1}},bh={includes:cx(!0),indexOf:cx(!1)},eQ=bh.indexOf,gL=function(d,f){var c,h=gr(d),g=0,b=[];for(c in h){!gd(aK,c)&&gd(h,c)&&b.push(c)}for(;f.length>g;){gd(h,c=f[g++])&&(~eQ(b,c)||b.push(c))}return b},eD=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],cP=eD.concat("length","prototype"),gB=Object.getOwnPropertyNames||function(a){return gL(a,cP)},bY={f:gB},cf=Object.getOwnPropertySymbols,g1={f:cf},e1=bB("Reflect","ownKeys")||function(b){var c=bY.f(gf(b)),a=g1.f;return a?c.concat(a(b)):c},bP=function(d,g){for(var c=e1(g),j=gh.f,h=gp.f,b=0;b0&&(!q.multiline||q.multiline&&"\n"!==u[q.lastIndex-1])&&(g="(?: "+g+")",k=" "+k,p++),j=RegExp("^(?:"+g+")",b)),d2&&(j=RegExp("^"+g+"$(?!\\s)",b)),c9&&(m=q.lastIndex),f=ak.call(v?j:q,k),v?f?(f.input=f.input.slice(p),f[0]=f[0].slice(p),f.index=q.lastIndex,q.lastIndex+=f[0].length):q.lastIndex=0:c9&&f&&(q.lastIndex=q.global?f.index+f[0].length:m),d2&&f&&f.length>1&&dB.call(f[0],j,function(){for(d=1;d=74)&&(cO=dN.match(/Chrome\/(\d+)/),cO&&(dE=cO[1])));var aV=dE&&+dE,cE=!!Object.getOwnPropertySymbols&&!fA(function(){return !Symbol.sham&&(aJ?38===aV:aV>37&&41>aV)}),bp=cE&&!Symbol.sham&&"symbol"==typeof Symbol.iterator,eX=d4("wks"),gU=fd.Symbol,eK=bp?gU:gU&&gU.withoutSetter||eA,cX=function(a){return(!gd(eX,a)||!cE&&"string"!=typeof eX[a])&&(cE&&gd(gU,a)?eX[a]=gU[a]:eX[a]=eK("Symbol."+a)),eX[a]},gK=cX("species"),b5=!fA(function(){var a=/./;return a.exec=function(){var b=[];return b.groups={a:"7"},b},"7"!=="".replace(a,"$")}),cp=function(){return"$0"==="a".replace(/./,"$0")}(),g6=cX("replace"),e8=function(){return/./[g6]?""===/./[g6]("a","$0"):!1}(),bW=!fA(function(){var b=/(?:)/,c=b.exec;b.exec=function(){return c.apply(this,arguments)};var a="ab".split(b);return 2!==a.length||"a"!==a[0]||"b"!==a[1]}),b8=function(u,m,j,f){var d=cX(u),q=!fA(function(){var a={};return a[d]=function(){return 7},7!=""[u](a)}),v=q&&!fA(function(){var c=!1,a=/a/;return"split"===u&&(a={},a.constructor={},a.constructor[gK]=function(){return a},a.flags="",a[d]=/./[d]),a.exec=function(){return c=!0,null},a[d](""),!c});if(!q||!v||"replace"===u&&(!b5||!cp||e8)||"split"===u&&!bW){var b=/./[d],g=j(d,""[u],function(c,h,a,r,l){return h.exec===bJ?q&&!l?{done:!0,value:b.call(h,a,r)}:{done:!0,value:c.call(a,h,r)}:{done:!1}},{REPLACE_KEEPS_$0:cp,REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE:e8}),p=g[0],k=g[1];a2(String.prototype,u,p),a2(RegExp.prototype,d,2==m?function(a,c){return k.call(a,this,c)}:function(a){return k.call(a,this)})}f&&f4(RegExp.prototype[d],"sham",!0)},fS=cX("match"),dQ=function(a){var b;return gu(a)&&(void 0!==(b=a[fS])?!!b:"RegExp"==gs(a))},bG=function(a){if("function"!=typeof a){throw TypeError(a+" is not a function")}return a},bf=cX("species"),eR=function(b,c){var a,d=gf(b).constructor;return void 0===d||void 0==(a=gf(d)[bf])?c:bG(a)},dW=function(a){return function(g,c){var j,h,b=f9(g)+"",d=aE(c),f=b.length;return 0>d||d>=f?a?"":void 0:(j=b.charCodeAt(d),55296>j||j>56319||d+1===f||(h=b.charCodeAt(d+1))<56320||h>57343?a?b.charAt(d):j:a?b.slice(d,d+2):(j-55296<<10)+(h-56320)+65536)}},cQ={codeAt:dW(!1),charAt:dW(!0)},cy=cQ.charAt,gN=function(b,c,a){return c+(a?cy(b,c).length:1)},bx=function(b,c){var a=b.exec;if("function"==typeof a){var d=a.call(b,c);if("object"!=typeof d){throw TypeError("RegExp exec method returned something other than an Object or null")}return d}if("RegExp"!==gs(b)){throw TypeError("RegExp#exec called on incompatible receiver")}return bJ.call(b,c)},bQ=[].push,dj=Math.min,fC=4294967295,d9=!fA(function(){return !RegExp(fC,"y")});b8("split",2,function(b,c,a){var d;return d="c"=="abbc".split(/(b)*/)[1]||4!="test".split(/(?:)/,-1).length||2!="ab".split(/(?:ab)*/).length||4!=".".split(/(.?)(.?)/).length||".".split(/()()/).length>1||"".split(/.?/).length?function(w,k){var g=f9(this)+"",f=void 0===k?fC:k>>>0;if(0===f){return[]}if(void 0===w){return[g]}if(!dQ(w)){return c.call(g,w,f)}for(var q,x,e,j=[],p=(w.ignoreCase?"i":"")+(w.multiline?"m":"")+(w.unicode?"u":"")+(w.sticky?"y":""),m=0,v=RegExp(w.source,p+"g");(q=bJ.call(v,g))&&(x=v.lastIndex,!(x>m&&(j.push(g.slice(m,q.index)),q.length>1&&q.index=f)));){v.lastIndex===q.index&&v.lastIndex++}return m===g.length?(e||!v.test(""))&&j.push(""):j.push(g.slice(m)),j.length>f?j.slice(0,f):j}:"0".split(void 0,0).length?function(f,e){return void 0===f&&0===e?[]:c.call(this,f,e)}:c,[function(h,g){var j=f9(this),f=void 0==h?void 0:h[b];return void 0!==f?f.call(h,j,g):d.call(j+"",h,g)},function(E,j){var B=a(d,E,this,j,d!==c);if(B.done){return B.value}var F=gf(E),e=this+"",n=eR(F,RegExp),z=F.unicode,q=(F.ignoreCase?"i":"")+(F.multiline?"m":"")+(F.unicode?"u":"")+(d9?"y":"g"),D=new n(d9?F:"^(?:"+F.source+")",q),y=void 0===j?fC:j>>>0;if(0===y){return[]}if(0===e.length){return null===bx(D,e)?[e]:[]}for(var x=0,i=0,w=[];ib;){gh.f(d,c=h[b++],f[c])}return d},cg=bB("document","documentElement"),eq=">",aO="<",gg="prototype",c3="script",gZ=ek("IE_PROTO"),aC=function(){},dq=function(a){return aO+c3+eq+a+aO+"/"+c3+eq},ag=function(a){a.write(dq("")),a.close();var b=a.parentWindow.Object;return a=null,b},dy=function(){var b,c=f0("iframe"),a="java"+c3+":";return c.style.display="none",cg.appendChild(c),c.src=a+"",b=c.contentWindow.document,b.open(),b.write(dq("document.F=Object")),b.close(),b.F},eg=function(){try{a0=document.domain&&new ActiveXObject("htmlfile")}catch(a){}eg=a0?ag(a0):dy();for(var b=eD.length;b--;){delete eg[gg][eD[b]]}return eg()};aK[gZ]=!0;var c8=Object.create||function(b,c){var a;return null!==b?(aC[gg]=gf(b),a=new aC,aC[gg]=null,a[gZ]=b):a=eg(),void 0===c?a:eE(a,c)},a6=cX("unscopables"),d1=Array.prototype;void 0==d1[a6]&&gh.f(d1,a6,{configurable:!0,value:c8(null)});var gx=function(a){d1[a6][a]=!0},bI=bh.includes;cB({target:"Array",proto:!0},{includes:function(a){return bI(this,a,arguments.length>1?arguments[1]:void 0)}}),gx("includes");var cL=Array.isArray||function(a){return"Array"==gs(a)},dD=function(a){return Object(f9(a))},aI=function(b,c,a){var d=fY(c);d in b?gh.f(b,d,gS(0,a)):b[d]=a},dK=cX("species"),ap=function(b,c){var a;return cL(b)&&(a=b.constructor,"function"!=typeof a||a!==Array&&!cL(a.prototype)?gu(a)&&(a=a[dK],null===a&&(a=void 0)):a=void 0),new (void 0===a?Array:a)(0===c?0:c)},ex=cX("species"),aw=function(a){return aV>=51||!fA(function(){var c=[],b=c.constructor={};return b[ex]=function(){return{foo:1}},1!==c[a](Boolean).foo})},aU=cX("isConcatSpreadable"),cD=9007199254740991,bm="Maximum allowed index exceeded",eW=aV>=51||!fA(function(){var a=[];return a[aU]=!1,a.concat()[0]!==a}),gT=aw("concat"),eJ=function(a){if(!gu(a)){return !1}var b=a[aU];return void 0!==b?!!b:cL(a)},cW=!eW||!gT;cB({target:"Array",proto:!0,forced:cW},{concat:function(k){var h,g,d,c,j,m=dD(this),b=ap(m,0),f=0;for(h=-1,d=arguments.length;d>h;h++){if(j=-1===h?m:arguments[h],eJ(j)){if(c=af(j.length),f+c>cD){throw TypeError(bm)}for(g=0;c>g;g++,f++){g in j&&aI(b,f,j[g])}}else{if(f>=cD){throw TypeError(bm)}aI(b,f++,j)}}return b.length=f,b}});var gH=function(b,c,a){if(bG(b),void 0===c){return b}switch(a){case 0:return function(){return b.call(c)};case 1:return function(d){return b.call(c,d)};case 2:return function(d,e){return b.call(c,d,e)};case 3:return function(d,f,e){return b.call(c,d,f,e)}}return function(){return b.apply(c,arguments)}},b2=[].push,cm=function(d){var h=1==d,c=2==d,k=3==d,j=4==d,b=6==d,f=7==d,g=5==d||b;return function(i,s,n,B){for(var r,q,a=dD(i),o=fR(a),A=gH(s,n,3),x=af(o.length),e=0,t=B||ap,z=h?t(i,x):c||f?t(i,0):void 0;x>e;e++){if((g||e in o)&&(r=o[e],q=A(r,e,a),d)){if(h){z[e]=q}else{if(q){switch(d){case 3:return !0;case 5:return r;case 6:return e;case 2:b2.call(z,r)}}else{switch(d){case 4:return !1;case 7:b2.call(z,r)}}}}}return b?-1:k||j?j:z}},g5={forEach:cm(0),map:cm(1),filter:cm(2),some:cm(3),every:cm(4),find:cm(5),findIndex:cm(6),filterOut:cm(7)},e7=g5.find,bV="find",b7=!0;bV in []&&Array(1)[bV](function(){b7=!1}),cB({target:"Array",proto:!0,forced:b7},{find:function(a){return e7(this,a,arguments.length>1?arguments[1]:void 0)}}),gx(bV);var fP=function(a){if(dQ(a)){throw TypeError("The method doesn't accept regular expressions")}return a},dP=cX("match"),bD=function(b){var c=/./;try{"/./"[b](c)}catch(a){try{return c[dP]=!1,"/./"[b](c)}catch(d){}}return !1};cB({target:"String",proto:!0,forced:!bD("includes")},{includes:function(a){return !!~(f9(this)+"").indexOf(fP(a),arguments.length>1?arguments[1]:void 0)}});var bd={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0},eP=g5.forEach,cN=ck("forEach"),cw=cN?[].forEach:function(a){return eP(this,a,arguments.length>1?arguments[1]:void 0)};for(var gJ in bd){var bv=fd[gJ],bO=bv&&bv.prototype;if(bO&&bO.forEach!==cw){try{f4(bO,"forEach",cw)}catch(dg){bO.forEach=cw}}}var fv=ed.trim,d7=fd.parseFloat,aZ=1/d7(gQ+"-0")!==-(1/0),e0=aZ?function(b){var c=fv(b+""),a=d7(c);return 0===a&&"-"==c.charAt(0)?-0:a}:d7;cB({global:!0,forced:parseFloat!=e0},{parseFloat:e0});var eC=gz.f,cd=function(a){return function(g){for(var c,j=gr(g),h=e2(j),b=h.length,d=0,f=[];b>d;){c=h[d++],(!f8||eC.call(j,c))&&f.push(a?[c,j[c]]:j[c])}return f}},em={entries:cd(!0),values:cd(!1)},aN=em.entries;cB({target:"Object",stat:!0},{entries:function(a){return aN(a)}});var f7=bh.indexOf,c1=[].indexOf,gY=!!c1&&1/[1].indexOf(1,-0)<0,aB=ck("indexOf");cB({target:"Array",proto:!0,forced:gY||!aB},{indexOf:function(a){return gY?c1.apply(this,arguments)||0:f7(this,a,arguments.length>1?arguments[1]:void 0)}});var dl=[],ad=dl.sort,dw=fA(function(){dl.sort(void 0)}),ec=fA(function(){dl.sort(null)}),c5=ck("sort"),a5=dw||!ec||!c5;cB({target:"Array",proto:!0,forced:a5},{sort:function(a){return void 0===a?ad.call(dD(this)):ad.call(dD(this),bG(a))}});var dY=Math.floor,gm="".replace,bF=/\$([$&'`]|\d{1,2}|<[^>]*>)/g,cI=/\$([$&'`]|\d{1,2})/g,dA=function(k,h,g,d,c,j){var m=g+k.length,b=d.length,f=cI;return void 0!==c&&(c=dD(c),f=bF),gm.call(j,f,function(i,e){var p;switch(e.charAt(0)){case"$":return"$";case"&":return k;case"`":return h.slice(0,g);case"'":return h.slice(m);case"<":p=c[e.slice(1,-1)];break;default:var o=+e;if(0===o){return i}if(o>b){var n=dY(o/10);return 0===n?i:b>=n?void 0===d[n-1]?e.charAt(1):d[n-1]+e.charAt(1):i}p=d[o-1]}return void 0===p?"":p})},aH=Math.max,dI=Math.min,aj=function(a){return void 0===a?a:a+""};b8("replace",2,function(d,g,c,j){var h=j.REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE,b=j.REPLACE_KEEPS_$0,f=h?"$":"$0";return[function(k,m){var l=f9(this),e=void 0==k?void 0:k[d];return void 0!==e?e.call(k,l,m):g.call(l+"",k,m)},function(B,E){if(!h&&b||"string"==typeof E&&-1===E.indexOf(f)){var C=c(g,B,this,E);if(C.done){return C.value}}var G=gf(B),M=this+"",I="function"==typeof E;I||(E+="");var A=G.global;if(A){var L=G.unicode;G.lastIndex=0}for(var K=[];;){var D=bx(G,M);if(null===D){break}if(K.push(D),!A){break}var J=D[0]+"";""===J&&(G.lastIndex=gN(M,af(G.lastIndex),L))}for(var z="",N=0,F=0;F=N&&(z+=M.slice(N,s)+a,N=s+o.length)}return z+M.slice(N)}]});var eu=Object.assign,ar=Object.defineProperty,aT=!eu||fA(function(){if(f8&&1!==eu({b:1},eu(ar({},"a",{enumerable:!0,get:function(){ar(this,"b",{value:3,enumerable:!1})}}),{b:2})).b){return !0}var b={},c={},a=Symbol(),d="abcdefghijklmnopqrst";return b[a]=7,d.split("").forEach(function(e){c[e]=e}),7!=eu({},b)[a]||e2(eu({},c)).join("")!=d})?function(w,m){for(var j=dD(w),f=arguments.length,d=1,q=g1.f,x=gz.f;f>d;){for(var b,g=fR(arguments[d++]),p=q?e2(g).concat(q(g)):e2(g),k=p.length,v=0;k>v;){b=p[v++],(!f8||x.call(g,b))&&(j[b]=g[b])}}return j}:eu;cB({target:"Object",stat:!0,forced:Object.assign!==aT},{assign:aT});var cA=g5.filter,bl=aw("filter");cB({target:"Array",proto:!0,forced:!bl},{filter:function(a){return cA(this,a,arguments.length>1?arguments[1]:void 0)}});var eT=Object.is||function(a,b){return a===b?0!==a||1/a===1/b:a!=a&&b!=b};b8("search",1,function(b,c,a){return[function(f){var d=f9(this),g=void 0==f?void 0:f[b];return void 0!==g?g.call(f,d):RegExp(f)[b](d+"")},function(e){var i=a(c,e,this);if(i.done){return i.value}var h=gf(e),d=this+"",f=h.lastIndex;eT(f,0)||(h.lastIndex=0);var g=bx(h,d);return eT(h.lastIndex,f)||(h.lastIndex=f),null===g?-1:g.index}]});var gP=ed.trim,eG=fd.parseInt,cT=/^[+-]?0[Xx]/,gE=8!==eG(gQ+"08")||22!==eG(gQ+"0x16"),b0=gE?function(b,c){var a=gP(b+"");return eG(a,c>>>0||(cT.test(a)?16:10))}:eG;cB({global:!0,forced:parseInt!=b0},{parseInt:b0});var cj=g5.map,g4=aw("map");cB({target:"Array",proto:!0,forced:!g4},{map:function(a){return cj(this,a,arguments.length>1?arguments[1]:void 0)}});var e4=g5.findIndex,bS="findIndex",b4=!0;bS in []&&Array(1)[bS](function(){b4=!1}),cB({target:"Array",proto:!0,forced:b4},{findIndex:function(a){return e4(this,a,arguments.length>1?arguments[1]:void 0)}}),gx(bS);var fH=function(a){if(!gu(a)&&null!==a){throw TypeError("Can't set "+(a+"")+" as a prototype")}return a},dM=Object.setPrototypeOf||("__proto__" in {}?function(){var b,c=!1,a={};try{b=Object.getOwnPropertyDescriptor(Object.prototype,"__proto__").set,b.call(a,[]),c=a instanceof Array}catch(d){}return function(e,f){return gf(e),fH(f),c?b.call(e,f):e.__proto__=f,e}}():void 0),bz=function(b,c,a){var f,d;return dM&&"function"==typeof(f=c.constructor)&&f!==a&&gu(d=f.prototype)&&d!==a.prototype&&dM(b,d),b},bc=cX("species"),eO=function(b){var c=bB(b),a=gh.f;f8&&c&&!c[bc]&&a(c,bc,{configurable:!0,get:function(){return this}})},dU=gh.f,cM=bY.f,cv=c2.set,gI=cX("match"),bu=fd.RegExp,bN=bu.prototype,df=/a/g,fs=/a/g,d6=new bu(df)!==df,aY=dr.UNSUPPORTED_Y,eB=f8&&dZ("RegExp",!d6||aY||fA(function(){return fs[gI]=!1,bu(df)!=df||bu(fs)==fs||"/a/i"!=bu(df,"i")}));if(eB){for(var cc=function(d,g){var c,j=this instanceof cc,h=dQ(d),b=void 0===g;if(!j&&h&&d.constructor===cc&&b){return d}d6?h&&!b&&(d=d.source):d instanceof cc&&(b&&(g=c6.call(d)),d=d.source),aY&&(c=!!g&&g.indexOf("y")>-1,c&&(g=g.replace(/y/g,"")));var f=bz(d6?new bu(d,g):bu(d,g),j?this:bN,cc);return aY&&c&&cv(f,{sticky:c}),f},el=(function(a){a in cc||dU(cc,a,{configurable:!0,get:function(){return bu[a]},set:function(b){bu[a]=b}})}),aM=cM(bu),f5=0;aM.length>f5;){el(aM[f5++])}bN.constructor=cc,cc.prototype=bN,a2(fd,"RegExp",cc)}eO("RegExp");var c0="toString",gX=RegExp.prototype,aA=gX[c0],dk=fA(function(){return"/a/b"!=aA.call({source:"a",flags:"b"})}),ac=aA.name!=c0;(dk||ac)&&a2(RegExp.prototype,c0,function(){var b=gf(this),c=b.source+"",a=b.flags,d=(void 0===a&&b instanceof RegExp&&!("flags" in gX)?c6.call(b):a)+"";return"/"+c+"/"+d},{unsafe:!0});var dv=cX("toStringTag"),eb={};eb[dv]="z";var c4=eb+""=="[object z]",a4=cX("toStringTag"),dX="Arguments"==gs(function(){return arguments}()),gj=function(b,c){try{return b[c]}catch(a){}},bE=c4?gs:function(b){var c,a,d;return void 0===b?"Undefined":null===b?"Null":"string"==typeof(a=gj(c=Object(b),a4))?a:dX?gs(c):"Object"==(d=gs(c))&&"function"==typeof c.callee?"Arguments":d},cH=c4?{}.toString:function(){return"[object "+bE(this)+"]"};c4||a2(Object.prototype,"toString",cH,{unsafe:!0});var dz=aw("slice"),aG=cX("species"),dH=[].slice,ah=Math.max;cB({target:"Array",proto:!0,forced:!dz},{slice:function(k,h){var g,d,c,j=gr(this),m=af(j.length),b=aQ(k,m),f=aQ(void 0===h?m:h,m);if(cL(j)&&(g=j.constructor,"function"!=typeof g||g!==Array&&!cL(g.prototype)?gu(g)&&(g=g[aG],null===g&&(g=void 0)):g=void 0,g===Array||void 0===g)){return dH.call(j,b,f)}for(d=new (void 0===g?Array:g)(ah(f-b,0)),c=0;f>b;b++,c++){b in j&&aI(d,c,j[b])}return d.length=c,d}});var er,aq,aS,cz=!fA(function(){function a(){}return a.prototype.constructor=null,Object.getPrototypeOf(new a)!==a.prototype}),bk=ek("IE_PROTO"),eS=Object.prototype,gO=cz?Object.getPrototypeOf:function(a){return a=dD(a),gd(a,bk)?a[bk]:"function"==typeof a.constructor&&a instanceof a.constructor?a.constructor.prototype:a instanceof Object?eS:null},eF=cX("iterator"),cS=!1,gD=function(){return this};[].keys&&(aS=[].keys(),"next" in aS?(aq=gO(gO(aS)),aq!==Object.prototype&&(er=aq)):cS=!0);var bZ=void 0==er||fA(function(){var a={};return er[eF].call(a)!==a});bZ&&(er={}),gd(er,eF)||f4(er,eF,gD);var ch={IteratorPrototype:er,BUGGY_SAFARI_ITERATORS:cS},g3=gh.f,e3=cX("toStringTag"),bR=function(b,c,a){b&&!gd(b=a?b:b.prototype,e3)&&g3(b,e3,{configurable:!0,value:c})},b3=ch.IteratorPrototype,fE=function(b,c,a){var d=c+" Iterator";return b.prototype=c8(b3,{next:gS(1,a)}),bR(b,d,!1),b},dL=ch.IteratorPrototype,by=ch.BUGGY_SAFARI_ITERATORS,bj=cX("iterator"),eV="keys",d0="values",cV="entries",cC=function(){return this},gR=function(G,A,w,m,k,D,H){fE(w,A,m);var b,q,C,x=function(a){if(a===k&&y){return y}if(!by&&a in z){return z[a]}switch(a){case eV:return function(){return new w(this,a)};case d0:return function(){return new w(this,a)};case cV:return function(){return new w(this,a)}}return function(){return new w(this)}},F=A+" Iterator",B=!1,z=G.prototype,j=z[bj]||z["@@iterator"]||k&&z[k],y=!by&&j||x(k),E="Array"==A?z.entries||j:j;if(E&&(b=gO(E.call(new G)),dL!==Object.prototype&&b.next&&(gO(b)!==dL&&(dM?dM(b,dL):"function"!=typeof b[bj]&&f4(b,bj,cC)),bR(b,F,!0))),k==d0&&j&&j.name!==d0&&(B=!0,y=function(){return j.call(this)}),z[bj]!==y&&f4(z,bj,y),k){if(q={values:x(d0),keys:D?y:x(eV),entries:x(cV)},H){for(C in q){!by&&!B&&C in z||a2(z,C,q[C])}}else{cB({target:A,proto:!0,forced:by||B},q)}}return q},bC="Array Iterator",bU=c2.set,dp=c2.getterFor(bC),fN=gR(Array,"Array",function(a,b){bU(this,{type:bC,target:gr(a),index:0,kind:b})},function(){var b=dp(this),c=b.target,a=b.kind,d=b.index++;return !c||d>=c.length?(b.target=void 0,{value:void 0,done:!0}):"keys"==a?{value:d,done:!1}:"values"==a?{value:c[d],done:!1}:{value:[d,c[d]],done:!1}},"values");gx("keys"),gx("values"),gx("entries");var ef=cX("iterator"),a3=cX("toStringTag"),e6=fN.values;for(var eI in bd){var cl=fd[eI],ew=cl&&cl.prototype;if(ew){if(ew[ef]!==e6){try{f4(ew,ef,e6)}catch(dg){ew[ef]=e6}}if(ew[a3]||f4(ew,a3,eI),bd[eI]){for(var aR in fN){if(ew[aR]!==fN[aR]){try{f4(ew,aR,fN[aR])}catch(dg){ew[aR]=fN[aR]}}}}}}var gv=aw("splice"),c7=Math.max,g2=Math.min,aF=9007199254740991,ds="Maximum allowed length exceeded";cB({target:"Array",proto:!0,forced:!gv},{splice:function(w,m){var j,f,d,q,x,b,g=dD(this),p=af(g.length),k=aQ(w,p),v=arguments.length;if(0===v?j=f=0:1===v?(j=0,f=p-k):(j=v-2,f=g2(c7(aE(m),0),p-k)),p+j-f>aF){throw TypeError(ds)}for(d=ap(g,f),q=0;f>q;q++){x=k+q,x in g&&aI(d,q,g[x])}if(d.length=f,f>j){for(q=k;p-f>q;q++){x=q+f,b=q+j,x in g?g[b]=g[x]:delete g[b]}for(q=p;q>p-f+j;q--){delete g[q-1]}}else{if(j>f){for(q=p-f;q>k;q--){x=q+f-1,b=q+j-1,x in g?g[b]=g[x]:delete g[b]}}}for(q=0;j>q;q++){g[q+k]=arguments[q+2]}return g.length=p-f+j,d}});var am=bY.f,dC=gp.f,ej=gh.f,db=ed.trim,bb="Number",d3=fd[bb],gC=d3.prototype,bM=gs(c8(gC))==bb,cR=function(p){var j,h,f,d,m,q,b,g,k=fY(p,!1);if("string"==typeof k&&k.length>2){if(k=db(k),j=k.charCodeAt(0),43===j||45===j){if(h=k.charCodeAt(2),88===h||120===h){return NaN}}else{if(48===j){switch(k.charCodeAt(1)){case 66:case 98:f=2,d=49;break;case 79:case 111:f=8,d=55;break;default:return +k}for(m=k.slice(2),q=m.length,b=0;q>b;b++){if(g=m.charCodeAt(b),48>g||g>d){return NaN}}return parseInt(m,f)}}}return +k};if(dZ(bb,!d3(" 0o1")||!d3("0b1")||d3("+0x1"))){for(var dF,aL=function(b){var c=arguments.length<1?0:b,a=this;return a instanceof aL&&(bM?fA(function(){gC.valueOf.call(a)}):gs(a)!=bb)?bz(new d3(cR(c)),a,aL):cR(c)},dO=f8?am(d3):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger,fromString,range".split(","),av=0;dO.length>av;av++){gd(d3,dF=dO[av])&&!gd(aL,dF)&&ej(aL,dF,dC(d3,dF))}aL.prototype=gC,gC.constructor=aL,a2(fd,bb,aL)}var ez=[].reverse,az=[1,2];cB({target:"Array",proto:!0,forced:az+""==az.reverse()+""},{reverse:function(){return cL(this)&&(this.length=this.length),ez.call(this)}});var aX="1.18.3",cG=4;try{var bs=fc["default"].fn.dropdown.Constructor.VERSION;void 0!==bs&&(cG=parseInt(bs,10))}catch(eY){}try{var gW=bootstrap.Tooltip.VERSION;void 0!==gW&&(cG=parseInt(gW,10))}catch(eY){}var eL={3:{iconsPrefix:"glyphicon",icons:{paginationSwitchDown:"glyphicon-collapse-down icon-chevron-down",paginationSwitchUp:"glyphicon-collapse-up icon-chevron-up",refresh:"glyphicon-refresh icon-refresh",toggleOff:"glyphicon-list-alt icon-list-alt",toggleOn:"glyphicon-list-alt icon-list-alt",columns:"glyphicon-th icon-th",detailOpen:"glyphicon-plus icon-plus",detailClose:"glyphicon-minus icon-minus",fullscreen:"glyphicon-fullscreen",search:"glyphicon-search",clearSearch:"glyphicon-trash"},classes:{buttonsPrefix:"btn",buttons:"default",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"pull",inputGroup:"input-group",inputPrefix:"input-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{toolbarDropdown:['"],toolbarDropdownItem:'
  • ',toolbarDropdownSeparator:'
  • ',pageDropdown:['"],pageDropdownItem:'
    ',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s%s
    ',searchInput:'',searchButton:'',searchClearButton:''}},4:{iconsPrefix:"fa",icons:{paginationSwitchDown:"fa-caret-square-down",paginationSwitchUp:"fa-caret-square-up",refresh:"fa-sync",toggleOff:"fa-toggle-off",toggleOn:"fa-toggle-on",columns:"fa-th-list",detailOpen:"fa-plus",detailClose:"fa-minus",fullscreen:"fa-arrows-alt",search:"fa-search",clearSearch:"fa-trash"},classes:{buttonsPrefix:"btn",buttons:"secondary",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"float",inputGroup:"btn-group",inputPrefix:"form-control-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{toolbarDropdown:['"],toolbarDropdownItem:'',pageDropdown:['"],pageDropdownItem:'%s',toolbarDropdownSeparator:'',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s
    %s
    ',searchInput:'',searchButton:'',searchClearButton:''}},5:{iconsPrefix:"fa",icons:{paginationSwitchDown:"fa-caret-square-down",paginationSwitchUp:"fa-caret-square-up",refresh:"fa-sync",toggleOff:"fa-toggle-off",toggleOn:"fa-toggle-on",columns:"fa-th-list",detailOpen:"fa-plus",detailClose:"fa-minus",fullscreen:"fa-arrows-alt",search:"fa-search",clearSearch:"fa-trash"},classes:{buttonsPrefix:"btn",buttons:"secondary",buttonsGroup:"btn-group",buttonsDropdown:"btn-group",pull:"float",inputGroup:"btn-group",inputPrefix:"form-control-",input:"form-control",paginationDropdown:"btn-group dropdown",dropup:"dropup",dropdownActive:"active",paginationActive:"active",buttonActive:"active"},html:{dataToggle:"data-bs-toggle",toolbarDropdown:['"],toolbarDropdownItem:'',pageDropdown:['"],pageDropdownItem:'%s',toolbarDropdownSeparator:'',dropdownCaret:'',pagination:['
      ',"
    "],paginationItem:'
  • %s
  • ',icon:'',inputGroup:'
    %s
    %s
    ',searchInput:'',searchButton:'',searchClearButton:''}}}[cG],cY={id:void 0,firstLoad:!0,height:void 0,classes:"table table-bordered table-hover",buttons:{},theadClasses:"",striped:!1,headerStyle:function(a){return{}},rowStyle:function(a,b){return{}},rowAttributes:function(a,b){return{}},undefinedText:"-",locale:void 0,virtualScroll:!1,virtualScrollItemHeight:void 0,sortable:!0,sortClass:void 0,silentSort:!0,sortName:void 0,sortOrder:void 0,sortReset:!1,sortStable:!1,rememberOrder:!1,serverSort:!0,customSort:void 0,columns:[[]],data:[],url:void 0,method:"get",cache:!0,contentType:"application/json",dataType:"json",ajax:void 0,ajaxOptions:{},queryParams:function(a){return a},queryParamsType:"limit",responseHandler:function(a){return a},totalField:"total",totalNotFilteredField:"totalNotFiltered",dataField:"rows",footerField:"footer",pagination:!1,paginationParts:["pageInfo","pageSize","pageList"],showExtendedPagination:!1,paginationLoop:!0,sidePagination:"client",totalRows:0,totalNotFiltered:0,pageNumber:1,pageSize:10,pageList:[10,25,50,100],paginationHAlign:"right",paginationVAlign:"bottom",paginationDetailHAlign:"left",paginationPreText:"‹",paginationNextText:"›",paginationSuccessivelySize:5,paginationPagesBySide:1,paginationUseIntermediate:!1,search:!1,searchHighlight:!1,searchOnEnterKey:!1,strictSearch:!1,searchSelector:!1,visibleSearch:!1,showButtonIcons:!0,showButtonText:!1,showSearchButton:!1,showSearchClearButton:!1,trimOnSearch:!0,searchAlign:"right",searchTimeOut:500,searchText:"",customSearch:void 0,showHeader:!0,showFooter:!1,footerStyle:function(a){return{}},searchAccentNeutralise:!1,showColumns:!1,showSearch:!1,showPageGo:!1,showColumnsToggleAll:!1,showColumnsSearch:!1,minimumCountColumns:1,showPaginationSwitch:!1,showRefresh:!1,showToggle:!1,showFullscreen:!1,smartDisplay:!0,escape:!1,filterOptions:{filterAlgorithm:"and"},idField:void 0,selectItemName:"btSelectItem",clickToSelect:!1,ignoreClickToSelectOn:function(a){var b=a.tagName;return["A","BUTTON"].includes(b)},singleSelect:!1,checkboxHeader:!0,maintainMetaData:!1,multipleSelectRow:!1,uniqueId:void 0,cardView:!1,detailView:!1,detailViewIcon:!0,detailViewByClick:!1,detailViewAlign:"left",detailFormatter:function(a,b){return""},detailFilter:function(a,b){return !0},toolbar:void 0,toolbarAlign:"left",buttonsToolbar:void 0,buttonsAlign:"right",buttonsOrder:["search","paginationSwitch","refresh","toggle","fullscreen","columns"],buttonsPrefix:eL.classes.buttonsPrefix,buttonsClass:eL.classes.buttons,icons:eL.icons,iconSize:void 0,iconsPrefix:eL.iconsPrefix,loadingFontSize:"auto",loadingTemplate:function(a){return'\n '.concat(a,'\n \n \n ')},onAll:function(a,b){return !1},onClickCell:function(b,c,a,d){return !1},onDblClickCell:function(b,c,a,d){return !1},onClickRow:function(a,b){return !1},onDblClickRow:function(a,b){return !1},onSort:function(a,b){return !1},onCheck:function(a){return !1},onUncheck:function(a){return !1},onCheckAll:function(a){return !1},onUncheckAll:function(a){return !1},onCheckSome:function(a){return !1},onUncheckSome:function(a){return !1},onLoadSuccess:function(a){return !1},onLoadError:function(a){return !1},onColumnSwitch:function(a,b){return !1},onPageChange:function(a,b){return !1},onSearch:function(a){return !1},onShowSearch:function(){return !1},onToggle:function(a){return !1},onPreBody:function(a){return !1},onPostBody:function(){return !1},onPostHeader:function(){return !1},onPostFooter:function(){return !1},onExpandRow:function(b,c,a){return !1},onCollapseRow:function(a,b){return !1},onRefreshOptions:function(a){return !1},onRefresh:function(a){return !1},onResetView:function(){return !1},onScrollBody:function(){return !1}},gM={formatLoadingMessage:function(){return"Loading, please wait"},formatRecordsPerPage:function(a){return"".concat(a," rows per page")},formatShowingRows:function(b,c,a,d){return void 0!==d&&d>0&&d>a?"Showing ".concat(b," to ").concat(c," of ").concat(a," rows (filtered from ").concat(d," total rows)"):"Showing ".concat(b," to ").concat(c," of ").concat(a," rows")},formatSRPaginationPreText:function(){return"previous page"},formatSRPaginationPageText:function(a){return"to page ".concat(a)},formatSRPaginationNextText:function(){return"next page"},formatDetailPagination:function(a){return"Showing ".concat(a," rows")},formatSearch:function(){return"Search"},formatShowSearch:function(){return"Show Search"},formatPageGo:function(){return"Go"},formatClearSearch:function(){return"Clear Search"},formatNoMatches:function(){return"No matching records found"},formatPaginationSwitch:function(){return"Hide/Show pagination"},formatPaginationSwitchDown:function(){return"Show pagination"},formatPaginationSwitchUp:function(){return"Hide pagination"},formatRefresh:function(){return"Refresh"},formatToggle:function(){return"Toggle"},formatToggleOn:function(){return"Show card view"},formatToggleOff:function(){return"Hide card view"},formatColumns:function(){return"Columns"},formatColumnsToggleAll:function(){return"Toggle all"},formatFullscreen:function(){return"Fullscreen"},formatAllRows:function(){return"All"}},b6={field:void 0,title:void 0,titleTooltip:void 0,"class":void 0,width:void 0,widthUnit:"px",rowspan:void 0,colspan:void 0,align:void 0,halign:void 0,falign:void 0,valign:void 0,cellStyle:void 0,radio:!1,checkbox:!1,checkboxEnabled:!0,clickToSelect:!0,showSelectTitle:!1,sortable:!1,sortName:void 0,order:"asc",sorter:void 0,visible:!0,ignore:!1,switchable:!0,cardVisible:!0,searchable:!0,formatter:void 0,footerFormatter:void 0,detailFormatter:void 0,searchFormatter:!0,searchHighlightFormatter:!1,escape:!1,events:void 0},cq=["getOptions","refreshOptions","getData","getSelections","load","append","prepend","remove","removeAll","insertRow","updateRow","getRowByUniqueId","updateByUniqueId","removeByUniqueId","updateCell","updateCellByUniqueId","showRow","hideRow","getHiddenRows","showColumn","hideColumn","getVisibleColumns","getHiddenColumns","showAllColumns","hideAllColumns","mergeCells","checkAll","uncheckAll","checkInvert","check","uncheck","checkBy","uncheckBy","refresh","destroy","resetView","showLoading","hideLoading","togglePagination","toggleFullscreen","toggleView","resetSearch","filterBy","scrollTo","getScrollPosition","selectPage","prevPage","nextPage","toggleDetailView","expandRow","collapseRow","expandRowByUniqueId","collapseRowByUniqueId","expandAllRows","collapseAllRows","updateColumnTitle","updateFormatText"],ab={"all.bs.table":"onAll","click-row.bs.table":"onClickRow","dbl-click-row.bs.table":"onDblClickRow","click-cell.bs.table":"onClickCell","dbl-click-cell.bs.table":"onDblClickCell","sort.bs.table":"onSort","check.bs.table":"onCheck","uncheck.bs.table":"onUncheck","check-all.bs.table":"onCheckAll","uncheck-all.bs.table":"onUncheckAll","check-some.bs.table":"onCheckSome","uncheck-some.bs.table":"onUncheckSome","load-success.bs.table":"onLoadSuccess","load-error.bs.table":"onLoadError","column-switch.bs.table":"onColumnSwitch","page-change.bs.table":"onPageChange","search.bs.table":"onSearch","toggle.bs.table":"onToggle","pre-body.bs.table":"onPreBody","post-body.bs.table":"onPostBody","post-header.bs.table":"onPostHeader","post-footer.bs.table":"onPostFooter","expand-row.bs.table":"onExpandRow","collapse-row.bs.table":"onCollapseRow","refresh-options.bs.table":"onRefreshOptions","reset-view.bs.table":"onResetView","refresh.bs.table":"onRefresh","scroll-body.bs.table":"onScrollBody"};Object.assign(cY,gM);var fb={VERSION:aX,THEME:"bootstrap".concat(cG),CONSTANTS:eL,DEFAULTS:cY,COLUMN_DEFAULTS:b6,METHODS:cq,EVENTS:ab,LOCALES:{en:gM,"en-US":gM}},bX=fA(function(){e2(1)});cB({target:"Object",stat:!0,forced:bX},{keys:function(a){return e2(dD(a))}});var b9=gp.f,fT="".startsWith,dR=Math.min,bH=bD("startsWith"),a9=!bH&&!!function(){var a=b9(String.prototype,"startsWith");return a&&!a.writable}();cB({target:"String",proto:!0,forced:!a9&&!bH},{startsWith:function(b){var c=f9(this)+"";fP(b);var a=af(dR(arguments.length>1?arguments[1]:void 0,c.length)),d=b+"";return fT?fT.call(c,d,a):c.slice(a,a+d.length)===d}});var eN=gp.f,dT="".endsWith,cK=Math.min,cu=bD("endsWith"),gG=!cu&&!!function(){var a=eN(String.prototype,"endsWith");return a&&!a.writable}();cB({target:"String",proto:!0,forced:!gG&&!cu},{endsWith:function(d){var f=f9(this)+"";fP(d);var c=arguments.length>1?arguments[1]:void 0,h=af(f.length),g=void 0===c?h:cK(af(c),h),b=d+"";return dT?dT.call(f,b,g):f.slice(g-b.length,g)===b}});var br={getSearchInput:function(a){return"string"==typeof a.options.searchSelector?fc["default"](a.options.searchSelector):a.$toolbar.find(".search input")},sprintf:function(d){for(var g=arguments.length,c=Array(g>1?g-1:0),j=1;g>j;j++){c[j-1]=arguments[j]}var h=!0,b=0,f=d.replace(/%s/g,function(){var a=c[b++];return void 0===a?(h=!1,""):a});return h?f:""},isObject:function(a){return a instanceof Object&&!Array.isArray(a)},isEmptyObject:function(){var a=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return 0===Object.entries(a).length&&a.constructor===Object},isNumeric:function(a){return !isNaN(parseFloat(a))&&isFinite(a)},getFieldTitle:function(d,f){var c,h=fg(d);try{for(h.s();!(c=h.n()).done;){var g=c.value;if(g.field===f){return g.title}}}catch(b){h.e(b)}finally{h.f()}return""},setFieldIndex:function(k){var F,B=0,y=[],x=fg(k[0]);try{for(x.s();!(F=x.n()).done;){var J=F.value;B+=J.colspan||1}}catch(q){x.e(q)}finally{x.f()}for(var v=0;vA;A++){y[v][A]=!1}}for(var H=0;HI;I++){for(var z=0;w>z;z++){y[H+I][D+z]=!0}}}}catch(q){j.e(q)}finally{j.f()}}},normalizeAccent:function(a){return"string"!=typeof a?a:a.normalize("NFD").replace(/[\u0300-\u036f]/g,"")},updateFieldGroup:function(y){var q,k,g=(q=[]).concat.apply(q,fp(y)),b=fg(y);try{for(b.s();!(k=b.n()).done;){var w,z=k.value,j=fg(z);try{for(j.s();!(w=j.n()).done;){var v=w.value;if(v.colspanGroup>1){for(var m=0,x=function(a){var c=g.find(function(d){return d.fieldIndex===a});c.visible&&m++},r=v.colspanIndex;r0}}}catch(p){j.e(p)}finally{j.f()}}}catch(p){b.e(p)}finally{b.f()}},getScrollBarWidth:function(){if(void 0===this.cachedWidth){var b=fc["default"]("
    ").addClass("fixed-table-scroll-inner"),c=fc["default"]("
    ").addClass("fixed-table-scroll-outer");c.append(b),fc["default"]("body").append(c);var a=b[0].offsetWidth;c.css("overflow","scroll");var d=b[0].offsetWidth;a===d&&(d=c[0].clientWidth),c.remove(),this.cachedWidth=a-d}return this.cachedWidth},calculateObjectValue:function(p,i,d,b){var k=i;if("string"==typeof i){var q=i.split(".");if(q.length>1){k=window;var f,j=fg(q);try{for(j.s();!(f=j.n()).done;){var g=f.value;k=k[g]}}catch(m){j.e(m)}finally{j.f()}}else{k=window[i]}}return null!==k&&"object"===fD(k)?k:"function"==typeof k?k.apply(p,d||[]):!k&&"string"==typeof i&&this.sprintf.apply(this,[i].concat(fp(d)))?this.sprintf.apply(this,[i].concat(fp(d))):b},compareObjects:function(d,h,c){var k=Object.keys(d),j=Object.keys(h);if(c&&k.length!==j.length){return !1}for(var b=0,f=k;b/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/`/g,"`"):a},unescapeHTML:function(a){return"string"==typeof a?a.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/`/g,"`"):a},getRealDataAttr:function(d){for(var g=0,c=Object.entries(d);gtd,>th").each(function(e,r){for(var v=fc["default"](r),k=+v.attr("colspan")||1,q=+v.attr("rowspan")||1,m=e;d[j]&&d[j][m];m++){}for(var t=m;m+k>t;t++){for(var p=j;j+q>p;p++){d[p]||(d[p]=[]),d[p][t]=!0}}var o=b[m].field;i[o]=v.html().trim(),i["_".concat(o,"_id")]=v.attr("id"),i["_".concat(o,"_class")]=v.attr("class"),i["_".concat(o,"_rowspan")]=v.attr("rowspan"),i["_".concat(o,"_colspan")]=v.attr("colspan"),i["_".concat(o,"_title")]=v.attr("title"),i["_".concat(o,"_data")]=a.getRealDataAttr(v.data()),i["_".concat(o,"_style")]=v.attr("style")}),f.push(i)}),f},sort:function(d,f,c,h,g,b){return(void 0===d||null===d)&&(d=""),(void 0===f||null===f)&&(f=""),h&&d===f&&(d=g,f=b),this.isNumeric(d)&&this.isNumeric(f)?(d=parseFloat(d),f=parseFloat(f),f>d?-1*c:d>f?c:0):d===f?0:("string"!=typeof d&&(d=""+d),-1===d.localeCompare(f)?-1*c:c)},getEventName:function(a){var b=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return b=b||"".concat(+new Date).concat(~~(1000000*Math.random())),"".concat(a,"-").concat(b)},hasDetailViewIcon:function(a){return a.detailView&&a.detailViewIcon&&!a.cardView},getDetailViewIndexOffset:function(a){return this.hasDetailViewIcon(a)&&"right"!==a.detailViewAlign?1:0},checkAutoMergeCells:function(d){var h,c=fg(d);try{for(c.s();!(h=c.n()).done;){for(var k=h.value,j=0,b=Object.keys(k);jc&&b++;for(var f=g;d>f;f++){k[f]&&m.push(k[f])}return{topOffset:c,bottomOffset:j,rowsAbove:b,rows:m}}},{key:"checkChanges",value:function(c,d){var b=d!==this.cache[c];return this.cache[c]=d,b}},{key:"getExtra",value:function(c,d){var b=document.createElement("tr");return b.className="virtual-scroll-".concat(c),d&&(b.style.height="".concat(d,"px")),b.outerHTML}}]),a}(),d5=function(){function a(d,c){fw(this,a),this.options=c,this.$el=fc["default"](d),this.$el_=this.$el.clone(),this.timeoutId_=0,this.timeoutFooter_=0}return fQ(a,[{key:"init",value:function(){this.initConstants(),this.initLocale(),this.initContainer(),this.initTable(),this.initHeader(),this.initData(),this.initHiddenRows(),this.initToolbar(),this.initPagination(),this.initBody(),this.initSearchText(),this.initServer()}},{key:"initConstants",value:function(){var c=this.options;this.constants=fb.CONSTANTS,this.constants.theme=fc["default"].fn.bootstrapTable.theme,this.constants.dataToggle=this.constants.html.dataToggle||"data-toggle";var d=c.buttonsPrefix?"".concat(c.buttonsPrefix,"-"):"";this.constants.buttonsClass=[c.buttonsPrefix,d+c.buttonsClass,br.sprintf("".concat(d,"%s"),c.iconSize)].join(" ").trim(),this.buttons=br.calculateObjectValue(this,c.buttons,[],{}),"object"!==fD(this.buttons)&&(this.buttons={}),"string"==typeof c.icons&&(c.icons=br.calculateObjectValue(null,c.icons))}},{key:"initLocale",value:function(){if(this.options.locale){var c=fc["default"].fn.bootstrapTable.locales,d=this.options.locale.split(/-|_/);d[0]=d[0].toLowerCase(),d[1]&&(d[1]=d[1].toUpperCase()),c[this.options.locale]?fc["default"].extend(this.options,c[this.options.locale]):c[d.join("-")]?fc["default"].extend(this.options,c[d.join("-")]):c[d[0]]&&fc["default"].extend(this.options,c[d[0]])}}},{key:"initContainer",value:function(){var d=["top","both"].includes(this.options.paginationVAlign)?'
    ':"",f=["bottom","both"].includes(this.options.paginationVAlign)?'
    ':"",c=br.calculateObjectValue(this.options,this.options.loadingTemplate,[this.options.formatLoadingMessage()]);this.$container=fc["default"]('\n
    \n
    \n ').concat(d,'\n
    \n
    \n
    \n
    \n ').concat(c,'\n
    \n
    \n \n
    \n ').concat(f,"\n
    \n ")),this.$container.insertAfter(this.$el),this.$tableContainer=this.$container.find(".fixed-table-container"),this.$tableHeader=this.$container.find(".fixed-table-header"),this.$tableBody=this.$container.find(".fixed-table-body"),this.$tableLoading=this.$container.find(".fixed-table-loading"),this.$tableFooter=this.$el.find("tfoot"),this.options.buttonsToolbar?this.$toolbar=fc["default"]("body").find(this.options.buttonsToolbar):this.$toolbar=this.$container.find(".fixed-table-toolbar"),this.$pagination=this.$container.find(".fixed-table-pagination"),this.$tableBody.append(this.$el),this.$container.after('
    '),this.$el.addClass(this.options.classes),this.$tableLoading.addClass(this.options.classes),this.options.striped&&this.$el.addClass("table-striped"),this.options.height&&(this.$tableContainer.addClass("fixed-height"),this.options.showFooter&&this.$tableContainer.addClass("has-footer"),this.options.classes.split(" ").includes("table-bordered")&&(this.$tableBody.append('
    '),this.$tableBorder=this.$tableBody.find(".fixed-table-border"),this.$tableLoading.addClass("fixed-table-border")),this.$tableFooter=this.$container.find(".fixed-table-footer"))}},{key:"initTable",value:function(){var d=this,c=[];if(this.$header=this.$el.find(">thead"),this.$header.length?this.options.theadClasses&&this.$header.addClass(this.options.theadClasses):this.$header=fc["default"]('')).appendTo(this.$el),this._headerTrClasses=[],this._headerTrStyles=[],this.$header.find("tr").each(function(g,i){var h=fc["default"](i),f=[];h.find("th").each(function(k,l){var j=fc["default"](l);void 0!==j.data("field")&&j.data("field","".concat(j.data("field"))),f.push(fc["default"].extend({},{title:j.html(),"class":j.attr("class"),titleTooltip:j.attr("title"),rowspan:j.attr("rowspan")?+j.attr("rowspan"):void 0,colspan:j.attr("colspan")?+j.attr("colspan"):void 0},j.data()))}),c.push(f),h.attr("class")&&d._headerTrClasses.push(h.attr("class")),h.attr("style")&&d._headerTrStyles.push(h.attr("style"))}),Array.isArray(this.options.columns[0])||(this.options.columns=[this.options.columns]),this.options.columns=fc["default"].extend(!0,[],c,this.options.columns),this.columns=[],this.fieldsColumnsIndex=[],br.setFieldIndex(this.options.columns),this.options.columns.forEach(function(f,g){f.forEach(function(j,k){var h=fc["default"].extend({},a.COLUMN_DEFAULTS,j);void 0!==h.fieldIndex&&(d.columns[h.fieldIndex]=h,d.fieldsColumnsIndex[h.field]=h.fieldIndex),d.options.columns[g][k]=h})}),!this.options.data.length){var e=br.trToData(this.columns,this.$el.find(">tbody>tr"));e.length&&(this.options.data=e,this.fromHtml=!0)}this.options.pagination&&"server"!==this.options.sidePagination||(this.footerData=br.trToData(this.columns,this.$el.find(">tfoot>tr"))),this.footerData&&this.$el.find("tfoot").html(""),!this.options.showFooter||this.options.cardView?this.$tableFooter.hide():this.$tableFooter.show()}},{key:"initHeader",value:function(){var d=this,f={},c=[];this.header={fields:[],styles:[],classes:[],formatters:[],detailFormatters:[],events:[],sorters:[],sortNames:[],cellStyles:[],searchables:[]},br.updateFieldGroup(this.options.columns),this.options.columns.forEach(function(k,j){var h=[];h.push(""));var i="";if(0===j&&br.hasDetailViewIcon(d.options)){var e=d.options.columns.length>1?' rowspan="'.concat(d.options.columns.length,'"'):"";i='\n
    \n ')}i&&"right"!==d.options.detailViewAlign&&h.push(i),k.forEach(function(G,D){var B=br.sprintf(' class="%s"',G["class"]),F=G.widthUnit,L=parseFloat(G.width),H=br.sprintf("text-align: %s; ",G.halign?G.halign:G.align),A=br.sprintf("text-align: %s; ",G.align),K=br.sprintf("vertical-align: %s; ",G.valign);if(K+=br.sprintf("width: %s; ",!G.checkbox&&!G.radio||L?L?L+F:void 0:G.showSelectTitle?void 0:"36px"),void 0!==G.fieldIndex||G.visible){var J=br.calculateObjectValue(null,d.options.headerStyle,[G]),C=[],I="";if(J&&J.css){for(var z=0,M=Object.entries(J.css);z0?" data-not-first-th":"",">"),h.push(br.sprintf('
    ',d.options.sortable&&G.sortable?"sortable both":""));var o=d.options.escape?br.escapeHTML(G.title):G.title,s=o;G.checkbox&&(o="",!d.options.singleSelect&&d.options.checkboxHeader&&(o=''),d.header.stateField=G.field),G.radio&&(o="",d.header.stateField=G.field),!o&&G.showSelectTitle&&(o+=s),h.push(o),h.push("
    "),h.push('
    '),h.push("
    "),h.push("")}}),i&&"right"===d.options.detailViewAlign&&h.push(i),h.push(""),h.length>3&&c.push(h.join(""))}),this.$header.html(c.join("")),this.$header.find("th[data-field]").each(function(h,e){fc["default"](e).data(f[fc["default"](e).data("field")])}),this.$container.off("click",".th-inner").on("click",".th-inner",function(j){var h=fc["default"](j.currentTarget);return d.options.detailView&&!h.parent().hasClass("bs-checkbox")&&h.closest(".bootstrap-table")[0]!==d.$container[0]?!1:void (d.options.sortable&&h.parent().data().sortable&&d.onSort(j))}),this.$header.children().children().off("keypress").on("keypress",function(j){if(d.options.sortable&&fc["default"](j.currentTarget).data().sortable){var h=j.keyCode||j.which;13===h&&d.onSort(j)}});var g=br.getEventName("resize.bootstrap-table",this.$el.attr("id"));fc["default"](window).off(g),!this.options.showHeader||this.options.cardView?(this.$header.hide(),this.$tableHeader.hide(),this.$tableLoading.css("top",0)):(this.$header.show(),this.$tableHeader.show(),this.$tableLoading.css("top",this.$header.outerHeight()+1),this.getCaret(),fc["default"](window).on(g,function(){return d.resetView()})),this.$selectAll=this.$header.find('[name="btSelectAll"]'),this.$selectAll.off("click").on("click",function(j){j.stopPropagation();var h=fc["default"](j.currentTarget).prop("checked");d[h?"checkAll":"uncheckAll"](),d.updateSelected()})}},{key:"initData",value:function(c,d){"append"===d?this.options.data=this.options.data.concat(c):"prepend"===d?this.options.data=[].concat(c).concat(this.options.data):(c=c||br.deepCopy(this.options.data),this.options.data=Array.isArray(c)?c:c[this.options.dataField]),this.data=fp(this.options.data),this.options.sortReset&&(this.unsortedData=fp(this.data)),"server"!==this.options.sidePagination&&this.initSort()}},{key:"initSort",value:function(){var d=this,f=this.options.sortName,c="desc"===this.options.sortOrder?-1:1,h=this.header.fields.indexOf(this.options.sortName),g=0;-1!==h?(this.options.sortStable&&this.data.forEach(function(i,j){i.hasOwnProperty("_position")||(i._position=j)}),this.options.customSort?br.calculateObjectValue(this.options,this.options.customSort,[this.options.sortName,this.options.sortOrder,this.data]):this.data.sort(function(m,i){d.header.sortNames[h]&&(f=d.header.sortNames[h]);var j=br.getItemField(m,f,d.options.escape),k=br.getItemField(i,f,d.options.escape),e=br.calculateObjectValue(d.header,d.header.sorters[h],[j,k,m,i]);return void 0!==e?d.options.sortStable&&0===e?c*(m._position-i._position):c*e:br.sort(j,k,c,d.options.sortStable,m._position,i._position)}),void 0!==this.options.sortClass&&(clearTimeout(g),g=setTimeout(function(){d.$el.removeClass(d.options.sortClass);var i=d.$header.find('[data-field="'.concat(d.options.sortName,'"]')).index();d.$el.find("tr td:nth-child(".concat(i+1,")")).addClass(d.options.sortClass)},250))):this.options.sortReset&&(this.data=fp(this.unsortedData))}},{key:"onSort",value:function(f){var g=f.type,d=f.currentTarget,j="keypress"===g?fc["default"](d):fc["default"](d).parent(),h=this.$header.find("th").eq(j.index());if(this.$header.add(this.$header_).find("span.order").remove(),this.options.sortName===j.data("field")){var c=this.options.sortOrder;void 0===c?this.options.sortOrder="asc":"asc"===c?this.options.sortOrder="desc":"desc"===this.options.sortOrder&&(this.options.sortOrder=this.options.sortReset?void 0:"asc"),void 0===this.options.sortOrder&&(this.options.sortName=void 0)}else{this.options.sortName=j.data("field"),this.options.rememberOrder?this.options.sortOrder="asc"===j.data("order")?"desc":"asc":this.options.sortOrder=this.columns[this.fieldsColumnsIndex[j.data("field")]].sortOrder||this.columns[this.fieldsColumnsIndex[j.data("field")]].order}return this.trigger("sort",this.options.sortName,this.options.sortOrder),j.add(h).data("order",this.options.sortOrder),this.getCaret(),"server"===this.options.sidePagination&&this.options.serverSort?(this.options.pageNumber=1,void this.initServer(this.options.silentSort)):(this.initSort(),void this.initBody())}},{key:"initToolbar",value:function(){var di,fn=this,ei=this.options,ee=[],ge=0,dn=0;this.$toolbar.find(".bs-bars").children().length&&fc["default"]("body").append(fc["default"](ei.toolbar)),this.$toolbar.html(""),("string"==typeof ei.toolbar||"object"===fD(ei.toolbar))&&fc["default"](br.sprintf('
    ',this.constants.classes.pull,ei.toolbarAlign)).appendTo(this.$toolbar).append(fc["default"](ei.toolbar)),ee=['
    ')],"string"==typeof ei.buttonsOrder&&(ei.buttonsOrder=ei.buttonsOrder.replace(/\[|\]| |'/g,"").split(",")),this.buttons=Object.assign(this.buttons,{search:{text:ei.formatSearch(),icon:ei.icons.search,render:!1,event:this.toggleShowSearch,attributes:{"aria-label":ei.formatShowSearch(),title:ei.formatShowSearch()}},paginationSwitch:{text:ei.pagination?ei.formatPaginationSwitchUp():ei.formatPaginationSwitchDown(),icon:ei.pagination?ei.icons.paginationSwitchDown:ei.icons.paginationSwitchUp,render:!1,event:this.togglePagination,attributes:{"aria-label":ei.formatPaginationSwitch(),title:ei.formatPaginationSwitch()}},refresh:{text:ei.formatRefresh(),icon:ei.icons.refresh,render:!1,event:this.refresh,attributes:{"aria-label":ei.formatRefresh(),title:ei.formatRefresh()}},toggle:{text:ei.formatToggle(),icon:ei.icons.toggleOff,render:!1,event:this.toggleView,attributes:{"aria-label":ei.formatToggleOn(),title:ei.formatToggleOn()}},fullscreen:{text:ei.formatFullscreen(),icon:ei.icons.fullscreen,render:!1,event:this.toggleFullscreen,attributes:{"aria-label":ei.formatFullscreen(),title:ei.formatFullscreen()}},columns:{render:!1,html:function s(){var e=[];if(e.push('
    \n \n ").concat(fn.constants.html.toolbarDropdown[0])),ei.showColumnsSearch&&(e.push(br.sprintf(fn.constants.html.toolbarDropdownItem,br.sprintf('',fn.constants.classes.input,ei.formatSearch()))),e.push(fn.constants.html.toolbarDropdownSeparator)),ei.showColumnsToggleAll){var d=fn.getVisibleColumns().length===fn.columns.filter(function(f){return !fn.isSelectionColumn(f)}).length;e.push(br.sprintf(fn.constants.html.toolbarDropdownItem,br.sprintf(' %s',d?'checked="checked"':"",ei.formatColumnsToggleAll()))),e.push(fn.constants.html.toolbarDropdownSeparator)}var c=0;return fn.columns.forEach(function(f){f.visible&&c++}),fn.columns.forEach(function(g,j){if(!fn.isSelectionColumn(g)&&(!ei.cardView||g.cardVisible)&&!g.ignore){var f=g.visible?' checked="checked"':"",h=c<=ei.minimumCountColumns&&f?' disabled="disabled"':"";g.switchable&&(e.push(br.sprintf(fn.constants.html.toolbarDropdownItem,br.sprintf(' %s',g.field,j,f,h,g.title))),dn++)}}),e.push(fn.constants.html.toolbarDropdown[1],"
    "),e.join("")}}});for(var eo={},ft=0,fa=Object.entries(this.buttons);ft"}eo[fo]=ea;var ct="show".concat(fo.charAt(0).toUpperCase()).concat(fo.substring(1)),es=ei[ct];!(!fi.hasOwnProperty("render")||fi.hasOwnProperty("render")&&fi.render)||void 0!==es&&es!==!0||(ei[ct]=!0),ei.buttonsOrder.includes(fo)||ei.buttonsOrder.push(fo)}var ai,Q=fg(ei.buttonsOrder);try{for(Q.s();!(ai=Q.n()).done;){var ce=ai.value,ae=ei["show".concat(ce.charAt(0).toUpperCase()).concat(ce.substring(1))];ae&&ee.push(eo[ce])}}catch(be){Q.e(be)}finally{Q.f()}ee.push("
    "),(this.showToolbar||ee.length>2)&&this.$toolbar.append(ee.join("")),ei.showSearch&&this.$toolbar.find('button[name="showSearch"]').off("click").on("click",function(){return fn.toggleShowSearch()});for(var cn=0,co=Object.entries(this.buttons);cn'),v=dt;if(ei.showSearchButton||ei.showSearchClearButton){var bn=(ei.showSearchButton?J:"")+(ei.showSearchClearButton?cs:"");v=ei.search?br.sprintf(this.constants.html.inputGroup,dt,bn):bn}ee.push(br.sprintf('\n
    \n %s\n
    \n '),v)),this.$toolbar.append(ee.join(""));var ba=br.getSearchInput(this);ei.showSearchButton?(this.$toolbar.find(".search button[name=search]").off("click").on("click",function(){clearTimeout(ge),ge=setTimeout(function(){fn.onSearch({currentTarget:ba})},ei.searchTimeOut)}),ei.searchOnEnterKey&&ao(ba)):ao(ba),ei.showSearchClearButton&&this.$toolbar.find(".search button[name=clearSearch]").click(function(){fn.resetSearch()})}else{if("string"==typeof ei.searchSelector){var i=br.getSearchInput(this);ao(i)}}}},{key:"onSearch",value:function(){var d=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},f=d.currentTarget,c=d.firedByInitSearchText,h=arguments.length>1&&void 0!==arguments[1]?arguments[1]:!0;if(void 0!==f&&fc["default"](f).length&&h){var g=fc["default"](f).val().trim();if(this.options.trimOnSearch&&fc["default"](f).val()!==g&&fc["default"](f).val(g),this.searchText===g){return}(f===br.getSearchInput(this)[0]||fc["default"](f).hasClass("search-input"))&&(this.searchText=g,this.options.searchText=g)}c||(this.options.pageNumber=1),this.initSearch(),c?"client"===this.options.sidePagination&&this.updatePagination():this.updatePagination(),this.trigger("search",this.searchText)}},{key:"initSearch",value:function(){var d=this;if(this.filterOptions=this.filterOptions||this.options.filterOptions,"server"!==this.options.sidePagination){if(this.options.customSearch){return this.data=br.calculateObjectValue(this.options,this.options.customSearch,[this.options.data,this.searchText,this.filterColumns]),void (this.options.sortReset&&(this.unsortedData=fp(this.data)))}var f=this.searchText&&(this.fromHtml?br.escapeHTML(this.searchText):this.searchText).toLowerCase(),c=br.isEmptyObject(this.filterColumns)?null:this.filterColumns;this.options.searchAccentNeutralise&&(f=br.normalizeAccent(f)),"function"==typeof this.filterOptions.filterAlgorithm?this.data=this.options.data.filter(function(h){return d.filterOptions.filterAlgorithm.apply(null,[h,c])}):"string"==typeof this.filterOptions.filterAlgorithm&&(this.data=c?this.options.data.filter(function(j){var l=d.filterOptions.filterAlgorithm;if("and"===l){for(var k in c){if(Array.isArray(c[k])&&!c[k].includes(j[k])||!Array.isArray(c[k])&&j[k]!==c[k]){return !1}}}else{if("or"===l){var h=!1;for(var i in c){(Array.isArray(c[i])&&c[i].includes(j[i])||!Array.isArray(c[i])&&j[i]===c[i])&&(h=!0)}return h}}return !0}):fp(this.options.data));var g=this.getVisibleFields();this.data=f?this.data.filter(function(n,k){for(var A=0;A|=<|>=|>|<)(?:\s+)?(-?\d+)?|(-?\d+)?(\s+)?(<=|=>|=<|>=|>|<))/gm,x=C.exec(d.searchText),w=!1;if(x){var j=x[1]||"".concat(x[5],"l"),t=x[2]||x[3],B=parseInt(m,10),z=parseInt(t,10);switch(j){case">":case"z;break;case"<":case">l":w=z>B;break;case"<=":case"=<":case">=l":case"=>l":w=z>=B;break;case">=":case"=>":case"<=l":case"==z}}if(w||"".concat(m).toLowerCase().includes(f)){return !0}}}}}return !1}):this.data,this.options.sortReset&&(this.unsortedData=fp(this.data)),this.initSort()}}},{key:"initPagination",value:function(){var O=this,K=this.options;if(!K.pagination){return void this.$pagination.hide()}this.$pagination.show();var G,F,T,C,D,I,Q,L=[],B=!1,P=this.getData({includeHiddenRows:!1}),N=K.pageList;if("string"==typeof N&&(N=N.replace(/\[|\]| /g,"").toLowerCase().split(",")),N=N.map(function(c){return"string"==typeof c?c.toLowerCase()===K.formatAllRows().toLowerCase()||["all","unlimited"].includes(c.toLowerCase())?K.formatAllRows():+c:c}),this.paginationParts=K.paginationParts,"string"==typeof this.paginationParts&&(this.paginationParts=this.paginationParts.replace(/\[|\]| |'/g,"").split(",")),"server"!==K.sidePagination&&(K.totalRows=P.length),this.totalPages=0,K.totalRows&&(K.pageSize===K.formatAllRows()&&(K.pageSize=K.totalRows,B=!0),this.totalPages=~~((K.totalRows-1)/K.pageSize)+1,K.totalPages=this.totalPages),this.totalPages>0&&K.pageNumber>this.totalPages&&(K.pageNumber=this.totalPages),this.pageFrom=(K.pageNumber-1)*K.pageSize+1,this.pageTo=K.pageNumber*K.pageSize,this.pageTo>K.totalRows&&(this.pageTo=K.totalRows),this.options.pagination&&"server"!==this.options.sidePagination&&(this.options.totalNotFiltered=this.options.data.length),this.options.showExtendedPagination||(this.options.totalNotFiltered=void 0),(this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")||this.paginationParts.includes("pageSize"))&&L.push('
    ')),this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")){var E=this.paginationParts.includes("pageInfoShort")?K.formatDetailPagination(K.totalRows):K.formatShowingRows(this.pageFrom,this.pageTo,K.totalRows,K.totalNotFiltered);L.push('\n '.concat(E,"\n "))}if(this.paginationParts.includes("pageSize")){L.push('
    ');var M=['
    \n \n ").concat(this.constants.html.pageDropdown[0])];N.forEach(function(c,e){if(!K.smartDisplay||0===e||N[e-1]")),L.push(K.formatRecordsPerPage(M.join("")))}if((this.paginationParts.includes("pageInfo")||this.paginationParts.includes("pageInfoShort")||this.paginationParts.includes("pageSize"))&&L.push("
    "),this.paginationParts.includes("pageList")){L.push('
    '),br.sprintf(this.constants.html.pagination[0],br.sprintf(" pagination-%s",K.iconSize)),br.sprintf(this.constants.html.paginationItem," page-pre",K.formatSRPaginationPreText(),K.paginationPreText)),this.totalPagesthis.totalPages-F&&(F=F-(K.paginationSuccessivelySize-(this.totalPages-F))+1),1>F&&(F=1),T>this.totalPages&&(T=this.totalPages);var A=Math.round(K.paginationPagesBySide/2),R=function(c){var d=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return br.sprintf(O.constants.html.paginationItem,d+(c===K.pageNumber?" ".concat(O.constants.classes.paginationActive):""),K.formatSRPaginationPageText(c),c)};if(F>1){var H=K.paginationPagesBySide;for(H>=F&&(H=F-1),G=1;H>=G;G++){L.push(R(G))}F-1===H+1?(G=F-1,L.push(R(G))):F-1>H&&(F-2*K.paginationPagesBySide>K.paginationPagesBySide&&K.paginationUseIntermediate?(G=Math.round((F-A)/2+A),L.push(R(G," page-intermediate"))):L.push(br.sprintf(this.constants.html.paginationItem," page-first-separator disabled","","...")))}for(G=F;T>=G;G++){L.push(R(G))}if(this.totalPages>T){var q=this.totalPages-(K.paginationPagesBySide-1);for(T>=q&&(q=T+1),T+1===q-1?(G=T+1,L.push(R(G))):q>T+1&&(this.totalPages-T>2*K.paginationPagesBySide&&K.paginationUseIntermediate?(G=Math.round((this.totalPages-A-T)/2+T),L.push(R(G," page-intermediate"))):L.push(br.sprintf(this.constants.html.paginationItem," page-last-separator disabled","","..."))),G=q;G<=this.totalPages;G++){L.push(R(G))}}L.push(br.sprintf(this.constants.html.paginationItem," page-next",K.formatSRPaginationNextText(),K.paginationNextText)),L.push(this.constants.html.pagination[1],"
    ")}this.$pagination.html(L.join(""));var z=["bottom","both"].includes(K.paginationVAlign)?" ".concat(this.constants.classes.dropup):"";if(this.$pagination.last().find(".page-list > div").addClass(z),!K.onlyInfoPagination&&(C=this.$pagination.find(".page-list a"),D=this.$pagination.find(".page-pre"),I=this.$pagination.find(".page-next"),Q=this.$pagination.find(".page-item").not(".page-next, .page-pre, .page-last-separator, .page-first-separator"),this.totalPages<=1&&this.$pagination.find("div.pagination").hide(),K.smartDisplay&&(N.length<2||K.totalRows<=N[0])&&this.$pagination.find("span.page-list").hide(),this.$pagination[this.getData().length?"show":"hide"](),K.paginationLoop||(1===K.pageNumber&&D.addClass("disabled"),K.pageNumber===this.totalPages&&I.addClass("disabled")),B&&(K.pageSize=K.formatAllRows()),C.off("click").on("click",function(c){return O.onPageListChange(c)}),D.off("click").on("click",function(c){return O.onPagePre(c)}),I.off("click").on("click",function(c){return O.onPageNext(c)}),Q.off("click").on("click",function(c){return O.onPageNumber(c)}),this.options.showPageGo)){var j=this,t=this.$pagination.find("ul.pagination"),J=t.find("li.pageGo");J.length||(J=fl('
  • '+br.sprintf('',this.options.pageNumber)+('
  • ").appendTo(t),J.find("button").click(function(){var c=parseInt(J.find("input").val())||1;(1>c||c>j.options.totalPages)&&(c=1),j.selectPage(c)}))}}},{key:"updatePagination",value:function(c){c&&fc["default"](c.currentTarget).hasClass("disabled")||(this.options.maintainMetaData||this.resetRows(),this.initPagination(),this.trigger("page-change",this.options.pageNumber,this.options.pageSize),"server"===this.options.sidePagination?this.initServer():this.initBody())}},{key:"onPageListChange",value:function(c){c.preventDefault();var d=fc["default"](c.currentTarget);return d.parent().addClass(this.constants.classes.dropdownActive).siblings().removeClass(this.constants.classes.dropdownActive),this.options.pageSize=d.text().toUpperCase()===this.options.formatAllRows().toUpperCase()?this.options.formatAllRows():+d.text(),this.$toolbar.find(".page-size").text(this.options.pageSize),this.updatePagination(c),!1}},{key:"onPagePre",value:function(c){return c.preventDefault(),this.options.pageNumber-1===0?this.options.pageNumber=this.options.totalPages:this.options.pageNumber--,this.updatePagination(c),!1}},{key:"onPageNext",value:function(c){return c.preventDefault(),this.options.pageNumber+1>this.options.totalPages?this.options.pageNumber=1:this.options.pageNumber++,this.updatePagination(c),!1}},{key:"onPageNumber",value:function(c){return c.preventDefault(),this.options.pageNumber!==+fc["default"](c.currentTarget).text()?(this.options.pageNumber=+fc["default"](c.currentTarget).text(),this.updatePagination(c),!1):void 0}},{key:"initRow",value:function(G,X,M,L){var ae=this,J=[],Q={},Z=[],U="",F={},Y=[];if(!(br.findIndex(this.hiddenRows,G)>-1)){if(Q=br.calculateObjectValue(this.options,this.options.rowStyle,[G,X],Q),Q&&Q.css){for(var W=0,K=Object.entries(Q.css);W"),this.options.cardView&&J.push('
    '));var A="";return br.hasDetailViewIcon(this.options)&&(A="",br.calculateObjectValue(null,this.options.detailFilter,[X,G])&&(A+='\n \n '.concat(br.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailOpen),"\n \n ")),A+=""),A&&"right"!==this.options.detailViewAlign&&J.push(A),this.header.fields.forEach(function(eo,dt){var dn="",ee=br.getItemField(G,eo,ae.options.escape),es="",de="",fe={},fa="",di=ae.header.classes[dt],et="",da="",fi="",ea="",co="",ct="",r=ae.columns[dt];if((!ae.fromHtml&&!ae.autoMergeCells||void 0!==ee||r.checkbox||r.radio)&&r.visible&&(!ae.options.cardView||r.cardVisible)){if(r.escape&&(ee=br.escapeHTML(ee)),Z.concat([ae.header.styles[dt]]).length&&(da+="".concat(Z.concat([ae.header.styles[dt]]).join("; "))),G["_".concat(eo,"_style")]&&(da+="".concat(G["_".concat(eo,"_style")])),da&&(et=' style="'.concat(da,'"')),G["_".concat(eo,"_id")]&&(fa=br.sprintf(' id="%s"',G["_".concat(eo,"_id")])),G["_".concat(eo,"_class")]&&(di=br.sprintf(' class="%s"',G["_".concat(eo,"_class")])),G["_".concat(eo,"_rowspan")]&&(ea=br.sprintf(' rowspan="%s"',G["_".concat(eo,"_rowspan")])),G["_".concat(eo,"_colspan")]&&(co=br.sprintf(' colspan="%s"',G["_".concat(eo,"_colspan")])),G["_".concat(eo,"_title")]&&(ct=br.sprintf(' title="%s"',G["_".concat(eo,"_title")])),fe=br.calculateObjectValue(ae.header,ae.header.cellStyles[dt],[ee,G,X,eo],fe),fe.classes&&(di=' class="'.concat(fe.classes,'"')),fe.css){for(var cs=[],ei=0,an=Object.entries(fe.css);ei$1",t=es&&/<(?=.*? .*?\/ ?>|br|hr|input|!--|wbr)[a-z]+.*?>|<([a-z]+).*?<\/\1>/i.test(es);if(t){var bo=(new DOMParser).parseFromString(""+es,"text/html").documentElement.textContent,en=bo.replace(ci,cn);be=es.replace(RegExp("(>\\s*)(".concat(bo,")(\\s*)"),"gm"),"$1".concat(en,"$3"))}else{be=(""+es).replace(ci,cn)}es=br.calculateObjectValue(r,r.searchHighlightFormatter,[es,ae.searchText],be)}if(G["_".concat(eo,"_data")]&&!br.isEmptyObject(G["_".concat(eo,"_data")])){for(var fn=0,ao=Object.entries(G["_".concat(eo,"_data")]);fn'):'"))+'")+(ae.header.formatters[dt]&&"string"==typeof es?es:"")+(ae.options.cardView?"
    ":""),G[ae.header.stateField]=es===!0||!!ee||es&&es.checked}else{if(ae.options.cardView){var at=ae.options.showHeader?'").concat(br.getFieldTitle(ae.columns,eo),""):"";dn='
    '.concat(at,'").concat(es,"
    "),ae.options.smartDisplay&&""===es&&(dn='
    ')}else{dn="").concat(es,"")}}J.push(dn)}}),A&&"right"===this.options.detailViewAlign&&J.push(A),this.options.cardView&&J.push("
    "),J.push(""),J.join("")}}},{key:"initBody",value:function(m){var j=this,h=this.getData();this.trigger("pre-body",h),this.$body=this.$el.find(">tbody"),this.$body.length||(this.$body=fc["default"]("").appendTo(this.$el)),this.options.pagination&&"server"!==this.options.sidePagination||(this.pageFrom=1,this.pageTo=h.length);var f=[],d=fc["default"](document.createDocumentFragment()),k=!1;this.autoMergeCells=br.checkAutoMergeCells(h.slice(this.pageFrom-1,this.pageTo));for(var p=this.pageFrom-1;p'.concat(br.sprintf('%s',this.getVisibleFields().length+br.getDetailViewIndexOffset(this.options),this.options.formatNoMatches()),"")),m||this.scrollTo(0),this.initBodyEvent(),this.updateSelected(),this.initFooter(),this.resetView(),"server"!==this.options.sidePagination&&(this.options.totalRows=h.length),this.trigger("post-body",h)}},{key:"initBodyEvent",value:function(){var c=this;this.$body.find("> tr[data-index] > td").off("click dblclick").on("click dblclick",function(v){var p=fc["default"](v.currentTarget),k=p.parent(),j=fc["default"](v.target).parents(".card-views").children(),y=fc["default"](v.target).parents(".card-view"),A=k.data("index"),g=c.data[A],m=c.options.cardView?j.index(y):p[0].cellIndex,x=c.getVisibleFields(),q=x[m-br.getDetailViewIndexOffset(c.options)],z=c.columns[c.fieldsColumnsIndex[q]],w=br.getItemField(g,q,c.options.escape);if(!p.find(".detail-icon").length){if(c.trigger("click"===v.type?"click-cell":"dbl-click-cell",q,w,g,p),c.trigger("click"===v.type?"click-row":"dbl-click-row",g,k,q),"click"===v.type&&c.options.clickToSelect&&z.clickToSelect&&!br.calculateObjectValue(c.options,c.options.ignoreClickToSelectOn,[v.target])){var t=k.find(br.sprintf('[name="%s"]',c.options.selectItemName));t.length&&t[0].click()}"click"===v.type&&c.options.detailViewByClick&&c.toggleDetailView(A,c.header.detailFormatters[c.fieldsColumnsIndex[q]])}}).off("mousedown").on("mousedown",function(d){c.multipleSelectRowCtrlKey=d.ctrlKey||d.metaKey,c.multipleSelectRowShiftKey=d.shiftKey}),this.$body.find("> tr[data-index] > td > .detail-icon").off("click").on("click",function(d){return d.preventDefault(),c.toggleDetailView(fc["default"](d.currentTarget).parent().parent().data("index")),!1}),this.$selectItem=this.$body.find(br.sprintf('[name="%s"]',this.options.selectItemName)),this.$selectItem.off("click").on("click",function(f){f.stopImmediatePropagation();var d=fc["default"](f.currentTarget);c._toggleCheck(d.prop("checked"),d.data("index"))}),this.header.events.forEach(function(j,f){var l=j;if(l){"string"==typeof l&&(l=br.calculateObjectValue(null,l));var k=c.header.fields[f],d=c.getVisibleFields().indexOf(k);if(-1!==d){d+=br.getDetailViewIndexOffset(c.options);var g=function(n){if(!l.hasOwnProperty(n)){return"continue"}var m=l[n];c.$body.find(">tr:not(.no-records-found)").each(function(v,p){var q=fc["default"](p),e=q.find(c.options.cardView?".card-views>.card-view":">td").eq(d),t=n.indexOf(" "),o=n.substring(0,t),i=n.substring(t+1);e.find(i).off(o).on(o,function(w){var x=q.data("index"),r=c.data[x],u=r[k];m.apply(c,[w,u,r,x])})})};for(var h in l){g(h)}}}})}},{key:"initServer",value:function(x,p,k){var g=this,f={},v=this.header.fields.indexOf(this.options.sortName),y={searchText:this.searchText,sortName:this.options.sortName,sortOrder:this.options.sortOrder};if(this.header.sortNames[v]&&(y.sortName=this.header.sortNames[v]),this.options.pagination&&"server"===this.options.sidePagination&&(y.pageSize=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize,y.pageNumber=this.options.pageNumber),!this.options.firstLoad&&!firstLoadTable.includes(this.options.id)){return void firstLoadTable.push(this.options.id)}if(k||this.options.url||this.options.ajax){if("limit"===this.options.queryParamsType&&(y={search:y.searchText,sort:y.sortName,order:y.sortOrder},this.options.pagination&&"server"===this.options.sidePagination&&(y.offset=this.options.pageSize===this.options.formatAllRows()?0:this.options.pageSize*(this.options.pageNumber-1),y.limit=this.options.pageSize===this.options.formatAllRows()?this.options.totalRows:this.options.pageSize,0===y.limit&&delete y.limit)),this.options.search&&"server"===this.options.sidePagination&&this.columns.filter(function(c){return !c.searchable}).length){y.searchable=[];var d,j=fg(this.columns);try{for(j.s();!(d=j.n()).done;){var q=d.value;!q.checkbox&&q.searchable&&(this.options.visibleSearch&&q.visible||!this.options.visibleSearch)&&y.searchable.push(q.field)}}catch(m){j.e(m)}finally{j.f()}}if(br.isEmptyObject(this.filterColumnsPartial)||(y.filter=JSON.stringify(this.filterColumnsPartial,null)),fc["default"].extend(y,p||{}),f=br.calculateObjectValue(this.options,this.options.queryParams,[y],f),f!==!1){x||this.showLoading();var w=fc["default"].extend({},br.calculateObjectValue(null,this.options.ajaxOptions),{type:this.options.method,url:k||this.options.url,data:"application/json"===this.options.contentType&&"post"===this.options.method?JSON.stringify(f):f,cache:this.options.cache,contentType:this.options.contentType,dataType:this.options.dataType,success:function(l,h,n){var c=br.calculateObjectValue(g.options,g.options.responseHandler,[l,n],l);g.load(c),g.trigger("load-success",c,n&&n.status,n),x||g.hideLoading(),"server"===g.options.sidePagination&&c[g.options.totalField]>0&&!c[g.options.dataField].length&&g.updatePagination()},error:function(h){var c=[];"server"===g.options.sidePagination&&(c={},c[g.options.totalField]=0,c[g.options.dataField]=[]),g.load(c),g.trigger("load-error",h&&h.status,h),x||g.$tableLoading.hide()}});return this.options.ajax?br.calculateObjectValue(this,this.options.ajax,[w],null):(this._xhr&&4!==this._xhr.readyState&&this._xhr.abort(),this._xhr=fc["default"].ajax(w)),f}}}},{key:"initSearchText",value:function(){if(this.options.search&&(this.searchText="",""!==this.options.searchText)){var c=br.getSearchInput(this);c.val(this.options.searchText),this.onSearch({currentTarget:c,firedByInitSearchText:!0})}}},{key:"getCaret",value:function(){var c=this;this.$header.find("th").each(function(f,d){fc["default"](d).find(".sortable").removeClass("desc asc").addClass(fc["default"](d).data("field")===c.options.sortName?c.options.sortOrder:"both")})}},{key:"updateSelected",value:function(){var c=this.$selectItem.filter(":enabled").length&&this.$selectItem.filter(":enabled").length===this.$selectItem.filter(":enabled").filter(":checked").length;this.$selectAll.add(this.$selectAll_).prop("checked",c),this.$selectItem.each(function(d,f){fc["default"](f).closest("tr")[fc["default"](f).prop("checked")?"addClass":"removeClass"]("selected")})}},{key:"updateRows",value:function(){var c=this;this.$selectItem.each(function(f,d){c.data[fc["default"](d).data("index")][c.header.stateField]=fc["default"](d).prop("checked")})}},{key:"resetRows",value:function(){var d,f=fg(this.data);try{for(f.s();!(d=f.n()).done;){var c=d.value;this.$selectAll.prop("checked",!1),this.$selectItem.prop("checked",!1),this.header.stateField&&(c[this.header.stateField]=!1)}}catch(g){f.e(g)}finally{f.f()}this.initHiddenRows()}},{key:"trigger",value:function(e){for(var d,j,h="".concat(e,".bs.table"),c=arguments.length,f=Array(c>1?c-1:0),g=1;c>g;g++){f[g-1]=arguments[g]}(d=this.options)[a.EVENTS[h]].apply(d,[].concat(f,[this])),this.$el.trigger(fc["default"].Event(h,{sender:this}),f),(j=this.options).onAll.apply(j,[h].concat([].concat(f,[this]))),this.$el.trigger(fc["default"].Event("all.bs.table",{sender:this}),[h,f])}},{key:"resetHeader",value:function(){var c=this;clearTimeout(this.timeoutId_),this.timeoutId_=setTimeout(function(){return c.fitHeader()},this.$el.is(":hidden")?100:0)}},{key:"fitHeader",value:function(){var x=this;if(this.$el.is(":hidden")){return void (this.timeoutId_=setTimeout(function(){return x.fitHeader()},100))}var p=this.$tableBody.get(0),k=p.scrollWidth>p.clientWidth&&p.scrollHeight>p.clientHeight+this.$header.outerHeight()?br.getScrollBarWidth():0;this.$el.css("margin-top",-this.$header.outerHeight());var g=fc["default"](":focus");if(g.length>0){var f=g.parents("th");if(f.length>0){var v=f.attr("data-field");if(void 0!==v){var y=this.$header.find("[data-field='".concat(v,"']"));y.length>0&&y.find(":input").addClass("focus-temp")}}}this.$header_=this.$header.clone(!0,!0),this.$selectAll_=this.$header_.find('[name="btSelectAll"]'),this.$tableHeader.css("margin-right",k).find("table").css("width",this.$el.outerWidth()).html("").attr("class",this.$el.attr("class")).append(this.$header_),this.$tableLoading.css("width",this.$el.outerWidth());var d=fc["default"](".focus-temp:visible:eq(0)");d.length>0&&(d.focus(),this.$header.find(".focus-temp").removeClass("focus-temp")),this.$header.find("th[data-field]").each(function(h,c){x.$header_.find(br.sprintf('th[data-field="%s"]',fc["default"](c).data("field"))).data(fc["default"](c).data())});for(var j=this.getVisibleFields(),q=this.$header_.find("th"),m=this.$body.find(">tr:not(.no-records-found,.virtual-scroll-top)").eq(0);m.length&&m.find('>td[colspan]:not([colspan="1"])').length;){m=m.next()}var w=m.find("> *").length;m.find("> *").each(function(A,l){var C=fc["default"](l);if(br.hasDetailViewIcon(x.options)&&(0===A&&"right"!==x.options.detailViewAlign||A===w-1&&"right"===x.options.detailViewAlign)){var B=q.filter(".detail"),c=B.innerWidth()-B.find(".fht-cell").width();return void B.find(".fht-cell").width(C.innerWidth()-c)}var u=A-br.getDetailViewIndexOffset(x.options),z=x.$header_.find(br.sprintf('th[data-field="%s"]',j[u]));z.length>1&&(z=fc["default"](q[C[0].cellIndex]));var t=z.innerWidth()-z.find(".fht-cell").width();z.find(".fht-cell").width(C.innerWidth()-t)}),this.horizontalScroll(),this.trigger("post-header")}},{key:"initFooter",value:function(){if(this.options.showFooter&&!this.options.cardView){var s=this.getData(),H=[],D="";br.hasDetailViewIcon(this.options)&&(D='
    '),D&&"right"!==this.options.detailViewAlign&&H.push(D);var A,z=fg(this.columns);try{for(z.s();!(A=z.n()).done;){var L=A.value,v="",C="",J=[],E={},q=br.sprintf(' class="%s"',L["class"]);if(L.visible&&(!(this.footerData&&this.footerData.length>0)||L.field in this.footerData[0])){if(this.options.cardView&&!L.cardVisible){return}if(v=br.sprintf("text-align: %s; ",L.falign?L.falign:L.align),C=br.sprintf("vertical-align: %s; ",L.valign),E=br.calculateObjectValue(null,this.options.footerStyle,[L]),E&&E.css){for(var I=0,G=Object.entries(E.css);I0&&(B=this.footerData[0]["_".concat(L.field,"_colspan")]||0),B&&H.push(' colspan="'.concat(B,'" ')),H.push(">"),H.push('
    ');var j="";this.footerData&&this.footerData.length>0&&(j=this.footerData[0][L.field]||""),H.push(br.calculateObjectValue(L,L.footerFormatter,[s,j],j)),H.push("
    "),H.push('
    '),H.push("
    "),H.push("")}}}catch(k){z.e(k)}finally{z.f()}D&&"right"===this.options.detailViewAlign&&H.push(D),this.options.height||this.$tableFooter.length||(this.$el.append(""),this.$tableFooter=this.$el.find("tfoot")),this.$tableFooter.find("tr").length||this.$tableFooter.html("
    "),this.$tableFooter.find("tr").html(H.join("")),this.trigger("post-footer",this.$tableFooter)}}},{key:"fitFooter",value:function(){var f=this;if(this.$el.is(":hidden")){return void setTimeout(function(){return f.fitFooter()},100)}var g=this.$tableBody.get(0),d=g.scrollWidth>g.clientWidth&&g.scrollHeight>g.clientHeight+this.$header.outerHeight()?br.getScrollBarWidth():0;this.$tableFooter.css("margin-right",d).find("table").css("width",this.$el.outerWidth()).attr("class",this.$el.attr("class"));var j=this.$tableFooter.find("th"),h=this.$body.find(">tr:first-child:not(.no-records-found)");for(j.find(".fht-cell").width("auto");h.length&&h.find('>td[colspan]:not([colspan="1"])').length;){h=h.next()}var c=h.find("> *").length;h.find("> *").each(function(q,m){var t=fc["default"](m);if(br.hasDetailViewIcon(f.options)&&(0===q&&"left"===f.options.detailViewAlign||q===c-1&&"right"===f.options.detailViewAlign)){var n=j.filter(".detail"),p=n.innerWidth()-n.find(".fht-cell").width();return void n.find(".fht-cell").width(t.innerWidth()-p)}var k=j.eq(q),u=k.innerWidth()-k.find(".fht-cell").width();k.find(".fht-cell").width(t.innerWidth()-u)}),this.horizontalScroll()}},{key:"horizontalScroll",value:function(){var c=this;this.$tableBody.off("scroll").on("scroll",function(){var d=c.$tableBody.scrollLeft();c.options.showHeader&&c.options.height&&c.$tableHeader.scrollLeft(d),c.options.showFooter&&!c.options.cardView&&c.$tableFooter.scrollLeft(d),c.trigger("scroll-body",c.$tableBody)})}},{key:"getVisibleFields",value:function(){var f,g=[],d=fg(this.header.fields);try{for(d.s();!(f=d.n()).done;){var j=f.value,h=this.columns[this.fieldsColumnsIndex[j]];h&&h.visible&&g.push(j)}}catch(c){d.e(c)}finally{d.f()}return g}},{key:"initHiddenRows",value:function(){this.hiddenRows=[]}},{key:"getOptions",value:function(){var c=fc["default"].extend({},this.options);return delete c.data,fc["default"].extend(!0,{},c)}},{key:"refreshOptions",value:function(c){br.compareObjects(this.options,c,!0)||(this.options=fc["default"].extend(this.options,c),this.trigger("refresh-options",this.options),this.destroy(),this.init())}},{key:"getData",value:function(d){var f=this,c=this.options.data;if(!(this.searchText||this.options.customSearch||void 0!==this.options.sortName||this.enableCustomSort)&&br.isEmptyObject(this.filterColumns)&&br.isEmptyObject(this.filterColumnsPartial)||d&&d.unfiltered||(c=this.data),d&&d.useCurrentPage&&(c=c.slice(this.pageFrom-1,this.pageTo)),d&&!d.includeHiddenRows){var g=this.getHiddenRows();c=c.filter(function(e){return -1===br.findIndex(g,e)})}return d&&d.formatted&&c.forEach(function(k){for(var j=0,q=Object.entries(k);j=0;c--){var g=this.options.data[c];(g.hasOwnProperty(d.field)||"$index"===d.field)&&(!g.hasOwnProperty(d.field)&&"$index"===d.field&&d.values.includes(c)||d.values.includes(g[d.field]))&&(f++,this.options.data.splice(c,1))}f&&("server"===this.options.sidePagination&&(this.options.totalRows-=f,this.data=fp(this.options.data)),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))}},{key:"removeAll",value:function(){this.options.data.length>0&&(this.options.data.splice(0,this.options.data.length),this.initSearch(),this.initPagination(),this.initBody(!0))}},{key:"insertRow",value:function(c){c.hasOwnProperty("index")&&c.hasOwnProperty("row")&&(this.options.data.splice(c.index,0,c.row),this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0))}},{key:"updateRow",value:function(f){var g,d=Array.isArray(f)?f:[f],j=fg(d);try{for(j.s();!(g=j.n()).done;){var h=g.value;h.hasOwnProperty("index")&&h.hasOwnProperty("row")&&(h.hasOwnProperty("replace")&&h.replace?this.options.data[h.index]=h.row:fc["default"].extend(this.options.data[h.index],h.row))}}catch(c){j.e(c)}finally{j.f()}this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0)}},{key:"getRowByUniqueId",value:function(f){var j,d,l,k=this.options.uniqueId,c=this.options.data.length,g=f,h=null;for(j=c-1;j>=0;j--){if(d=this.options.data[j],d.hasOwnProperty(k)){l=d[k]}else{if(!d._data||!d._data.hasOwnProperty(k)){continue}l=d._data[k]}if("string"==typeof l?g=""+g:"number"==typeof l&&(+l===l&&l%1===0?g=parseInt(g):l===+l&&0!==l&&(g=parseFloat(g))),l===g){h=d;break}}return h}},{key:"updateByUniqueId",value:function(f){var h,d=Array.isArray(f)?f:[f],k=fg(d);try{for(k.s();!(h=k.n()).done;){var j=h.value;if(j.hasOwnProperty("id")&&j.hasOwnProperty("row")){var c=this.options.data.indexOf(this.getRowByUniqueId(j.id));-1!==c&&(j.hasOwnProperty("replace")&&j.replace?this.options.data[c]=j.row:fc["default"].extend(this.options.data[c],j.row))}}}catch(g){k.e(g)}finally{k.f()}this.initSearch(),this.initPagination(),this.initSort(),this.initBody(!0)}},{key:"removeByUniqueId",value:function(d){var f=this.options.data.length,c=this.getRowByUniqueId(d);c&&this.options.data.splice(this.options.data.indexOf(c),1),f!==this.options.data.length&&("server"===this.options.sidePagination&&(this.options.totalRows-=1,this.data=fp(this.options.data)),this.initSearch(),this.initPagination(),this.initBody(!0))}},{key:"updateCell",value:function(c){c.hasOwnProperty("index")&&c.hasOwnProperty("field")&&c.hasOwnProperty("value")&&(this.data[c.index][c.field]=c.value,c.reinit!==!1&&(this.initSort(),this.initBody(!0)))}},{key:"updateCellByUniqueId",value:function(d){var f=this,c=Array.isArray(d)?d:[d];c.forEach(function(h){var g=h.id,k=h.field,j=h.value,e=f.options.data.indexOf(f.getRowByUniqueId(g));-1!==e&&(f.options.data[e][k]=j)}),d.reinit!==!1&&(this.initSort(),this.initBody(!0))}},{key:"showRow",value:function(c){this._toggleRow(c,!0)}},{key:"hideRow",value:function(c){this._toggleRow(c,!1)}},{key:"_toggleRow",value:function(d,f){var c;if(d.hasOwnProperty("index")?c=this.getData()[d.index]:d.hasOwnProperty("uniqueId")&&(c=this.getRowByUniqueId(d.uniqueId)),c){var g=br.findIndex(this.hiddenRows,c);f||-1!==g?f&&g>-1&&this.hiddenRows.splice(g,1):this.hiddenRows.push(c),this.initBody(!0),this.initPagination()}}},{key:"getHiddenRows",value:function(f){if(f){return this.initHiddenRows(),this.initBody(!0),void this.initPagination()}var h,d=this.getData(),k=[],j=fg(d);try{for(j.s();!(h=j.n()).done;){var c=h.value;this.hiddenRows.includes(c)&&k.push(c)}}catch(g){j.e(g)}finally{j.f()}return this.hiddenRows=k,k}},{key:"showColumn",value:function(d){var f=this,c=Array.isArray(d)?d:[d];c.forEach(function(e){f._toggleColumn(f.fieldsColumnsIndex[e],!0,!0)})}},{key:"hideColumn",value:function(d){var f=this,c=Array.isArray(d)?d:[d];c.forEach(function(e){f._toggleColumn(f.fieldsColumnsIndex[e],!1,!0)})}},{key:"_toggleColumn",value:function(d,f,c){if(-1!==d&&this.columns[d].visible!==f&&(this.columns[d].visible=f,this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns)){var g=this.$toolbar.find('.keep-open input:not(".toggle-all")').prop("disabled",!1);c&&g.filter(br.sprintf('[value="%s"]',d)).prop("checked",f),g.filter(":checked").length<=this.options.minimumCountColumns&&g.filter(":checked").prop("disabled",!0)}}},{key:"getVisibleColumns",value:function(){var c=this;return this.columns.filter(function(d){return d.visible&&!c.isSelectionColumn(d)})}},{key:"getHiddenColumns",value:function(){return this.columns.filter(function(c){var d=c.visible;return !d})}},{key:"isSelectionColumn",value:function(c){return c.radio||c.checkbox}},{key:"showAllColumns",value:function(){this._toggleAllColumns(!0)}},{key:"hideAllColumns",value:function(){this._toggleAllColumns(!1)}},{key:"_toggleAllColumns",value:function(f){var h,d=this,k=fg(this.columns.slice().reverse());try{for(k.s();!(h=k.n()).done;){var j=h.value;if(j.switchable){if(!f&&this.options.showColumns&&this.getVisibleColumns().length===this.options.minimumCountColumns){continue}j.visible=f}}}catch(c){k.e(c)}finally{k.f()}if(this.initHeader(),this.initSearch(),this.initPagination(),this.initBody(),this.options.showColumns){var g=this.$toolbar.find('.keep-open input[type="checkbox"]:not(".toggle-all")').prop("disabled",!1);f?g.prop("checked",f):g.get().reverse().forEach(function(i){g.filter(":checked").length>d.options.minimumCountColumns&&fc["default"](i).prop("checked",f)}),g.filter(":checked").length<=this.options.minimumCountColumns&&g.filter(":checked").prop("disabled",!0)}}},{key:"mergeCells",value:function(m){var j,h,f=m.index,d=this.getVisibleFields().indexOf(m.field),k=m.rowspan||1,p=m.colspan||1,c=this.$body.find(">tr");d+=br.getDetailViewIndexOffset(this.options);var g=c.eq(f).find(">td").eq(d);if(!(0>f||0>d||f>=this.data.length)){for(j=f;f+k>j;j++){for(h=d;d+p>h;h++){c.eq(j).find(">td").eq(h).hide()}}g.attr("rowspan",k).attr("colspan",p).show()}}},{key:"checkAll",value:function(){this._toggleCheckAll(!0)}},{key:"uncheckAll",value:function(){this._toggleCheckAll(!1)}},{key:"_toggleCheckAll",value:function(d){var f=this.getSelections();this.$selectAll.add(this.$selectAll_).prop("checked",d),this.$selectItem.filter(":enabled").prop("checked",d),this.updateRows(),this.updateSelected();var c=this.getSelections();return d?void this.trigger("check-all",c,f):void this.trigger("uncheck-all",c,f)}},{key:"checkInvert",value:function(){var c=this.$selectItem.filter(":enabled"),d=c.filter(":checked");c.each(function(f,g){fc["default"](g).prop("checked",!fc["default"](g).prop("checked"))}),this.updateRows(),this.updateSelected(),this.trigger("uncheck-some",d),d=this.getSelections(),this.trigger("check-some",d)}},{key:"check",value:function(c){this._toggleCheck(!0,c)}},{key:"uncheck",value:function(c){this._toggleCheck(!1,c)}},{key:"_toggleCheck",value:function(A,v){var p=this.$selectItem.filter('[data-index="'.concat(v,'"]')),k=this.data[v];if(p.is(":radio")||this.options.singleSelect||this.options.multipleSelectRow&&!this.multipleSelectRowCtrlKey&&!this.multipleSelectRowShiftKey){var j,y=fg(this.options.data);try{for(y.s();!(j=y.n()).done;){var g=j.value;g[this.header.stateField]=!1}}catch(m){y.e(m)}finally{y.f()}this.$selectItem.filter(":checked").not(p).prop("checked",!1)}if(k[this.header.stateField]=A,this.options.multipleSelectRow){if(this.multipleSelectRowShiftKey&&this.multipleSelectRowLastSelectedIndex>=0){for(var x=this.multipleSelectRowLastSelectedIndexs;s++){this.data[s][this.header.stateField]=!0,this.$selectItem.filter('[data-index="'.concat(s,'"]')).prop("checked",!0)}}this.multipleSelectRowCtrlKey=!1,this.multipleSelectRowShiftKey=!1,this.multipleSelectRowLastSelectedIndex=A?v:-1}p.prop("checked",A),this.updateSelected(),this.trigger(A?"check":"uncheck",this.data[v],p)}},{key:"checkBy",value:function(c){this._toggleCheckBy(!0,c)}},{key:"uncheckBy",value:function(c){this._toggleCheckBy(!1,c)}},{key:"_toggleCheckBy",value:function(d,f){var c=this;if(f.hasOwnProperty("field")&&f.hasOwnProperty("values")){var g=[];this.data.forEach(function(i,e){if(!i.hasOwnProperty(f.field)){return !1}if(f.values.includes(i[f.field])){var h=c.$selectItem.filter(":enabled").filter(br.sprintf('[data-index="%s"]',e));if(h=d?h.not(":checked"):h.filter(":checked"),!h.length){return}h.prop("checked",d),i[c.header.stateField]=d,g.push(i),c.trigger(d?"check":"uncheck",i,h)}}),this.updateSelected(),this.trigger(d?"check-some":"uncheck-some",g)}}},{key:"refresh",value:function(c){c&&c.url&&(this.options.url=c.url),c&&c.pageNumber&&(this.options.pageNumber=c.pageNumber),c&&c.pageSize&&(this.options.pageSize=c.pageSize),table.rememberSelecteds={},table.rememberSelectedIds={},this.trigger("refresh",this.initServer(c&&c.silent,c&&c.query,c&&c.url))}},{key:"destroy",value:function(){this.$el.insertBefore(this.$container),fc["default"](this.options.toolbar).insertBefore(this.$el),this.$container.next().remove(),this.$container.remove(),this.$el.html(this.$el_.html()).css("margin-top","0").attr("class",this.$el_.attr("class")||"")}},{key:"resetView",value:function(f){var j=0;if(f&&f.height&&(this.options.height=f.height),this.$selectAll.prop("checked",this.$selectItem.length>0&&this.$selectItem.length===this.$selectItem.filter(":checked").length),this.$tableContainer.toggleClass("has-card-view",this.options.cardView),!this.options.cardView&&this.options.showHeader&&this.options.height?(this.$tableHeader.show(),this.resetHeader(),j+=this.$header.outerHeight(!0)+1):(this.$tableHeader.hide(),this.trigger("post-header")),!this.options.cardView&&this.options.showFooter&&(this.$tableFooter.show(),this.fitFooter(),this.options.height&&(j+=this.$tableFooter.outerHeight(!0))),this.$container.hasClass("fullscreen")){this.$tableContainer.css("height",""),this.$tableContainer.css("width","")}else{if(this.options.height){this.$tableBorder&&(this.$tableBorder.css("width",""),this.$tableBorder.css("height",""));var d=this.$toolbar.outerHeight(!0),l=this.$pagination.outerHeight(!0),k=this.options.height-d-l,c=this.$tableBody.find(">table"),g=c.outerHeight();if(this.$tableContainer.css("height","".concat(k,"px")),this.$tableBorder&&c.is(":visible")){var h=k-g-2;this.$tableBody[0].scrollWidth-this.$tableBody.innerWidth()&&(h-=br.getScrollBarWidth()),this.$tableBorder.css("width","".concat(c.outerWidth(),"px")),this.$tableBorder.css("height","".concat(h,"px"))}}}this.options.cardView?(this.$el.css("margin-top","0"),this.$tableContainer.css("padding-bottom","0"),this.$tableFooter.hide()):(this.getCaret(),this.$tableContainer.css("padding-bottom","".concat(j,"px"))),this.trigger("reset-view")}},{key:"showLoading",value:function(){this.$tableLoading.toggleClass("open",!0);var c=this.options.loadingFontSize;"auto"===this.options.loadingFontSize&&(c=0.04*this.$tableLoading.width(),c=Math.max(12,c),c=Math.min(32,c),c="".concat(c,"px")),this.$tableLoading.find(".loading-text").css("font-size",c)}},{key:"hideLoading",value:function(){this.$tableLoading.toggleClass("open",!1)}},{key:"toggleShowSearch",value:function(){this.$el.parents(".select-table").siblings().slideToggle()}},{key:"togglePagination",value:function(){this.options.pagination=!this.options.pagination;var c=this.options.showButtonIcons?this.options.pagination?this.options.icons.paginationSwitchDown:this.options.icons.paginationSwitchUp:"",d=this.options.showButtonText?this.options.pagination?this.options.formatPaginationSwitchUp():this.options.formatPaginationSwitchDown():"";this.$toolbar.find('button[name="paginationSwitch"]').html("".concat(br.sprintf(this.constants.html.icon,this.options.iconsPrefix,c)," ").concat(d)),this.updatePagination()}},{key:"toggleFullscreen",value:function(){this.$el.closest(".bootstrap-table").toggleClass("fullscreen"),this.resetView()}},{key:"toggleView",value:function(){this.options.cardView=!this.options.cardView,this.initHeader();var c=this.options.showButtonIcons?this.options.cardView?this.options.icons.toggleOn:this.options.icons.toggleOff:"",d=this.options.showButtonText?this.options.cardView?this.options.formatToggleOff():this.options.formatToggleOn():"";this.$toolbar.find('button[name="toggle"]').html("".concat(br.sprintf(this.constants.html.icon,this.options.iconsPrefix,c)," ").concat(d)),this.initBody(),this.trigger("toggle",this.options.cardView)}},{key:"resetSearch",value:function(c){var d=br.getSearchInput(this);d.val(c||""),this.onSearch({currentTarget:d})}},{key:"filterBy",value:function(c,d){this.filterOptions=br.isEmptyObject(d)?this.options.filterOptions:fc["default"].extend(this.options.filterOptions,d),this.filterColumns=br.isEmptyObject(c)?{}:c,this.options.pageNumber=1,this.initSearch(),this.updatePagination()}},{key:"scrollTo",value:function b(c){var d={unit:"px",value:0};"object"===fD(c)?d=Object.assign(d,c):"string"==typeof c&&"bottom"===c?d.value=this.$tableBody[0].scrollHeight:("string"==typeof c||"number"==typeof c)&&(d.value=c);var f=d.value;"rows"===d.unit&&(f=0,this.$body.find("> tr:lt(".concat(d.value,")")).each(function(g,h){f+=fc["default"](h).outerHeight(!0)})),this.$tableBody.scrollTop(f)}},{key:"getScrollPosition",value:function(){return this.$tableBody.scrollTop()}},{key:"selectPage",value:function(c){c>0&&c<=this.options.totalPages&&(this.options.pageNumber=c,this.updatePagination())}},{key:"prevPage",value:function(){this.options.pageNumber>1&&(this.options.pageNumber--,this.updatePagination())}},{key:"nextPage",value:function(){this.options.pageNumber tr[data-index="%s"]',d));c.next().is("tr.detail-view")?this.collapseRow(d):this.expandRow(d,f),this.resetView()}},{key:"expandRow",value:function(f,h){var d=this.data[f],k=this.$body.find(br.sprintf('> tr[data-index="%s"][data-has-detail-view]',f));if(!k.next().is("tr.detail-view")){this.options.detailViewIcon&&k.find("a.detail-icon").html(br.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailClose)),k.after(br.sprintf('',k.children("td").length));var j=k.next().find("td"),c=h||this.options.detailFormatter,g=br.calculateObjectValue(this.options,c,[f,d,j],"");1===j.length&&j.append(g),this.trigger("expand-row",f,d,j)}}},{key:"expandRowByUniqueId",value:function(c){var d=this.getRowByUniqueId(c);d&&this.expandRow(this.data.indexOf(d))}},{key:"collapseRow",value:function(d){var f=this.data[d],c=this.$body.find(br.sprintf('> tr[data-index="%s"][data-has-detail-view]',d));c.next().is("tr.detail-view")&&(this.options.detailViewIcon&&c.find("a.detail-icon").html(br.sprintf(this.constants.html.icon,this.options.iconsPrefix,this.options.icons.detailOpen)),this.trigger("collapse-row",d,f,c.next()),c.next().remove())}},{key:"collapseRowByUniqueId",value:function(c){var d=this.getRowByUniqueId(c);d&&this.collapseRow(this.data.indexOf(d))}},{key:"expandAllRows",value:function(){for(var c=this.$body.find("> tr[data-index][data-has-detail-view]"),d=0;d tr[data-index][data-has-detail-view]"),d=0;d1?d-1:0),f=1;d>f;f++){g[f-1]=arguments[f]}var b;return this.each(function(j,k){var h=fc["default"](k).data("bootstrap.table"),i=fc["default"].extend({},d5.DEFAULTS,fc["default"](k).data(),"object"===fD(c)&&c);if("string"==typeof c){var a;if(!fb.METHODS.includes(c)){throw Error("Unknown method: ".concat(c))}if(!h){return}b=(a=h)[c].apply(a,g),"destroy"===c&&fc["default"](k).removeData("bootstrap.table")}h||(h=new fc["default"].BootstrapTable(k,i),fc["default"](k).data("bootstrap.table",h),h.init())}),void 0===b?this:b},fc["default"].fn.bootstrapTable.Constructor=d5,fc["default"].fn.bootstrapTable.theme=fb.THEME,fc["default"].fn.bootstrapTable.VERSION=fb.VERSION,fc["default"].fn.bootstrapTable.defaults=d5.DEFAULTS,fc["default"].fn.bootstrapTable.columnDefaults=d5.COLUMN_DEFAULTS,fc["default"].fn.bootstrapTable.events=d5.EVENTS,fc["default"].fn.bootstrapTable.locales=d5.LOCALES,fc["default"].fn.bootstrapTable.methods=d5.METHODS,fc["default"].fn.bootstrapTable.utils=br,fc["default"](function(){fc["default"]('[data-toggle="table"]').bootstrapTable()}),d5});var TABLE_EVENTS="all.bs.table click-cell.bs.table dbl-click-cell.bs.table click-row.bs.table dbl-click-row.bs.table sort.bs.table check.bs.table uncheck.bs.table onUncheck check-all.bs.table uncheck-all.bs.table check-some.bs.table uncheck-some.bs.table load-success.bs.table load-error.bs.table column-switch.bs.table page-change.bs.table search.bs.table toggle.bs.table show-search.bs.table expand-row.bs.table collapse-row.bs.table refresh-options.bs.table reset-view.bs.table refresh.bs.table",firstLoadTable=[],union=function(a,b){return $.isPlainObject(b)?addRememberRow(a,b):$.isArray(b)?$.each(b,function(d,c){$.isPlainObject(c)?addRememberRow(a,c):-1==$.inArray(c,a)&&(a[a.length]=c)}):-1==$.inArray(b,a)&&(a[a.length]=b),a},difference=function(b,c){if($.isPlainObject(c)){removeRememberRow(b,c)}else{if($.isArray(c)){$.each(c,function(f,d){if($.isPlainObject(d)){removeRememberRow(b,d)}else{var g=$.inArray(d,b);-1!=g&&b.splice(g,1)}})}else{var a=$.inArray(c,b);-1!=a&&b.splice(a,1)}}return b},_={union:union,difference:difference}; \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js new file mode 100644 index 00000000..8a5b44dc --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/auto-refresh/bootstrap-table-auto-refresh.js @@ -0,0 +1,93 @@ +/** + * @author: Alec Fenichel + * @webSite: https://fenichelar.com + * @update: zhixin wen + */ + +var Utils = $.fn.bootstrapTable.utils + +$.extend($.fn.bootstrapTable.defaults, { + autoRefresh: false, + autoRefreshInterval: 60, + autoRefreshSilent: true, + autoRefreshStatus: true, + autoRefreshFunction: null +}) + +$.extend($.fn.bootstrapTable.defaults.icons, { + autoRefresh: { + bootstrap3: 'glyphicon-time icon-time', + materialize: 'access_time', + 'bootstrap-table': 'icon-clock' + }[$.fn.bootstrapTable.theme] || 'fa-clock' +}) + +$.extend($.fn.bootstrapTable.locales, { + formatAutoRefresh () { + return 'Auto Refresh' + } +}) + +$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales) + +$.BootstrapTable = class extends $.BootstrapTable { + init (...args) { + super.init(...args) + + if (this.options.autoRefresh && this.options.autoRefreshStatus) { + this.setupRefreshInterval() + } + } + + initToolbar (...args) { + if (this.options.autoRefresh) { + this.buttons = Object.assign(this.buttons, { + autoRefresh: { + html: ` + + `, + event: this.toggleAutoRefresh + } + }) + } + + super.initToolbar(...args) + } + + toggleAutoRefresh () { + if (this.options.autoRefresh) { + if (this.options.autoRefreshStatus) { + clearInterval(this.options.autoRefreshFunction) + this.$toolbar.find('>.columns .auto-refresh') + .removeClass(this.constants.classes.buttonActive) + } else { + this.setupRefreshInterval() + this.$toolbar.find('>.columns .auto-refresh') + .addClass(this.constants.classes.buttonActive) + } + this.options.autoRefreshStatus = !this.options.autoRefreshStatus + } + } + + destroy () { + if (this.options.autoRefresh && this.options.autoRefreshStatus) { + clearInterval(this.options.autoRefreshFunction) + } + + super.destroy() + } + + setupRefreshInterval () { + this.options.autoRefreshFunction = setInterval(() => { + if (!this.options.autoRefresh || !this.options.autoRefreshStatus) { + return + } + this.refresh({ silent: this.options.autoRefreshSilent }) + }, this.options.autoRefreshInterval * 1000) + } +} diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js new file mode 100644 index 00000000..ab477949 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/columns/bootstrap-table-fixed-columns.js @@ -0,0 +1,404 @@ +/** + * @author zhixin wen + */ + +var Utils = $.fn.bootstrapTable.utils + +// Reasonable defaults +const PIXEL_STEP = 10 +const LINE_HEIGHT = 40 +const PAGE_HEIGHT = 800 + +function normalizeWheel (event) { + let sX = 0 // spinX + let sY = 0 // spinY + let pX = 0 // pixelX + let pY = 0 // pixelY + + // Legacy + if ('detail' in event) { sY = event.detail } + if ('wheelDelta' in event) { sY = -event.wheelDelta / 120 } + if ('wheelDeltaY' in event) { sY = -event.wheelDeltaY / 120 } + if ('wheelDeltaX' in event) { sX = -event.wheelDeltaX / 120 } + + // side scrolling on FF with DOMMouseScroll + if ('axis' in event && event.axis === event.HORIZONTAL_AXIS) { + sX = sY + sY = 0 + } + + pX = sX * PIXEL_STEP + pY = sY * PIXEL_STEP + + if ('deltaY' in event) { pY = event.deltaY } + if ('deltaX' in event) { pX = event.deltaX } + + if ((pX || pY) && event.deltaMode) { + if (event.deltaMode === 1) { // delta in LINE units + pX *= LINE_HEIGHT + pY *= LINE_HEIGHT + } else { // delta in PAGE units + pX *= PAGE_HEIGHT + pY *= PAGE_HEIGHT + } + } + + // Fall-back if spin cannot be determined + if (pX && !sX) { sX = (pX < 1) ? -1 : 1 } + if (pY && !sY) { sY = (pY < 1) ? -1 : 1 } + + return { + spinX: sX, + spinY: sY, + pixelX: pX, + pixelY: pY + } +} + +$.extend($.fn.bootstrapTable.defaults, { + fixedColumns: false, + fixedNumber: 0, + fixedRightNumber: 0 +}) + +$.BootstrapTable = class extends $.BootstrapTable { + + fixedColumnsSupported () { + return this.options.fixedColumns && + !this.options.detailView && + !this.options.cardView + } + + initContainer () { + super.initContainer() + + if (!this.fixedColumnsSupported()) { + return + } + + if (this.options.fixedNumber) { + this.$tableContainer.append('
    ') + this.$fixedColumns = this.$tableContainer.find('.fixed-columns') + } + + if (this.options.fixedRightNumber) { + this.$tableContainer.append('
    ') + this.$fixedColumnsRight = this.$tableContainer.find('.fixed-columns-right') + } + } + + initBody (...args) { + super.initBody(...args) + + if (this.$fixedColumns && this.$fixedColumns.length) { + this.$fixedColumns.toggle(this.fixedColumnsSupported()) + } + if (this.$fixedColumnsRight && this.$fixedColumnsRight.length) { + this.$fixedColumnsRight.toggle(this.fixedColumnsSupported()) + } + + if (!this.fixedColumnsSupported()) { + return + } + + if (this.options.showHeader && this.options.height) { + return + } + + this.initFixedColumnsBody() + this.initFixedColumnsEvents() + } + + trigger (...args) { + super.trigger(...args) + + if (!this.fixedColumnsSupported()) { + return + } + + if (args[0] === 'post-header') { + this.initFixedColumnsHeader() + } else if (args[0] === 'scroll-body') { + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody.scrollTop(this.$tableBody.scrollTop()) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight.scrollTop(this.$tableBody.scrollTop()) + } + } + } + + updateSelected () { + super.updateSelected() + + if (!this.fixedColumnsSupported()) { + return + } + + this.$tableBody.find('tr').each((i, el) => { + const $el = $(el) + const index = $el.data('index') + const classes = $el.attr('class') + + const inputSelector = `[name="${this.options.selectItemName}"]` + const $input = $el.find(inputSelector) + + if (typeof index === undefined) { + return + } + + const updateFixedBody = ($fixedHeader, $fixedBody) => { + const $tr = $fixedBody.find(`tr[data-index="${index}"]`) + + $tr.attr('class', classes) + + if ($input.length) { + $tr.find(inputSelector).prop('checked', $input.prop('checked')) + } + + if (this.$selectAll.length) { + $fixedHeader.add($fixedBody) + .find('[name="btSelectAll"]') + .prop('checked', this.$selectAll.prop('checked')) + } + } + + if (this.$fixedBody && this.options.fixedNumber) { + updateFixedBody(this.$fixedHeader, this.$fixedBody) + } + + if (this.$fixedBodyRight && this.options.fixedRightNumber) { + updateFixedBody(this.$fixedHeaderRight, this.$fixedBodyRight) + } + }) + } + + hideLoading () { + super.hideLoading() + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedColumns.find('.fixed-table-loading').hide() + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedColumnsRight.find('.fixed-table-loading').hide() + } + } + + initFixedColumnsHeader () { + if (this.options.height) { + this.needFixedColumns = this.$tableHeader.outerWidth(true) < this.$tableHeader.find('table').outerWidth(true) + } else { + this.needFixedColumns = this.$tableBody.outerWidth(true) < this.$tableBody.find('table').outerWidth(true) + } + + const initFixedHeader = ($fixedColumns, isRight) => { + $fixedColumns.find('.fixed-table-header').remove() + $fixedColumns.append(this.$tableHeader.clone(true)) + + $fixedColumns.css({ + width: this.getFixedColumnsWidth(isRight) + }) + return $fixedColumns.find('.fixed-table-header') + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedHeader = initFixedHeader(this.$fixedColumns) + this.$fixedHeader.css('margin-right', '') + } else if (this.$fixedColumns) { + this.$fixedColumns.html('').css('width', '') + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedHeaderRight = initFixedHeader(this.$fixedColumnsRight, true) + this.$fixedHeaderRight.scrollLeft(this.$fixedHeaderRight.find('table').width()) + } else if (this.$fixedColumnsRight) { + this.$fixedColumnsRight.html('').css('width', '') + } + + this.initFixedColumnsBody() + this.initFixedColumnsEvents() + } + + initFixedColumnsBody () { + const initFixedBody = ($fixedColumns, $fixedHeader) => { + $fixedColumns.find('.fixed-table-body').remove() + $fixedColumns.append(this.$tableBody.clone(true)) + + const $fixedBody = $fixedColumns.find('.fixed-table-body') + + const tableBody = this.$tableBody.get(0) + const scrollHeight = tableBody.scrollWidth > tableBody.clientWidth ? + Utils.getScrollBarWidth() : 0 + const height = this.$tableContainer.outerHeight(true) - scrollHeight - 1 + + $fixedColumns.css({ + height + }) + + $fixedBody.css({ + height: height - $fixedHeader.height() + }) + + return $fixedBody + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody = initFixedBody(this.$fixedColumns, this.$fixedHeader) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight = initFixedBody(this.$fixedColumnsRight, this.$fixedHeaderRight) + this.$fixedBodyRight.scrollLeft(this.$fixedBodyRight.find('table').width()) + this.$fixedBodyRight.css('overflow-y', this.options.height ? 'auto' : 'hidden') + } + } + + getFixedColumnsWidth (isRight) { + let visibleFields = this.getVisibleFields() + let width = 0 + let fixedNumber = this.options.fixedNumber + let marginRight = 0 + + if (isRight) { + visibleFields = visibleFields.reverse() + fixedNumber = this.options.fixedRightNumber + marginRight = parseInt(this.$tableHeader.css('margin-right'), 10) + } + + for (let i = 0; i < fixedNumber; i++) { + width += this.$header.find(`th[data-field="${visibleFields[i]}"]`).outerWidth(true) + } + + return width + marginRight + 1 + } + + initFixedColumnsEvents () { + const toggleHover = (e, toggle) => { + const tr = `tr[data-index="${$(e.currentTarget).data('index')}"]` + let $trs = this.$tableBody.find(tr) + + if (this.$fixedBody) { + $trs = $trs.add(this.$fixedBody.find(tr)) + } + if (this.$fixedBodyRight) { + $trs = $trs.add(this.$fixedBodyRight.find(tr)) + } + + $trs.css('background-color', toggle ? $(e.currentTarget).css('background-color') : '') + } + + this.$tableBody.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + const isFirefox = typeof navigator !== 'undefined' && + navigator.userAgent.toLowerCase().indexOf('firefox') > -1 + const mousewheel = isFirefox ? 'DOMMouseScroll' : 'mousewheel' + const updateScroll = (e, fixedBody) => { + const normalized = normalizeWheel(e) + const deltaY = Math.ceil(normalized.pixelY) + const top = this.$tableBody.scrollTop() + deltaY + + if ( + deltaY < 0 && top > 0 || + deltaY > 0 && top < fixedBody.scrollHeight - fixedBody.clientHeight + ) { + e.preventDefault() + } + + this.$tableBody.scrollTop(top) + if (this.$fixedBody) { + this.$fixedBody.scrollTop(top) + } + if (this.$fixedBodyRight) { + this.$fixedBodyRight.scrollTop(top) + } + } + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedBody.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + this.$fixedBody[0].addEventListener(mousewheel, e => { + updateScroll(e, this.$fixedBody[0]) + }) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + this.$fixedBodyRight.find('tr').hover(e => { + toggleHover(e, true) + }, e => { + toggleHover(e, false) + }) + + this.$fixedBodyRight.off('scroll').on('scroll', () => { + const top = this.$fixedBodyRight.scrollTop() + + this.$tableBody.scrollTop(top) + if (this.$fixedBody) { + this.$fixedBody.scrollTop(top) + } + }) + } + + if (this.options.filterControl) { + $(this.$fixedColumns).off('keyup change').on('keyup change', e => { + const $target = $(e.target) + const value = $target.val() + const field = $target.parents('th').data('field') + const $coreTh = this.$header.find(`th[data-field="${field}"]`) + + if ($target.is('input')) { + $coreTh.find('input').val(value) + } else if ($target.is('select')) { + const $select = $coreTh.find('select') + + $select.find('option[selected]').removeAttr('selected') + $select.find(`option[value="${value}"]`).attr('selected', true) + } + + this.triggerSearch() + }) + } + } + + renderStickyHeader () { + if (!this.options.stickyHeader) { + return + } + + this.$stickyContainer = this.$container.find('.sticky-header-container') + super.renderStickyHeader() + + if (this.needFixedColumns && this.options.fixedNumber) { + this.$fixedColumns.css('z-index', 101) + .find('.sticky-header-container') + .css('right', '') + .width(this.$fixedColumns.outerWidth()) + } + + if (this.needFixedColumns && this.options.fixedRightNumber) { + const $stickyHeaderContainerRight = this.$fixedColumnsRight.find('.sticky-header-container') + + this.$fixedColumnsRight.css('z-index', 101) + $stickyHeaderContainerRight.css('left', '') + .scrollLeft($stickyHeaderContainerRight.find('.table').outerWidth()) + .width(this.$fixedColumnsRight.outerWidth()) + } + } + + matchPositionX () { + if (!this.options.stickyHeader) { + return + } + + this.$stickyContainer.eq(0).scrollLeft(this.$tableBody.scrollLeft()) + } +} diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js new file mode 100644 index 00000000..83e4648c --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/custom-view/bootstrap-table-custom-view.js @@ -0,0 +1,108 @@ +/** + * @author zhixin wen + */ + +var Utils = $.fn.bootstrapTable.utils + +$.extend($.fn.bootstrapTable.defaults, { + customView: false, + showCustomView: false, + showCustomViewButton: false +}) + +$.extend($.fn.bootstrapTable.defaults.icons, { + customView: { + bootstrap3: 'glyphicon glyphicon-eye-open', + bootstrap5: 'bi-eye', + bootstrap4: 'fa fa-eye', + semantic: 'fa fa-eye', + foundation: 'fa fa-eye', + bulma: 'fa fa-eye', + materialize: 'remove_red_eye' + }[$.fn.bootstrapTable.theme] || 'fa-eye' +}) + +$.extend($.fn.bootstrapTable.defaults, { + onCustomViewPostBody () { + return false + }, + onCustomViewPreBody () { + return false + } +}) + +$.extend($.fn.bootstrapTable.locales, { + formatToggleCustomView () { + return 'Toggle custom view' + } +}) +$.extend($.fn.bootstrapTable.defaults, $.fn.bootstrapTable.locales) + +$.fn.bootstrapTable.methods.push('toggleCustomView') + +$.extend($.fn.bootstrapTable.Constructor.EVENTS, { + 'custom-view-post-body.bs.table': 'onCustomViewPostBody', + 'custom-view-pre-body.bs.table': 'onCustomViewPreBody' +}) + +$.BootstrapTable = class extends $.BootstrapTable { + + init () { + this.showCustomView = this.options.showCustomView + + super.init() + } + + initToolbar (...args) { + if (this.options.customView && this.options.showCustomViewButton) { + this.buttons = Object.assign(this.buttons, { + customView: { + text: this.options.formatToggleCustomView(), + icon: this.options.icons.customView, + event: this.toggleCustomView, + attributes: { + 'aria-label': this.options.formatToggleCustomView(), + title: this.options.formatToggleCustomView() + } + } + }) + } + + super.initToolbar(...args) + } + + initBody () { + super.initBody() + + if (!this.options.customView) { + return + } + + const $table = this.$el + const $customViewContainer = this.$container.find('.fixed-table-custom-view') + + $table.hide() + $customViewContainer.hide() + if (!this.options.customView || !this.showCustomView) { + $table.show() + return + } + + const data = this.getData().slice(this.pageFrom - 1, this.pageTo) + const value = Utils.calculateObjectValue(this, this.options.customView, [data], '') + + this.trigger('custom-view-pre-body', data, value) + if ($customViewContainer.length === 1) { + $customViewContainer.show().html(value) + } else { + this.$tableBody.after(`
    ${value}
    `) + } + + this.trigger('custom-view-post-body', data, value) + } + + toggleCustomView () { + this.showCustomView = !this.showCustomView + this.initBody() + } +} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css new file mode 100644 index 00000000..7cd44972 --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.css @@ -0,0 +1,663 @@ +/*! X-editable - v1.5.1 +* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery +* http://github.com/vitalets/x-editable +* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ +.editableform { + margin-bottom: 0; /* overwrites bootstrap margin */ +} + +.editableform .control-group { + margin-bottom: 0; /* overwrites bootstrap margin */ + white-space: nowrap; /* prevent wrapping buttons on new line */ + line-height: 20px; /* overwriting bootstrap line-height. See #133 */ +} + +/* + BS3 width:1005 for inputs breaks editable form in popup + See: https://github.com/vitalets/x-editable/issues/393 +*/ +.editableform .form-control { + width: auto; +} + +.editable-buttons { + display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ + vertical-align: top; + margin-left: 7px; + /* inline-block emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-buttons.editable-buttons-bottom { + display: block; + margin-top: 7px; + margin-left: 0; +} + +.editable-input { + vertical-align: top; + display: inline-block; /* should be inline to take effect of parent's white-space: nowrap */ + width: auto; /* bootstrap-responsive has width: 100% that breakes layout */ + white-space: normal; /* reset white-space decalred in parent*/ + /* display-inline emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-buttons .editable-cancel { + margin-left: 7px; +} + +/*for jquery-ui buttons need set height to look more pretty*/ +.editable-buttons button.ui-button-icon-only { + height: 24px; + width: 30px; +} + +.editableform-loading { + background: url('loading.gif') center center no-repeat; + height: 25px; + width: auto; + min-width: 25px; +} + +.editable-inline .editableform-loading { + background-position: left 5px; +} + + .editable-error-block { + max-width: 300px; + margin: 5px 0 0 0; + width: auto; + white-space: normal; +} + +/*add padding for jquery ui*/ +.editable-error-block.ui-state-error { + padding: 3px; +} + +.editable-error { + color: red; +} + +/* ---- For specific types ---- */ + +.editableform .editable-date { + padding: 0; + margin: 0; + float: left; +} + +/* move datepicker icon to center of add-on button. See https://github.com/vitalets/x-editable/issues/183 */ +.editable-inline .add-on .icon-th { + margin-top: 3px; + margin-left: 1px; +} + + +/* checklist vertical alignment */ +.editable-checklist label input[type="checkbox"], +.editable-checklist label span { + vertical-align: middle; + margin: 0; +} + +.editable-checklist label { + white-space: nowrap; +} + +/* set exact width of textarea to fit buttons toolbar */ +.editable-wysihtml5 { + width: 566px; + height: 250px; +} + +/* clear button shown as link in date inputs */ +.editable-clear { + clear: both; + font-size: 0.9em; + text-decoration: none; + text-align: right; +} + +/* IOS-style clear button for text inputs */ +.editable-clear-x { + background: url('clear.png') center center no-repeat; + display: block; + width: 13px; + height: 13px; + position: absolute; + opacity: 0.6; + z-index: 100; + + top: 50%; + right: 6px; + margin-top: -6px; + +} + +.editable-clear-x:hover { + opacity: 1; +} + +.editable-pre-wrapped { + white-space: pre-wrap; +} +.editable-container.editable-popup { + max-width: none !important; /* without this rule poshytip/tooltip does not stretch */ +} + +.editable-container.popover { + width: auto; /* without this rule popover does not stretch */ +} + +.editable-container.editable-inline { + display: inline-block; + vertical-align: middle; + width: auto; + /* inline-block emulation for IE7*/ + zoom: 1; + *display: inline; +} + +.editable-container.ui-widget { + font-size: inherit; /* jqueryui widget font 1.1em too big, overwrite it */ + z-index: 9990; /* should be less than select2 dropdown z-index to close dropdown first when click */ +} +.editable-click, +a.editable-click, +a.editable-click:hover { + text-decoration: none; + border-bottom: dashed 1px #0088cc; +} + +.editable-click.editable-disabled, +a.editable-click.editable-disabled, +a.editable-click.editable-disabled:hover { + color: #585858; + cursor: default; + border-bottom: none; +} + +.editable-empty, .editable-empty:hover, .editable-empty:focus{ + font-style: italic; + color: #DD1144; + /* border-bottom: none; */ + text-decoration: none; +} + +.editable-unsaved { + font-weight: bold; +} + +.editable-unsaved:after { +/* content: '*'*/ +} + +.editable-bg-transition { + -webkit-transition: background-color 1400ms ease-out; + -moz-transition: background-color 1400ms ease-out; + -o-transition: background-color 1400ms ease-out; + -ms-transition: background-color 1400ms ease-out; + transition: background-color 1400ms ease-out; +} + +/*see https://github.com/vitalets/x-editable/issues/139 */ +.form-horizontal .editable +{ + padding-top: 5px; + display:inline-block; +} + + +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.datepicker { + padding: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + direction: ltr; + /*.dow { + border-top: 1px solid #ddd !important; + }*/ + +} +.datepicker-inline { + width: 220px; +} +.datepicker.datepicker-rtl { + direction: rtl; +} +.datepicker.datepicker-rtl table tr td span { + float: right; +} +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown:before { + content: ''; + display: inline-block; + border-left: 7px solid transparent; + border-right: 7px solid transparent; + border-bottom: 7px solid #ccc; + border-bottom-color: rgba(0, 0, 0, 0.2); + position: absolute; + top: -7px; + left: 6px; +} +.datepicker-dropdown:after { + content: ''; + display: inline-block; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + border-bottom: 6px solid #ffffff; + position: absolute; + top: -6px; + left: 7px; +} +.datepicker > div { + display: none; +} +.datepicker.days div.datepicker-days { + display: block; +} +.datepicker.months div.datepicker-months { + display: block; +} +.datepicker.years div.datepicker-years { + display: block; +} +.datepicker table { + margin: 0; +} +.datepicker td, +.datepicker th { + text-align: center; + width: 20px; + height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + background-color: #fde19a; + background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a)); + background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -o-linear-gradient(top, #fdd49a, #fdf59a); + background-image: linear-gradient(top, #fdd49a, #fdf59a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0); + border-color: #fdf59a #fdf59a #fbed50; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #000; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled] { + background-color: #fdf59a; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active { + background-color: #fbf069 \9; +} +.datepicker table tr td.today:hover:hover { + color: #000; +} +.datepicker table tr td.today.active:hover { + color: #fff; +} +.datepicker table tr td.range, +.datepicker table tr td.range:hover, +.datepicker table tr td.range.disabled, +.datepicker table tr td.range.disabled:hover { + background: #eeeeee; + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today, +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today.disabled:hover { + background-color: #f3d17a; + background-image: -moz-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -ms-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f3c17a), to(#f3e97a)); + background-image: -webkit-linear-gradient(top, #f3c17a, #f3e97a); + background-image: -o-linear-gradient(top, #f3c17a, #f3e97a); + background-image: linear-gradient(top, #f3c17a, #f3e97a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f3c17a', endColorstr='#f3e97a', GradientType=0); + border-color: #f3e97a #f3e97a #edde34; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + -webkit-border-radius: 0; + -moz-border-radius: 0; + border-radius: 0; +} +.datepicker table tr td.range.today:hover, +.datepicker table tr td.range.today:hover:hover, +.datepicker table tr td.range.today.disabled:hover, +.datepicker table tr td.range.today.disabled:hover:hover, +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active, +.datepicker table tr td.range.today.disabled, +.datepicker table tr td.range.today:hover.disabled, +.datepicker table tr td.range.today.disabled.disabled, +.datepicker table tr td.range.today.disabled:hover.disabled, +.datepicker table tr td.range.today[disabled], +.datepicker table tr td.range.today:hover[disabled], +.datepicker table tr td.range.today.disabled[disabled], +.datepicker table tr td.range.today.disabled:hover[disabled] { + background-color: #f3e97a; +} +.datepicker table tr td.range.today:active, +.datepicker table tr td.range.today:hover:active, +.datepicker table tr td.range.today.disabled:active, +.datepicker table tr td.range.today.disabled:hover:active, +.datepicker table tr td.range.today.active, +.datepicker table tr td.range.today:hover.active, +.datepicker table tr td.range.today.disabled.active, +.datepicker table tr td.range.today.disabled:hover.active { + background-color: #efe24b \9; +} +.datepicker table tr td.selected, +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected.disabled:hover { + background-color: #9e9e9e; + background-image: -moz-linear-gradient(top, #b3b3b3, #808080); + background-image: -ms-linear-gradient(top, #b3b3b3, #808080); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#b3b3b3), to(#808080)); + background-image: -webkit-linear-gradient(top, #b3b3b3, #808080); + background-image: -o-linear-gradient(top, #b3b3b3, #808080); + background-image: linear-gradient(top, #b3b3b3, #808080); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3b3b3', endColorstr='#808080', GradientType=0); + border-color: #808080 #808080 #595959; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.selected:hover, +.datepicker table tr td.selected:hover:hover, +.datepicker table tr td.selected.disabled:hover, +.datepicker table tr td.selected.disabled:hover:hover, +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active, +.datepicker table tr td.selected.disabled, +.datepicker table tr td.selected:hover.disabled, +.datepicker table tr td.selected.disabled.disabled, +.datepicker table tr td.selected.disabled:hover.disabled, +.datepicker table tr td.selected[disabled], +.datepicker table tr td.selected:hover[disabled], +.datepicker table tr td.selected.disabled[disabled], +.datepicker table tr td.selected.disabled:hover[disabled] { + background-color: #808080; +} +.datepicker table tr td.selected:active, +.datepicker table tr td.selected:hover:active, +.datepicker table tr td.selected.disabled:active, +.datepicker table tr td.selected.disabled:hover:active, +.datepicker table tr td.selected.active, +.datepicker table tr td.selected:hover.active, +.datepicker table tr td.selected.disabled.active, +.datepicker table tr td.selected.disabled:hover.active { + background-color: #666666 \9; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled:hover { + background-color: #006dcc; + background-image: -moz-linear-gradient(top, #0088cc, #0044cc); + background-image: -ms-linear-gradient(top, #0088cc, #0044cc); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); + background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); + background-image: -o-linear-gradient(top, #0088cc, #0044cc); + background-image: linear-gradient(top, #0088cc, #0044cc); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); + border-color: #0044cc #0044cc #002a80; + border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); + filter: progid:DXImageTransform.Microsoft.gradient(enabled=false); + color: #fff; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); +} +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span.old, +.datepicker table tr td span.new { + color: #999999; +} +.datepicker th.datepicker-switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child th.cw { + cursor: default; + background-color: transparent; +} +.input-append.date .add-on i, +.input-prepend.date .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} +.input-daterange input { + text-align: center; +} +.input-daterange input:first-child { + -webkit-border-radius: 3px 0 0 3px; + -moz-border-radius: 3px 0 0 3px; + border-radius: 3px 0 0 3px; +} +.input-daterange input:last-child { + -webkit-border-radius: 0 3px 3px 0; + -moz-border-radius: 0 3px 3px 0; + border-radius: 0 3px 3px 0; +} +.input-daterange .add-on { + display: inline-block; + width: auto; + min-width: 16px; + height: 18px; + padding: 4px 5px; + font-weight: normal; + line-height: 18px; + text-align: center; + text-shadow: 0 1px 0 #ffffff; + vertical-align: middle; + background-color: #eeeeee; + border: 1px solid #ccc; + margin-left: -5px; + margin-right: -5px; +} \ No newline at end of file diff --git a/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js new file mode 100644 index 00000000..e2703aee --- /dev/null +++ b/ghy-admin/src/main/resources/static/ajax/libs/bootstrap-table/extensions/editable/bootstrap-editable.min.js @@ -0,0 +1,7 @@ +/*! X-editable - v1.5.1 +* In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery +* http://github.com/vitalets/x-editable +* Copyright (c) 2013 Vitaliy Potapov; Licensed MIT */ +!function(a){"use strict";var b=function(b,c){this.options=a.extend({},a.fn.editableform.defaults,c),this.$div=a(b),this.options.scope||(this.options.scope=this)};b.prototype={constructor:b,initInput:function(){this.input=this.options.input,this.value=this.input.str2value(this.options.value),this.input.prerender()},initTemplate:function(){this.$form=a(a.fn.editableform.template)},initButtons:function(){var b=this.$form.find(".editable-buttons");b.append(a.fn.editableform.buttons),"bottom"===this.options.showbuttons&&b.addClass("editable-buttons-bottom")},render:function(){this.$loading=a(a.fn.editableform.loading),this.$div.empty().append(this.$loading),this.initTemplate(),this.options.showbuttons?this.initButtons():this.$form.find(".editable-buttons").remove(),this.showLoading(),this.isSaving=!1,this.$div.triggerHandler("rendering"),this.initInput(),this.$form.find("div.editable-input").append(this.input.$tpl),this.$div.append(this.$form),a.when(this.input.render()).then(a.proxy(function(){if(this.options.showbuttons||this.input.autosubmit(),this.$form.find(".editable-cancel").click(a.proxy(this.cancel,this)),this.input.error)this.error(this.input.error),this.$form.find(".editable-submit").attr("disabled",!0),this.input.$input.attr("disabled",!0),this.$form.submit(function(a){a.preventDefault()});else{this.error(!1),this.input.$input.removeAttr("disabled"),this.$form.find(".editable-submit").removeAttr("disabled");var b=null===this.value||void 0===this.value||""===this.value?this.options.defaultValue:this.value;this.input.value2input(b),this.$form.submit(a.proxy(this.submit,this))}this.$div.triggerHandler("rendered"),this.showForm(),this.input.postrender&&this.input.postrender()},this))},cancel:function(){this.$div.triggerHandler("cancel")},showLoading:function(){var a,b;this.$form?(a=this.$form.outerWidth(),b=this.$form.outerHeight(),a&&this.$loading.width(a),b&&this.$loading.height(b),this.$form.hide()):(a=this.$loading.parent().width(),a&&this.$loading.width(a)),this.$loading.show()},showForm:function(a){this.$loading.hide(),this.$form.show(),a!==!1&&this.input.activate(),this.$div.triggerHandler("show")},error:function(b){var c,d=this.$form.find(".control-group"),e=this.$form.find(".editable-error-block");if(b===!1)d.removeClass(a.fn.editableform.errorGroupClass),e.removeClass(a.fn.editableform.errorBlockClass).empty().hide();else{if(b){c=(""+b).split("\n");for(var f=0;f").text(c[f]).html();b=c.join("
    ")}d.addClass(a.fn.editableform.errorGroupClass),e.addClass(a.fn.editableform.errorBlockClass).html(b).show()}},submit:function(b){b.stopPropagation(),b.preventDefault();var c=this.input.input2value(),d=this.validate(c);if("object"===a.type(d)&&void 0!==d.newValue){if(c=d.newValue,this.input.value2input(c),"string"==typeof d.msg)return this.error(d.msg),this.showForm(),void 0}else if(d)return this.error(d),this.showForm(),void 0;if(!this.options.savenochange&&this.input.value2str(c)==this.input.value2str(this.value))return this.$div.triggerHandler("nochange"),void 0;var e=this.input.value2submit(c);this.isSaving=!0,a.when(this.save(e)).done(a.proxy(function(a){this.isSaving=!1;var b="function"==typeof this.options.success?this.options.success.call(this.options.scope,a,c):null;return b===!1?(this.error(!1),this.showForm(!1),void 0):"string"==typeof b?(this.error(b),this.showForm(),void 0):(b&&"object"==typeof b&&b.hasOwnProperty("newValue")&&(c=b.newValue),this.error(!1),this.value=c,this.$div.triggerHandler("save",{newValue:c,submitValue:e,response:a}),void 0)},this)).fail(a.proxy(function(a){this.isSaving=!1;var b;b="function"==typeof this.options.error?this.options.error.call(this.options.scope,a,c):"string"==typeof a?a:a.responseText||a.statusText||"Unknown error!",this.error(b),this.showForm()},this))},save:function(b){this.options.pk=a.fn.editableutils.tryParseJson(this.options.pk,!0);var c,d="function"==typeof this.options.pk?this.options.pk.call(this.options.scope):this.options.pk,e=!!("function"==typeof this.options.url||this.options.url&&("always"===this.options.send||"auto"===this.options.send&&null!==d&&void 0!==d));return e?(this.showLoading(),c={name:this.options.name||"",value:b,pk:d},"function"==typeof this.options.params?c=this.options.params.call(this.options.scope,c):(this.options.params=a.fn.editableutils.tryParseJson(this.options.params,!0),a.extend(c,this.options.params)),"function"==typeof this.options.url?this.options.url.call(this.options.scope,c):a.ajax(a.extend({url:this.options.url,data:c,type:"POST"},this.options.ajaxOptions))):void 0},validate:function(a){return void 0===a&&(a=this.value),"function"==typeof this.options.validate?this.options.validate.call(this.options.scope,a):void 0},option:function(a,b){a in this.options&&(this.options[a]=b),"value"===a&&this.setValue(b)},setValue:function(a,b){this.value=b?this.input.str2value(a):a,this.$form&&this.$form.is(":visible")&&this.input.value2input(this.value)}},a.fn.editableform=function(c){var d=arguments;return this.each(function(){var e=a(this),f=e.data("editableform"),g="object"==typeof c&&c;f||e.data("editableform",f=new b(this,g)),"string"==typeof c&&f[c].apply(f,Array.prototype.slice.call(d,1))})},a.fn.editableform.Constructor=b,a.fn.editableform.defaults={type:"text",url:null,params:null,name:null,pk:null,value:null,defaultValue:null,send:"auto",validate:null,success:null,error:null,ajaxOptions:null,showbuttons:!0,scope:null,savenochange:!1},a.fn.editableform.template='
    ',a.fn.editableform.loading='
    ',a.fn.editableform.buttons='',a.fn.editableform.errorGroupClass=null,a.fn.editableform.errorBlockClass="editable-error",a.fn.editableform.engine="jquery"}(window.jQuery),function(a){"use strict";a.fn.editableutils={inherit:function(a,b){var c=function(){};c.prototype=b.prototype,a.prototype=new c,a.prototype.constructor=a,a.superclass=b.prototype},setCursorPosition:function(a,b){if(a.setSelectionRange)a.setSelectionRange(b,b);else if(a.createTextRange){var c=a.createTextRange();c.collapse(!0),c.moveEnd("character",b),c.moveStart("character",b),c.select()}},tryParseJson:function(a,b){if("string"==typeof a&&a.length&&a.match(/^[\{\[].*[\}\]]$/))if(b)try{a=new Function("return "+a)()}catch(c){}finally{return a}else a=new Function("return "+a)();return a},sliceObj:function(b,c,d){var e,f,g={};if(!a.isArray(c)||!c.length)return g;for(var h=0;h").text(b).html()},itemsByValue:function(b,c,d){if(!c||null===b)return[];if("function"!=typeof d){var e=d||"value";d=function(a){return a[e]}}var f=a.isArray(b),g=[],h=this;return a.each(c,function(c,e){if(e.children)g=g.concat(h.itemsByValue(b,e.children,d));else if(f)a.grep(b,function(a){return a==(e&&"object"==typeof e?d(e):e)}).length&&g.push(e);else{var i=e&&"object"==typeof e?d(e):e;b==i&&g.push(e)}}),g},createInput:function(b){var c,d,e,f=b.type;return"date"===f&&("inline"===b.mode?a.fn.editabletypes.datefield?f="datefield":a.fn.editabletypes.dateuifield&&(f="dateuifield"):a.fn.editabletypes.date?f="date":a.fn.editabletypes.dateui&&(f="dateui"),"date"!==f||a.fn.editabletypes.date||(f="combodate")),"datetime"===f&&"inline"===b.mode&&(f="datetimefield"),"wysihtml5"!==f||a.fn.editabletypes[f]||(f="textarea"),"function"==typeof a.fn.editabletypes[f]?(c=a.fn.editabletypes[f],d=this.sliceObj(b,this.objectKeys(c.defaults)),e=new c(d)):(a.error("Unknown type: "+f),!1)},supportsTransitions:function(){var a=document.body||document.documentElement,b=a.style,c="transition",d=["Moz","Webkit","Khtml","O","ms"];if("string"==typeof b[c])return!0;c=c.charAt(0).toUpperCase()+c.substr(1);for(var e=0;e"),this.tip().is(this.innerCss)?this.tip().append(this.$form):this.tip().find(this.innerCss).append(this.$form),this.renderForm()},hide:function(a){if(this.tip()&&this.tip().is(":visible")&&this.$element.hasClass("editable-open")){if(this.$form.data("editableform").isSaving)return this.delayedHide={reason:a},void 0;this.delayedHide=!1,this.$element.removeClass("editable-open"),this.innerHide(),this.$element.triggerHandler("hidden",a||"manual")}},innerShow:function(){},innerHide:function(){},toggle:function(a){this.container()&&this.tip()&&this.tip().is(":visible")?this.hide():this.show(a)},setPosition:function(){},save:function(a,b){this.$element.triggerHandler("save",b),this.hide("save")},option:function(a,b){this.options[a]=b,a in this.containerOptions?(this.containerOptions[a]=b,this.setContainerOption(a,b)):(this.formOptions[a]=b,this.$form&&this.$form.editableform("option",a,b))},setContainerOption:function(a,b){this.call("option",a,b)},destroy:function(){this.hide(),this.innerDestroy(),this.$element.off("destroyed"),this.$element.removeData("editableContainer")},innerDestroy:function(){},closeOthers:function(b){a(".editable-open").each(function(c,d){if(d!==b&&!a(d).find(b).length){var e=a(d),f=e.data("editableContainer");f&&("cancel"===f.options.onblur?e.data("editableContainer").hide("onblur"):"submit"===f.options.onblur&&e.data("editableContainer").tip().find("form").submit())}})},activate:function(){this.tip&&this.tip().is(":visible")&&this.$form&&this.$form.data("editableform").input.activate()}},a.fn.editableContainer=function(d){var e=arguments;return this.each(function(){var f=a(this),g="editableContainer",h=f.data(g),i="object"==typeof d&&d,j="inline"===i.mode?c:b;h||f.data(g,h=new j(this,i)),"string"==typeof d&&h[d].apply(h,Array.prototype.slice.call(e,1))})},a.fn.editableContainer.Popup=b,a.fn.editableContainer.Inline=c,a.fn.editableContainer.defaults={value:null,placement:"top",autohide:!0,onblur:"cancel",anim:!1,mode:"popup"},jQuery.event.special.destroyed={remove:function(a){a.handler&&a.handler()}}}(window.jQuery),function(a){"use strict";a.extend(a.fn.editableContainer.Inline.prototype,a.fn.editableContainer.Popup.prototype,{containerName:"editableform",innerCss:".editable-inline",containerClass:"editable-container editable-inline",initContainer:function(){this.$tip=a(""),this.options.anim||(this.options.anim=0)},splitOptions:function(){this.containerOptions={},this.formOptions=this.options},tip:function(){return this.$tip},innerShow:function(){this.$element.hide(),this.tip().insertAfter(this.$element).show()},innerHide:function(){this.$tip.hide(this.options.anim,a.proxy(function(){this.$element.show(),this.innerDestroy()},this))},innerDestroy:function(){this.tip()&&this.tip().empty().remove()}})}(window.jQuery),function(a){"use strict";var b=function(b,c){this.$element=a(b),this.options=a.extend({},a.fn.editable.defaults,c,a.fn.editableutils.getConfigData(this.$element)),this.options.selector?this.initLive():this.init(),this.options.highlight&&!a.fn.editableutils.supportsTransitions()&&(this.options.highlight=!1)};b.prototype={constructor:b,init:function(){var b,c=!1;if(this.options.name=this.options.name||this.$element.attr("id"),this.options.scope=this.$element[0],this.input=a.fn.editableutils.createInput(this.options),this.input){switch(void 0===this.options.value||null===this.options.value?(this.value=this.input.html2value(a.trim(this.$element.html())),c=!0):(this.options.value=a.fn.editableutils.tryParseJson(this.options.value,!0),this.value="string"==typeof this.options.value?this.input.str2value(this.options.value):this.options.value),this.$element.addClass("editable"),"textarea"===this.input.type&&this.$element.addClass("editable-pre-wrapped"),"manual"!==this.options.toggle?(this.$element.addClass("editable-click"),this.$element.on(this.options.toggle+".editable",a.proxy(function(a){if(this.options.disabled||a.preventDefault(),"mouseenter"===this.options.toggle)this.show();else{var b="click"!==this.options.toggle;this.toggle(b)}},this))):this.$element.attr("tabindex",-1),"function"==typeof this.options.display&&(this.options.autotext="always"),this.options.autotext){case"always":b=!0;break;case"auto":b=!a.trim(this.$element.text()).length&&null!==this.value&&void 0!==this.value&&!c;break;default:b=!1}a.when(b?this.render():!0).then(a.proxy(function(){this.options.disabled?this.disable():this.enable(),this.$element.triggerHandler("init",this)},this))}},initLive:function(){var b=this.options.selector;this.options.selector=!1,this.options.autotext="never",this.$element.on(this.options.toggle+".editable",b,a.proxy(function(b){var c=a(b.target);c.data("editable")||(c.hasClass(this.options.emptyclass)&&c.empty(),c.editable(this.options).trigger(b))},this))},render:function(a){return this.options.display!==!1?this.input.value2htmlFinal?this.input.value2html(this.value,this.$element[0],this.options.display,a):"function"==typeof this.options.display?this.options.display.call(this.$element[0],this.value,a):this.input.value2html(this.value,this.$element[0]):void 0},enable:function(){this.options.disabled=!1,this.$element.removeClass("editable-disabled"),this.handleEmpty(this.isEmpty),"manual"!==this.options.toggle&&"-1"===this.$element.attr("tabindex")&&this.$element.removeAttr("tabindex")},disable:function(){this.options.disabled=!0,this.hide(),this.$element.addClass("editable-disabled"),this.handleEmpty(this.isEmpty),this.$element.attr("tabindex",-1)},toggleDisabled:function(){this.options.disabled?this.enable():this.disable()},option:function(b,c){return b&&"object"==typeof b?(a.each(b,a.proxy(function(b,c){this.option(a.trim(b),c)},this)),void 0):(this.options[b]=c,"disabled"===b?c?this.disable():this.enable():("value"===b&&this.setValue(c),this.container&&this.container.option(b,c),this.input.option&&this.input.option(b,c),void 0))},handleEmpty:function(b){this.options.display!==!1&&(this.isEmpty=void 0!==b?b:"function"==typeof this.input.isEmpty?this.input.isEmpty(this.$element):""===a.trim(this.$element.html()),this.options.disabled?this.isEmpty&&(this.$element.empty(),this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass)):this.isEmpty?(this.$element.html(this.options.emptytext),this.options.emptyclass&&this.$element.addClass(this.options.emptyclass)):this.options.emptyclass&&this.$element.removeClass(this.options.emptyclass))},show:function(b){if(!this.options.disabled){if(this.container){if(this.container.tip().is(":visible"))return}else{var c=a.extend({},this.options,{value:this.value,input:this.input});this.$element.editableContainer(c),this.$element.on("save.internal",a.proxy(this.save,this)),this.container=this.$element.data("editableContainer")}this.container.show(b)}},hide:function(){this.container&&this.container.hide()},toggle:function(a){this.container&&this.container.tip().is(":visible")?this.hide():this.show(a)},save:function(a,b){if(this.options.unsavedclass){var c=!1;c=c||"function"==typeof this.options.url,c=c||this.options.display===!1,c=c||void 0!==b.response,c=c||this.options.savenochange&&this.input.value2str(this.value)!==this.input.value2str(b.newValue),c?this.$element.removeClass(this.options.unsavedclass):this.$element.addClass(this.options.unsavedclass)}if(this.options.highlight){var d=this.$element,e=d.css("background-color");d.css("background-color",this.options.highlight),setTimeout(function(){"transparent"===e&&(e=""),d.css("background-color",e),d.addClass("editable-bg-transition"),setTimeout(function(){d.removeClass("editable-bg-transition")},1700)},10)}this.setValue(b.newValue,!1,b.response)},validate:function(){return"function"==typeof this.options.validate?this.options.validate.call(this,this.value):void 0},setValue:function(b,c,d){this.value=c?this.input.str2value(b):b,this.container&&this.container.option("value",this.value),a.when(this.render(d)).then(a.proxy(function(){this.handleEmpty()},this))},activate:function(){this.container&&this.container.activate()},destroy:function(){this.disable(),this.container&&this.container.destroy(),this.input.destroy(),"manual"!==this.options.toggle&&(this.$element.removeClass("editable-click"),this.$element.off(this.options.toggle+".editable")),this.$element.off("save.internal"),this.$element.removeClass("editable editable-open editable-disabled"),this.$element.removeData("editable")}},a.fn.editable=function(c){var d={},e=arguments,f="editable";switch(c){case"validate":return this.each(function(){var b,c=a(this),e=c.data(f);e&&(b=e.validate())&&(d[e.options.name]=b)}),d;case"getValue":return 2===arguments.length&&arguments[1]===!0?d=this.eq(0).data(f).value:this.each(function(){var b=a(this),c=b.data(f);c&&void 0!==c.value&&null!==c.value&&(d[c.options.name]=c.input.value2submit(c.value))}),d;case"submit":var g=arguments[1]||{},h=this,i=this.editable("validate");if(a.isEmptyObject(i)){var j={};if(1===h.length){var k=h.data("editable"),l={name:k.options.name||"",value:k.input.value2submit(k.value),pk:"function"==typeof k.options.pk?k.options.pk.call(k.options.scope):k.options.pk};"function"==typeof k.options.params?l=k.options.params.call(k.options.scope,l):(k.options.params=a.fn.editableutils.tryParseJson(k.options.params,!0),a.extend(l,k.options.params)),j={url:k.options.url,data:l,type:"POST"},g.success=g.success||k.options.success,g.error=g.error||k.options.error}else{var m=this.editable("getValue");j={url:g.url,data:m,type:"POST"}}j.success="function"==typeof g.success?function(a){g.success.call(h,a,g)}:a.noop,j.error="function"==typeof g.error?function(){g.error.apply(h,arguments)}:a.noop,g.ajaxOptions&&a.extend(j,g.ajaxOptions),g.data&&a.extend(j.data,g.data),a.ajax(j)}else"function"==typeof g.error&&g.error.call(h,i);return this}return this.each(function(){var d=a(this),g=d.data(f),h="object"==typeof c&&c;return h&&h.selector?(g=new b(this,h),void 0):(g||d.data(f,g=new b(this,h)),"string"==typeof c&&g[c].apply(g,Array.prototype.slice.call(e,1)),void 0)})},a.fn.editable.defaults={type:"text",disabled:!1,toggle:"click",emptytext:"Empty",autotext:"auto",value:null,display:null,emptyclass:"editable-empty",unsavedclass:"editable-unsaved",selector:null,highlight:"#FFFF80"}}(window.jQuery),function(a){"use strict";a.fn.editabletypes={};var b=function(){};b.prototype={init:function(b,c,d){this.type=b,this.options=a.extend({},d,c)},prerender:function(){this.$tpl=a(this.options.tpl),this.$input=this.$tpl,this.$clear=null,this.error=null},render:function(){},value2html:function(b,c){a(c)[this.options.escape?"text":"html"](a.trim(b))},html2value:function(b){return a("
    ").html(b).text()},value2str:function(a){return a},str2value:function(a){return a},value2submit:function(a){return a},value2input:function(a){this.$input.val(a)},input2value:function(){return this.$input.val()},activate:function(){this.$input.is(":visible")&&this.$input.focus()},clear:function(){this.$input.val(null)},escape:function(b){return a("
    ").text(b).html()},autosubmit:function(){},destroy:function(){},setClass:function(){this.options.inputclass&&this.$input.addClass(this.options.inputclass)},setAttr:function(a){void 0!==this.options[a]&&null!==this.options[a]&&this.$input.attr(a,this.options[a])},option:function(a,b){this.options[a]=b}},b.defaults={tpl:"",inputclass:null,escape:!0,scope:null,showbuttons:!0},a.extend(a.fn.editabletypes,{abstractinput:b})}(window.jQuery),function(a){"use strict";var b=function(){};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){var b=a.Deferred();return this.error=null,this.onSourceReady(function(){this.renderList(),b.resolve()},function(){this.error=this.options.sourceError,b.resolve()}),b.promise()},html2value:function(){return null},value2html:function(b,c,d,e){var f=a.Deferred(),g=function(){"function"==typeof d?d.call(c,b,this.sourceData,e):this.value2htmlFinal(b,c),f.resolve()};return null===b?g.call(this):this.onSourceReady(g,function(){f.resolve()}),f.promise()},onSourceReady:function(b,c){var d;if(a.isFunction(this.options.source)?(d=this.options.source.call(this.options.scope),this.sourceData=null):d=this.options.source,this.options.sourceCache&&a.isArray(this.sourceData))return b.call(this),void 0;try{d=a.fn.editableutils.tryParseJson(d,!1)}catch(e){return c.call(this),void 0}if("string"==typeof d){if(this.options.sourceCache){var f,g=d;if(a(document).data(g)||a(document).data(g,{}),f=a(document).data(g),f.loading===!1&&f.sourceData)return this.sourceData=f.sourceData,this.doPrepend(),b.call(this),void 0;if(f.loading===!0)return f.callbacks.push(a.proxy(function(){this.sourceData=f.sourceData,this.doPrepend(),b.call(this)},this)),f.err_callbacks.push(a.proxy(c,this)),void 0;f.loading=!0,f.callbacks=[],f.err_callbacks=[]}var h=a.extend({url:d,type:"get",cache:!1,dataType:"json",success:a.proxy(function(d){f&&(f.loading=!1),this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(f&&(f.sourceData=this.sourceData,a.each(f.callbacks,function(){this.call()})),this.doPrepend(),b.call(this)):(c.call(this),f&&a.each(f.err_callbacks,function(){this.call()}))},this),error:a.proxy(function(){c.call(this),f&&(f.loading=!1,a.each(f.err_callbacks,function(){this.call()}))},this)},this.options.sourceOptions);a.ajax(h)}else this.sourceData=this.makeArray(d),a.isArray(this.sourceData)?(this.doPrepend(),b.call(this)):c.call(this)},doPrepend:function(){null!==this.options.prepend&&void 0!==this.options.prepend&&(a.isArray(this.prependData)||(a.isFunction(this.options.prepend)&&(this.options.prepend=this.options.prepend.call(this.options.scope)),this.options.prepend=a.fn.editableutils.tryParseJson(this.options.prepend,!0),"string"==typeof this.options.prepend&&(this.options.prepend={"":this.options.prepend}),this.prependData=this.makeArray(this.options.prepend)),a.isArray(this.prependData)&&a.isArray(this.sourceData)&&(this.sourceData=this.prependData.concat(this.sourceData)))},renderList:function(){},value2htmlFinal:function(){},makeArray:function(b){var c,d,e,f,g=[];if(!b||"string"==typeof b)return null;if(a.isArray(b)){f=function(a,b){return d={value:a,text:b},c++>=2?!1:void 0};for(var h=0;h1&&(e.children&&(e.children=this.makeArray(e.children)),g.push(e))):g.push({value:e,text:e})}else a.each(b,function(a,b){g.push({value:a,text:b})});return g},option:function(a,b){this.options[a]=b,"source"===a&&(this.sourceData=null),"prepend"===a&&(this.prependData=null)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{source:null,prepend:!1,sourceError:"Error when loading list",sourceCache:!0,sourceOptions:null}),a.fn.editabletypes.list=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("text",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.renderClear(),this.setClass(),this.setAttr("placeholder")},activate:function(){this.$input.is(":visible")&&(this.$input.focus(),a.fn.editableutils.setCursorPosition(this.$input.get(0),this.$input.val().length),this.toggleClear&&this.toggleClear())},renderClear:function(){this.options.clear&&(this.$clear=a(''),this.$input.after(this.$clear).css("padding-right",24).keyup(a.proxy(function(b){if(!~a.inArray(b.keyCode,[40,38,9,13,27])){clearTimeout(this.t);var c=this;this.t=setTimeout(function(){c.toggleClear(b)},100)}},this)).parent().css("position","relative"),this.$clear.click(a.proxy(this.clear,this)))},postrender:function(){},toggleClear:function(){if(this.$clear){var a=this.$input.val().length,b=this.$clear.is(":visible");a&&!b&&this.$clear.show(),!a&&b&&this.$clear.hide()}},clear:function(){this.$clear.hide(),this.$input.val("").focus()}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:'',placeholder:null,clear:!0}),a.fn.editabletypes.text=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("textarea",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.abstractinput),a.extend(b.prototype,{render:function(){this.setClass(),this.setAttr("placeholder"),this.setAttr("rows"),this.$input.keydown(function(b){b.ctrlKey&&13===b.which&&a(this).closest("form").submit()})},activate:function(){a.fn.editabletypes.text.prototype.activate.call(this)}}),b.defaults=a.extend({},a.fn.editabletypes.abstractinput.defaults,{tpl:"",inputclass:"input-large",placeholder:null,rows:7}),a.fn.editabletypes.textarea=b}(window.jQuery),function(a){"use strict";var b=function(a){this.init("select",a,b.defaults)};a.fn.editableutils.inherit(b,a.fn.editabletypes.list),a.extend(b.prototype,{renderList:function(){this.$input.empty();var b=function(c,d){var e;if(a.isArray(d))for(var f=0;f",e),d[f].children))):(e.value=d[f].value,d[f].disabled&&(e.disabled=!0),c.append(a("